Further consolidate the libraries

This commit is contained in:
Asim Aslam
2019-06-03 18:44:43 +01:00
parent fe060b2d0b
commit b42b6fa0fc
110 changed files with 11934 additions and 83 deletions

7
service/grpc/.travis.yml Normal file
View File

@@ -0,0 +1,7 @@
language: go
go:
- 1.10.x
- 1.11.x
notifications:
slack:
secure: aEvhLbhujaGaKSrOokiG3//PaVHTIrc3fBpoRbCRqfZpyq6WREoapJJhF+tIpWWOwaC9GmChbD6aHo/jMUgwKXVyPSaNjiEL87YzUUpL8B2zslNp1rgfTg/LrzthOx3Q1TYwpaAl3to0fuHUVFX4yMeC2vuThq7WSXgMMxFCtbc=

36
service/grpc/README.md Normal file
View File

@@ -0,0 +1,36 @@
# Micro gRPC [![License](https://img.shields.io/:license-apache-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![GoDoc](https://godoc.org/github.com/micro/go-micro/service/grpc?status.svg)](https://godoc.org/github.com/micro/go-micro/service/grpc) [![Travis CI](https://api.travis-ci.org/micro/go-micro/service/grpc.svg?branch=master)](https://travis-ci.org/micro/go-micro/service/grpc) [![Go Report Card](https://goreportcard.com/badge/micro/go-micro/service/grpc)](https://goreportcard.com/report/github.com/micro/go-micro/service/grpc)
A micro gRPC framework. A simplified experience for building gRPC services.
## Overview
**Go gRPC** makes use of [go-micro](https://github.com/micro/go-micro) plugins to create a simpler framework for gRPC development.
It interoperates with standard gRPC services seamlessly, including the [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway).
The go-grpc library uses the go-micro broker, client and server plugins which make use of
[github.com/grpc/grpc-go](https://github.com/grpc/grpc-go) internally.
This means we ignore the go-micro codec and transport but provide a native grpc experience.
<img src="https://micro.mu/docs/images/go-grpc.svg" />
## Features
- **Service Discovery** - We make use of go-micro's registry and selector interfaces to provide pluggable discovery
and client side load balancing. There's no need to dial connections, we'll do everything beneath the covers for you.
- **PubSub Messaging** - Where gRPC only provides you synchronous communication, **Go gRPC** uses the go-micro broker
to provide asynchronous messaging while using the gRPC protocol.
- **Micro Ecosystem** - Make use of the existing micro ecosystem of tooling including our api gateway, web dashboard,
command line interface and much more. We're enhancing gRPC with a simplified experience using micro.
## Examples
Find an example greeter service in [examples/greeter](https://github.com/micro/go-micro/service/grpc/tree/master/examples/greeter).
## Getting Started
See the [docs](https://micro.mu/docs/go-grpc.html) to get started.
## I18n
### [中文](README_cn.md)

25
service/grpc/README_cn.md Normal file
View File

@@ -0,0 +1,25 @@
# Micro gRPC [![License](https://img.shields.io/:license-apache-blue.svg)](https://opensource.org/licenses/Apache-2.0) [![GoDoc](https://godoc.org/github.com/micro/go-micro/service/grpc?status.svg)](https://godoc.org/github.com/micro/go-micro/service/grpc) [![Travis CI](https://api.travis-ci.org/micro/go-micro/service/grpc.svg?branch=master)](https://travis-ci.org/micro/go-micro/service/grpc) [![Go Report Card](https://goreportcard.com/badge/micro/go-micro/service/grpc)](https://goreportcard.com/report/github.com/micro/go-micro/service/grpc)
Micro gRPC是micro的gRPC框架插件简化开发基于gRPC的服务。
## 概览
micro提供有基于Go的gRPC插件[go-micro](https://github.com/micro/go-micro)该插件可以在内部集成gPRC并与之无缝交互让开发gRPC更简单并支持[grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway)。
micro有面向gRPC的[客户端](https://github.com/micro/go-plugins/tree/master/client)和[服务端](https://github.com/micro/go-plugins/tree/master/server)插件go-grpc库调用客户端/服务端插件生成micro需要的gRPC代码而客户端/服务端插件都是从[github.com/grpc/grpc-go](https://github.com/grpc/grpc-go)扩展而来也即是说我们不需要去知道go-micro是如何编解码或传输就可以使用原生的gRPC。
## 特性
- **服务发现** - go-micro的服务发现基于其[注册](https://github.com/micro/go-plugins/tree/master/registry)与[选择器](https://github.com/micro/go-micro/tree/master/selector)接口实现了可插拔的服务发现与客户端侧的负载均衡不需要拨号连接micro已经把所有都封装好大家只管用。
- **消息发布订阅** - 因为gRPC只提供同步通信机制而**Go gRPC**使用go-micro的[broker代理](https://github.com/micro/go-micro/tree/master/broker)提供异步消息broker也是基于gRPC协议。
- **Micro生态系统** - Micro生态系统包含工具链中比如api网关、web管理控制台、CLI命令行接口等等。我们通过使用micro来增强gRPC框架的易用性。
## 示例
示例请查看[examples/greeter](https://github.com/micro/go-micro/service/grpc/tree/master/examples/greeter)。
## 开始使用
我们提供相关文档[docs](https://micro.mu/docs/go-grpc_cn.html),以便上手。

View File

@@ -0,0 +1,64 @@
# Greeter Service
An example Go-Micro based gRPC service
## What's here?
- **server** - a gRPC greeter service
- **client** - a gRPC client that calls the service once
- **function** - a gRPC greeter functionmore about [Function](https://micro.mu/docs/writing-a-go-function.html)
- **gateway** - a grpc-gateway
## Test Service
Run Service
```
$ go run server/main.go --registry=mdns
2016/11/03 18:41:22 Listening on [::]:55194
2016/11/03 18:41:22 Broker Listening on [::]:55195
2016/11/03 18:41:22 Registering node: go.micro.srv.greeter-1e200612-a1f5-11e6-8e84-68a86d0d36b6
```
Test Service
```
$ go run client/main.go --registry=mdns
Hello John
```
## Test Function
Run function
```
go run function/main.go --registry=mdns
```
Query function
```
go run client/main.go --registry=mdns --service_name="go.micro.fnc.greeter"
```
## Test Gateway
Run server with address set
```
go run server/main.go --registry=mdns --server_address=localhost:9090
```
Run gateway
```
go run gateway/main.go
```
Curl gateway
```
curl -d '{"name": "john"}' http://localhost:8080/greeter/hello
```
## i18n
### [中文](README_cn.md)

View File

@@ -0,0 +1,76 @@
# Greeter 问候示例服务
本示例展示基于gRPC的Go-Micro服务
## 本目录有
- **server** - Greeter的gRPC服务端
- **client** - gRPC客户端会调用一次server
- **function** - 演示gRPC Greeter function接口更多关于Function请查阅[Function](https://micro.mu/docs/writing-a-go-function_cn.html)
- **gateway** - gRPC网关
## 测试服务
运行服务
```
$ go run server/main.go --registry=mdns
2016/11/03 18:41:22 Listening on [::]:55194
2016/11/03 18:41:22 Broker Listening on [::]:55195
2016/11/03 18:41:22 Registering node: go.micro.srv.greeter-1e200612-a1f5-11e6-8e84-68a86d0d36b6
```
测试
```
$ go run client/main.go --registry=mdns
Hello John
```
## 测试 Function
运行测试
```
go run function/main.go --registry=mdns
```
调用服务
服务端的Function服务只会执行一次所以在下面的命令执行且服务端返回请求后服务端便后退出
```bash
$ go run client/main.go --registry=mdns --service_name="go.micro.fnc.greeter"
# 返回
Hello John
# 再次执行
$ go run client/main.go --registry=mdns --service_name="go.micro.fnc.greeter"
# 就会报异常,找不到服务
{"id":"go.micro.client","code":500,"detail":"none available","status":"Internal Server Error"}
```
## 测试网关
指定地址再运行服务端:
```
go run server/main.go --registry=mdns --server_address=localhost:9090
```
运行网关
```
go run gateway/main.go
```
使用curl调用网关
```
curl -d '{"name": "john"}' http://localhost:8080/greeter/hello
# 返回
{"msg":"Hello john"}
```

View File

@@ -0,0 +1,40 @@
package main
import (
"context"
"fmt"
"github.com/micro/cli"
"github.com/micro/go-micro"
"github.com/micro/go-micro/service/grpc"
hello "github.com/micro/go-micro/service/grpc/examples/greeter/server/proto/hello"
)
var (
// service to call
serviceName string
)
func main() {
service := grpc.NewService()
service.Init(
micro.Flags(cli.StringFlag{
Name: "service_name",
Value: "go.micro.srv.greeter",
Destination: &serviceName,
}),
)
cl := hello.NewSayService(serviceName, service.Client())
rsp, err := cl.Hello(context.TODO(), &hello.Request{
Name: "John",
})
if err != nil {
fmt.Println(err)
return
}
fmt.Println(rsp.Msg)
}

View File

@@ -0,0 +1,31 @@
package main
import (
"context"
"log"
"github.com/micro/go-micro"
"github.com/micro/go-micro/service/grpc"
hello "github.com/micro/go-micro/service/grpc/examples/greeter/server/proto/hello"
)
type Say struct{}
func (s *Say) Hello(ctx context.Context, req *hello.Request, rsp *hello.Response) error {
rsp.Msg = "Hello " + req.Name
return nil
}
func main() {
fn := grpc.NewFunction(
micro.Name("go.micro.fnc.greeter"),
)
fn.Init()
fn.Handle(new(Say))
if err := fn.Run(); err != nil {
log.Fatal(err)
}
}

View File

@@ -0,0 +1,99 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: github.com/micro/go-micro/service/grpc/examples/greeter/function/proto/hello/hello.proto
/*
Package go_micro_srv_greeter is a generated protocol buffer package.
It is generated from these files:
github.com/micro/go-micro/service/grpc/examples/greeter/function/proto/hello/hello.proto
It has these top-level messages:
Request
Response
*/
package go_micro_srv_greeter
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "context"
client "github.com/micro/go-micro/client"
server "github.com/micro/go-micro/server"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ client.Option
var _ server.Option
// Client API for Say service
type SayService interface {
Hello(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
}
type sayService struct {
c client.Client
serviceName string
}
func NewSayService(serviceName string, c client.Client) SayService {
if c == nil {
c = client.NewClient()
}
if len(serviceName) == 0 {
serviceName = "go.micro.srv.greeter"
}
return &sayService{
c: c,
serviceName: serviceName,
}
}
func (c *sayService) Hello(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
req := c.c.NewRequest(c.serviceName, "Say.Hello", in)
out := new(Response)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Say service
type SayHandler interface {
Hello(context.Context, *Request, *Response) error
}
func RegisterSayHandler(s server.Server, hdlr SayHandler, opts ...server.HandlerOption) {
type say interface {
Hello(ctx context.Context, in *Request, out *Response) error
}
type Say struct {
say
}
h := &sayHandler{hdlr}
s.Handle(s.NewHandler(&Say{h}, opts...))
}
type sayHandler struct {
SayHandler
}
func (h *sayHandler) Hello(ctx context.Context, in *Request, out *Response) error {
return h.SayHandler.Hello(ctx, in, out)
}

View File

@@ -0,0 +1,163 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/micro/go-micro/service/grpc/examples/greeter/function/proto/hello/hello.proto
/*
Package go_micro_srv_greeter is a generated protocol buffer package.
It is generated from these files:
github.com/micro/go-micro/service/grpc/examples/greeter/function/proto/hello/hello.proto
It has these top-level messages:
Request
Response
*/
package go_micro_srv_greeter
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Request struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
}
func (m *Request) Reset() { *m = Request{} }
func (m *Request) String() string { return proto.CompactTextString(m) }
func (*Request) ProtoMessage() {}
func (*Request) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *Request) GetName() string {
if m != nil {
return m.Name
}
return ""
}
type Response struct {
Msg string `protobuf:"bytes,1,opt,name=msg" json:"msg,omitempty"`
}
func (m *Response) Reset() { *m = Response{} }
func (m *Response) String() string { return proto.CompactTextString(m) }
func (*Response) ProtoMessage() {}
func (*Response) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *Response) GetMsg() string {
if m != nil {
return m.Msg
}
return ""
}
func init() {
proto.RegisterType((*Request)(nil), "go.micro.srv.greeter.Request")
proto.RegisterType((*Response)(nil), "go.micro.srv.greeter.Response")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for Say service
type SayClient interface {
Hello(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
}
type sayClient struct {
cc *grpc.ClientConn
}
func NewSayClient(cc *grpc.ClientConn) SayClient {
return &sayClient{cc}
}
func (c *sayClient) Hello(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
out := new(Response)
err := grpc.Invoke(ctx, "/go.micro.srv.greeter.Say/Hello", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Say service
type SayServer interface {
Hello(context.Context, *Request) (*Response, error)
}
func RegisterSayServer(s *grpc.Server, srv SayServer) {
s.RegisterService(&_Say_serviceDesc, srv)
}
func _Say_Hello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Request)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SayServer).Hello(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/go.micro.srv.greeter.Say/Hello",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SayServer).Hello(ctx, req.(*Request))
}
return interceptor(ctx, in, info, handler)
}
var _Say_serviceDesc = grpc.ServiceDesc{
ServiceName: "go.micro.srv.greeter.Say",
HandlerType: (*SayServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Hello",
Handler: _Say_Hello_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "github.com/micro/go-micro/service/grpc/examples/greeter/function/proto/hello/hello.proto",
}
func init() {
proto.RegisterFile("github.com/micro/go-micro/service/grpc/examples/greeter/function/proto/hello/hello.proto", fileDescriptor0)
}
var fileDescriptor0 = []byte{
// 187 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x8e, 0x4d, 0x0a, 0xc2, 0x30,
0x10, 0x85, 0x2d, 0xf5, 0x37, 0x2b, 0x09, 0x2e, 0x44, 0xac, 0x48, 0x57, 0x6e, 0x4c, 0x40, 0x2f,
0x51, 0xdc, 0x08, 0xf5, 0x04, 0x6d, 0x18, 0xd3, 0x42, 0x93, 0x89, 0x49, 0x2a, 0x7a, 0x7b, 0x69,
0xcc, 0x52, 0x37, 0xc3, 0x63, 0x3e, 0x66, 0xbe, 0x47, 0x2e, 0xb2, 0xf5, 0x4d, 0x5f, 0x33, 0x81,
0x8a, 0xab, 0x56, 0x58, 0xe4, 0x12, 0x8f, 0xd2, 0x1a, 0xc1, 0xe1, 0x55, 0x29, 0xd3, 0x81, 0xe3,
0xd2, 0x02, 0x78, 0xb0, 0xfc, 0xde, 0x6b, 0xe1, 0x5b, 0xd4, 0xdc, 0x58, 0xf4, 0xc8, 0x1b, 0xe8,
0xba, 0x38, 0x59, 0xd8, 0xd0, 0x95, 0x44, 0x16, 0x7e, 0x30, 0x67, 0x9f, 0x2c, 0x9e, 0xe5, 0x19,
0x99, 0x95, 0xf0, 0xe8, 0xc1, 0x79, 0x4a, 0xc9, 0x58, 0x57, 0x0a, 0xd6, 0xc9, 0x3e, 0x39, 0x2c,
0xca, 0x90, 0xf3, 0x2d, 0x99, 0x97, 0xe0, 0x0c, 0x6a, 0x07, 0x74, 0x49, 0x52, 0xe5, 0x64, 0xc4,
0x43, 0x3c, 0x5d, 0x49, 0x7a, 0xab, 0xde, 0xb4, 0x20, 0x93, 0x62, 0x10, 0xd1, 0x8c, 0xfd, 0x72,
0xb0, 0x28, 0xd8, 0xec, 0xfe, 0xe1, 0xaf, 0x20, 0x1f, 0xd5, 0xd3, 0x50, 0xf5, 0xfc, 0x09, 0x00,
0x00, 0xff, 0xff, 0x79, 0x62, 0x76, 0xe6, 0xf8, 0x00, 0x00, 0x00,
}

View File

@@ -0,0 +1,15 @@
syntax = "proto3";
package go.micro.srv.greeter;
service Say {
rpc Hello(Request) returns (Response) {}
}
message Request {
string name = 1;
}
message Response {
string msg = 1;
}

View File

@@ -0,0 +1,29 @@
# GRPC Gateway
This directory contains a grpc gateway generated using [grpc-ecosystem/grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway).
Services written with [micro/go-micro/service/grpc](https://github.com/micro/go-micro/service/grpc) are fully compatible with the grpc-gateway and any other
grpc services.
Go to [grpc-ecosystem/grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway) for details on how to generate gateways. We
have generated the gateway from the same proto as the greeter server but with additional options for the gateway.
## Usage
Run the go.micro.srv.greeter service
```
go run ../server/main.go --server_address=localhost:9090
```
Run the gateway
```
go run main.go
```
Curl your request at the gateway (localhost:8080)
```
curl -d '{"name": "john"}' http://localhost:8080/greeter/hello
```

View File

@@ -0,0 +1,44 @@
package main
import (
"context"
"flag"
"net/http"
"github.com/golang/glog"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"google.golang.org/grpc"
hello "github.com/micro/examples/grpc/gateway/proto/hello"
)
var (
// the go.micro.srv.greeter address
endpoint = flag.String("endpoint", "localhost:9090", "go.micro.srv.greeter address")
)
func run() error {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
mux := runtime.NewServeMux()
opts := []grpc.DialOption{grpc.WithInsecure()}
err := hello.RegisterSayHandlerFromEndpoint(ctx, mux, *endpoint, opts)
if err != nil {
return err
}
return http.ListenAndServe(":8080", mux)
}
func main() {
flag.Parse()
defer glog.Flush()
if err := run(); err != nil {
glog.Fatal(err)
}
}

View File

@@ -0,0 +1,161 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hello.proto
/*
Package greeter is a generated protocol buffer package.
It is generated from these files:
hello.proto
It has these top-level messages:
Request
Response
*/
package greeter
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import _ "google.golang.org/genproto/googleapis/api/annotations"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Request struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
}
func (m *Request) Reset() { *m = Request{} }
func (m *Request) String() string { return proto.CompactTextString(m) }
func (*Request) ProtoMessage() {}
func (*Request) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *Request) GetName() string {
if m != nil {
return m.Name
}
return ""
}
type Response struct {
Msg string `protobuf:"bytes,1,opt,name=msg" json:"msg,omitempty"`
}
func (m *Response) Reset() { *m = Response{} }
func (m *Response) String() string { return proto.CompactTextString(m) }
func (*Response) ProtoMessage() {}
func (*Response) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *Response) GetMsg() string {
if m != nil {
return m.Msg
}
return ""
}
func init() {
proto.RegisterType((*Request)(nil), "greeter.Request")
proto.RegisterType((*Response)(nil), "greeter.Response")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for Say service
type SayClient interface {
Hello(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
}
type sayClient struct {
cc *grpc.ClientConn
}
func NewSayClient(cc *grpc.ClientConn) SayClient {
return &sayClient{cc}
}
func (c *sayClient) Hello(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
out := new(Response)
err := grpc.Invoke(ctx, "/greeter.Say/Hello", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Say service
type SayServer interface {
Hello(context.Context, *Request) (*Response, error)
}
func RegisterSayServer(s *grpc.Server, srv SayServer) {
s.RegisterService(&_Say_serviceDesc, srv)
}
func _Say_Hello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Request)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SayServer).Hello(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/greeter.Say/Hello",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SayServer).Hello(ctx, req.(*Request))
}
return interceptor(ctx, in, info, handler)
}
var _Say_serviceDesc = grpc.ServiceDesc{
ServiceName: "greeter.Say",
HandlerType: (*SayServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Hello",
Handler: _Say_Hello_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "hello.proto",
}
func init() { proto.RegisterFile("hello.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 176 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xce, 0x48, 0xcd, 0xc9,
0xc9, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x4f, 0x2f, 0x4a, 0x4d, 0x2d, 0x49, 0x2d,
0x92, 0x92, 0x49, 0xcf, 0xcf, 0x4f, 0xcf, 0x49, 0xd5, 0x4f, 0x2c, 0xc8, 0xd4, 0x4f, 0xcc, 0xcb,
0xcb, 0x2f, 0x49, 0x2c, 0xc9, 0xcc, 0xcf, 0x2b, 0x86, 0x28, 0x53, 0x92, 0xe5, 0x62, 0x0f, 0x4a,
0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x11, 0x12, 0xe2, 0x62, 0xc9, 0x4b, 0xcc, 0x4d, 0x95, 0x60, 0x54,
0x60, 0xd4, 0xe0, 0x0c, 0x02, 0xb3, 0x95, 0x64, 0xb8, 0x38, 0x82, 0x52, 0x8b, 0x0b, 0xf2, 0xf3,
0x8a, 0x53, 0x85, 0x04, 0xb8, 0x98, 0x73, 0x8b, 0xd3, 0xa1, 0xd2, 0x20, 0xa6, 0x91, 0x1f, 0x17,
0x73, 0x70, 0x62, 0xa5, 0x90, 0x3b, 0x17, 0xab, 0x07, 0xc8, 0x66, 0x21, 0x01, 0x3d, 0xa8, 0xa5,
0x7a, 0x50, 0x33, 0xa5, 0x04, 0x91, 0x44, 0x20, 0xc6, 0x28, 0x49, 0x36, 0x5d, 0x7e, 0x32, 0x99,
0x49, 0x58, 0x89, 0x4f, 0x1f, 0x2a, 0xa5, 0x0f, 0x76, 0xb6, 0x15, 0xa3, 0x56, 0x12, 0x1b, 0xd8,
0x4d, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb4, 0x1b, 0x54, 0xae, 0xc9, 0x00, 0x00, 0x00,
}

View File

@@ -0,0 +1,112 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: hello.proto
/*
Package greeter is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package greeter
import (
"io"
"net/http"
"github.com/golang/protobuf/proto"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/status"
)
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
func request_Say_Hello_0(ctx context.Context, marshaler runtime.Marshaler, client SayClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq Request
var metadata runtime.ServerMetadata
if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.Hello(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
// RegisterSayHandlerFromEndpoint is same as RegisterSayHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterSayHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterSayHandler(ctx, mux, conn)
}
// RegisterSayHandler registers the http handlers for service Say to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterSayHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
client := NewSayClient(conn)
mux.Handle("POST", pattern_Say_Hello_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
if cn, ok := w.(http.CloseNotifier); ok {
go func(done <-chan struct{}, closed <-chan bool) {
select {
case <-done:
case <-closed:
cancel()
}
}(ctx.Done(), cn.CloseNotify())
}
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_Say_Hello_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_Say_Hello_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_Say_Hello_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"greeter", "hello"}, ""))
)
var (
forward_Say_Hello_0 = runtime.ForwardResponseMessage
)

View File

@@ -0,0 +1,22 @@
syntax = "proto3";
package greeter;
import "google/api/annotations.proto";
service Say {
rpc Hello(Request) returns (Response) {
option (google.api.http) = {
post: "/greeter/hello"
body: "*"
};
}
}
message Request {
string name = 1;
}
message Response {
string msg = 1;
}

View File

@@ -0,0 +1,35 @@
package main
import (
"context"
"log"
"github.com/micro/go-micro"
"github.com/micro/go-micro/service/grpc"
hello "github.com/micro/go-micro/service/grpc/examples/greeter/server/proto/hello"
)
type Say struct{}
func (s *Say) Hello(ctx context.Context, req *hello.Request, rsp *hello.Response) error {
log.Print("Received Say.Hello request")
rsp.Msg = "Hello " + req.Name
return nil
}
func main() {
service := grpc.NewService(
micro.Name("go.micro.srv.greeter"),
)
// optionally setup command line usage
service.Init()
// Register Handlers
hello.RegisterSayHandler(service.Server(), new(Say))
// Run server
if err := service.Run(); err != nil {
log.Fatal(err)
}
}

View File

@@ -0,0 +1,99 @@
// Code generated by protoc-gen-micro. DO NOT EDIT.
// source: github.com/micro/go-micro/service/grpc/examples/greeter/server/proto/hello/hello.proto
/*
Package go_micro_srv_greeter is a generated protocol buffer package.
It is generated from these files:
github.com/micro/go-micro/service/grpc/examples/greeter/server/proto/hello/hello.proto
It has these top-level messages:
Request
Response
*/
package go_micro_srv_greeter
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "context"
client "github.com/micro/go-micro/client"
server "github.com/micro/go-micro/server"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ client.Option
var _ server.Option
// Client API for Say service
type SayService interface {
Hello(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error)
}
type sayService struct {
c client.Client
serviceName string
}
func NewSayService(serviceName string, c client.Client) SayService {
if c == nil {
c = client.NewClient()
}
if len(serviceName) == 0 {
serviceName = "go.micro.srv.greeter"
}
return &sayService{
c: c,
serviceName: serviceName,
}
}
func (c *sayService) Hello(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) {
req := c.c.NewRequest(c.serviceName, "Say.Hello", in)
out := new(Response)
err := c.c.Call(ctx, req, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Say service
type SayHandler interface {
Hello(context.Context, *Request, *Response) error
}
func RegisterSayHandler(s server.Server, hdlr SayHandler, opts ...server.HandlerOption) {
type say interface {
Hello(ctx context.Context, in *Request, out *Response) error
}
type Say struct {
say
}
h := &sayHandler{hdlr}
s.Handle(s.NewHandler(&Say{h}, opts...))
}
type sayHandler struct {
SayHandler
}
func (h *sayHandler) Hello(ctx context.Context, in *Request, out *Response) error {
return h.SayHandler.Hello(ctx, in, out)
}

View File

@@ -0,0 +1,163 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: github.com/micro/go-micro/service/grpc/examples/greeter/server/proto/hello/hello.proto
/*
Package go_micro_srv_greeter is a generated protocol buffer package.
It is generated from these files:
github.com/micro/go-micro/service/grpc/examples/greeter/server/proto/hello/hello.proto
It has these top-level messages:
Request
Response
*/
package go_micro_srv_greeter
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Request struct {
Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
}
func (m *Request) Reset() { *m = Request{} }
func (m *Request) String() string { return proto.CompactTextString(m) }
func (*Request) ProtoMessage() {}
func (*Request) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
func (m *Request) GetName() string {
if m != nil {
return m.Name
}
return ""
}
type Response struct {
Msg string `protobuf:"bytes,1,opt,name=msg" json:"msg,omitempty"`
}
func (m *Response) Reset() { *m = Response{} }
func (m *Response) String() string { return proto.CompactTextString(m) }
func (*Response) ProtoMessage() {}
func (*Response) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *Response) GetMsg() string {
if m != nil {
return m.Msg
}
return ""
}
func init() {
proto.RegisterType((*Request)(nil), "go.micro.srv.greeter.Request")
proto.RegisterType((*Response)(nil), "go.micro.srv.greeter.Response")
}
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4
// Client API for Say service
type SayClient interface {
Hello(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
}
type sayClient struct {
cc *grpc.ClientConn
}
func NewSayClient(cc *grpc.ClientConn) SayClient {
return &sayClient{cc}
}
func (c *sayClient) Hello(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
out := new(Response)
err := grpc.Invoke(ctx, "/go.micro.srv.greeter.Say/Hello", in, out, c.cc, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// Server API for Say service
type SayServer interface {
Hello(context.Context, *Request) (*Response, error)
}
func RegisterSayServer(s *grpc.Server, srv SayServer) {
s.RegisterService(&_Say_serviceDesc, srv)
}
func _Say_Hello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(Request)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(SayServer).Hello(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/go.micro.srv.greeter.Say/Hello",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SayServer).Hello(ctx, req.(*Request))
}
return interceptor(ctx, in, info, handler)
}
var _Say_serviceDesc = grpc.ServiceDesc{
ServiceName: "go.micro.srv.greeter.Say",
HandlerType: (*SayServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Hello",
Handler: _Say_Hello_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "github.com/micro/go-micro/service/grpc/examples/greeter/server/proto/hello/hello.proto",
}
func init() {
proto.RegisterFile("github.com/micro/go-micro/service/grpc/examples/greeter/server/proto/hello/hello.proto", fileDescriptor0)
}
var fileDescriptor0 = []byte{
// 186 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x8e, 0xcd, 0xaa, 0xc2, 0x30,
0x10, 0x85, 0x6f, 0xe9, 0xfd, 0x33, 0x2b, 0x09, 0x2e, 0x44, 0xac, 0x48, 0x57, 0x6e, 0x4c, 0x40,
0x5f, 0xa2, 0x3b, 0xa1, 0x3e, 0x41, 0x5b, 0x86, 0xb4, 0xd0, 0x74, 0xe2, 0x4c, 0x5a, 0xf4, 0xed,
0xa5, 0x31, 0x4b, 0xdd, 0x0c, 0x87, 0xf9, 0x98, 0xf9, 0x8e, 0x28, 0x4c, 0xe7, 0xdb, 0xb1, 0x56,
0x0d, 0x5a, 0x6d, 0xbb, 0x86, 0x50, 0x1b, 0x3c, 0x1a, 0x72, 0x8d, 0x86, 0x7b, 0x65, 0x5d, 0x0f,
0xac, 0x0d, 0x01, 0x78, 0x20, 0xcd, 0x40, 0x13, 0x90, 0x76, 0x84, 0x1e, 0x75, 0x0b, 0x7d, 0x1f,
0xa7, 0x0a, 0x1b, 0xb9, 0x32, 0xa8, 0xc2, 0x07, 0xc5, 0x34, 0xa9, 0x78, 0x94, 0x67, 0xe2, 0xaf,
0x84, 0xdb, 0x08, 0xec, 0xa5, 0x14, 0xdf, 0x43, 0x65, 0x61, 0x9d, 0xec, 0x93, 0xc3, 0xa2, 0x0c,
0x39, 0xdf, 0x8a, 0xff, 0x12, 0xd8, 0xe1, 0xc0, 0x20, 0x97, 0x22, 0xb5, 0x6c, 0x22, 0x9e, 0xe3,
0xe9, 0x22, 0xd2, 0x6b, 0xf5, 0x90, 0x85, 0xf8, 0x29, 0x66, 0x91, 0xcc, 0xd4, 0x3b, 0x87, 0x8a,
0x82, 0xcd, 0xee, 0x13, 0x7e, 0x09, 0xf2, 0xaf, 0xfa, 0x37, 0x54, 0x3d, 0x3f, 0x03, 0x00, 0x00,
0xff, 0xff, 0xf2, 0x68, 0x96, 0xe9, 0xf6, 0x00, 0x00, 0x00,
}

View File

@@ -0,0 +1,15 @@
syntax = "proto3";
package go.micro.srv.greeter;
service Say {
rpc Hello(Request) returns (Response) {}
}
message Request {
string name = 1;
}
message Response {
string msg = 1;
}

58
service/grpc/grpc.go Normal file
View File

@@ -0,0 +1,58 @@
package grpc
import (
"time"
"github.com/micro/go-micro"
broker "github.com/micro/go-micro/broker"
client "github.com/micro/go-micro/client"
server "github.com/micro/go-micro/server"
)
// NewService returns a grpc service compatible with go-micro.Service
func NewService(opts ...micro.Option) micro.Service {
// our grpc client
c := client.NewClient()
// our grpc server
s := server.NewServer()
// our grpc broker
b := broker.NewBroker()
// create options with priority for our opts
options := []micro.Option{
micro.Client(c),
micro.Server(s),
micro.Broker(b),
}
// append passed in opts
options = append(options, opts...)
// generate and return a service
return micro.NewService(options...)
}
// NewFunction returns a grpc service compatible with go-micro.Function
func NewFunction(opts ...micro.Option) micro.Function {
// our grpc client
c := client.NewClient()
// our grpc server
s := server.NewServer()
// our grpc broker
b := broker.NewBroker()
// create options with priority for our opts
options := []micro.Option{
micro.Client(c),
micro.Server(s),
micro.Broker(b),
micro.RegisterTTL(time.Minute),
micro.RegisterInterval(time.Second * 30),
}
// append passed in opts
options = append(options, opts...)
// generate and return a function
return micro.NewFunction(options...)
}

178
service/grpc/grpc_test.go Normal file
View File

@@ -0,0 +1,178 @@
package grpc
import (
"context"
"crypto/tls"
"sync"
"testing"
"github.com/micro/go-micro"
"github.com/micro/go-micro/registry/memory"
hello "github.com/micro/go-micro/service/grpc/examples/greeter/server/proto/hello"
mls "github.com/micro/go-micro/util/tls"
)
type testHandler struct{}
func (t *testHandler) Hello(ctx context.Context, req *hello.Request, rsp *hello.Response) error {
rsp.Msg = "Hello " + req.Name
return nil
}
func TestGRPCService(t *testing.T) {
var wg sync.WaitGroup
wg.Add(1)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// create memory registry
r := memory.NewRegistry()
// create GRPC service
service := NewService(
micro.Name("test.service"),
micro.Registry(r),
micro.AfterStart(func() error {
wg.Done()
return nil
}),
micro.Context(ctx),
)
// register test handler
hello.RegisterSayHandler(service.Server(), &testHandler{})
// run service
go func() {
if err := service.Run(); err != nil {
t.Fatal(err)
}
}()
// wait for start
wg.Wait()
// create client
say := hello.NewSayService("test.service", service.Client())
// call service
rsp, err := say.Hello(context.Background(), &hello.Request{
Name: "John",
})
if err != nil {
t.Fatal(err)
}
// check message
if rsp.Msg != "Hello John" {
t.Fatalf("unexpected response %s", rsp.Msg)
}
}
func TestGRPCFunction(t *testing.T) {
var wg sync.WaitGroup
wg.Add(1)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// create service
fn := NewFunction(
micro.Name("test.function"),
micro.Registry(memory.NewRegistry()),
micro.AfterStart(func() error {
wg.Done()
return nil
}),
micro.Context(ctx),
)
// register test handler
hello.RegisterSayHandler(fn.Server(), &testHandler{})
// run service
go fn.Run()
// wait for start
wg.Wait()
// create client
say := hello.NewSayService("test.function", fn.Client())
// call service
rsp, err := say.Hello(context.Background(), &hello.Request{
Name: "John",
})
if err != nil {
t.Fatal(err)
}
// check message
if rsp.Msg != "Hello John" {
t.Fatalf("unexpected response %s", rsp.Msg)
}
}
func TestGRPCTLSService(t *testing.T) {
var wg sync.WaitGroup
wg.Add(1)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// create memory registry
r := memory.NewRegistry()
// create cert
cert, err := mls.Certificate("test.service")
if err != nil {
t.Fatal(err)
}
config := &tls.Config{
Certificates: []tls.Certificate{cert},
InsecureSkipVerify: true,
}
// create GRPC service
service := NewService(
micro.Name("test.service"),
micro.Registry(r),
micro.AfterStart(func() error {
wg.Done()
return nil
}),
micro.Context(ctx),
// set TLS config
WithTLS(config),
)
// register test handler
hello.RegisterSayHandler(service.Server(), &testHandler{})
// run service
go func() {
if err := service.Run(); err != nil {
t.Fatal(err)
}
}()
// wait for start
wg.Wait()
// create client
say := hello.NewSayService("test.service", service.Client())
// call service
rsp, err := say.Hello(context.Background(), &hello.Request{
Name: "John",
})
if err != nil {
t.Fatal(err)
}
// check message
if rsp.Msg != "Hello John" {
t.Fatalf("unexpected response %s", rsp.Msg)
}
}

21
service/grpc/options.go Normal file
View File

@@ -0,0 +1,21 @@
package grpc
import (
"crypto/tls"
"github.com/micro/go-micro"
gc "github.com/micro/go-plugins/client/grpc"
gs "github.com/micro/go-plugins/server/grpc"
)
// WithTLS sets the TLS config for the service
func WithTLS(t *tls.Config) micro.Option {
return func(o *micro.Options) {
o.Client.Init(
gc.AuthTLS(t),
)
o.Server.Init(
gs.AuthTLS(t),
)
}
}