From 38fb19589a242c53afc38fdb7f812abef6d1cf4b Mon Sep 17 00:00:00 2001 From: Vasiliy Tolstov Date: Mon, 21 Mar 2022 13:08:38 +0300 Subject: [PATCH] add combined server test Signed-off-by: Vasiliy Tolstov --- server/combo/combo_test.go | 352 ++++++++++++++++++++++++ server/combo/generate.go | 13 + server/combo/mdpb/test_micro.pb.go | 38 +++ server/combo/mdpb/test_micro_drpc.pb.go | 59 ++++ server/combo/mgpb/test_micro.pb.go | 38 +++ server/combo/mgpb/test_micro_grpc.pb.go | 59 ++++ server/combo/mhpb/test_micro.pb.go | 38 +++ server/combo/mhpb/test_micro_http.pb.go | 71 +++++ server/combo/ndpb/test_drpc.pb.go | 103 +++++++ server/combo/ngpb/test_grpc.pb.go | 108 ++++++++ server/combo/proto/test.pb.go | 286 +++++++++++++++++++ server/combo/proto/test.proto | 40 +++ 12 files changed, 1205 insertions(+) create mode 100644 server/combo/combo_test.go create mode 100644 server/combo/generate.go create mode 100644 server/combo/mdpb/test_micro.pb.go create mode 100644 server/combo/mdpb/test_micro_drpc.pb.go create mode 100644 server/combo/mgpb/test_micro.pb.go create mode 100644 server/combo/mgpb/test_micro_grpc.pb.go create mode 100644 server/combo/mhpb/test_micro.pb.go create mode 100644 server/combo/mhpb/test_micro_http.pb.go create mode 100644 server/combo/ndpb/test_drpc.pb.go create mode 100644 server/combo/ngpb/test_grpc.pb.go create mode 100644 server/combo/proto/test.pb.go create mode 100644 server/combo/proto/test.proto diff --git a/server/combo/combo_test.go b/server/combo/combo_test.go new file mode 100644 index 0000000..dfd9cd2 --- /dev/null +++ b/server/combo/combo_test.go @@ -0,0 +1,352 @@ +package combo_test + +import ( + "context" + "fmt" + "net" + "net/http" + "strconv" + "strings" + "testing" + "time" + + drpccli "go.unistack.org/micro-client-drpc/v3" + grpccli "go.unistack.org/micro-client-grpc/v3" + httpcli "go.unistack.org/micro-client-http/v3" + jsonpbcodec "go.unistack.org/micro-codec-jsonpb/v3" + protocodec "go.unistack.org/micro-codec-proto/v3" + httpsrv "go.unistack.org/micro-server-http/v3" + mdpb "go.unistack.org/micro-tests/server/combo/mdpb" + mgpb "go.unistack.org/micro-tests/server/combo/mgpb" + mhpb "go.unistack.org/micro-tests/server/combo/mhpb" + ndpb "go.unistack.org/micro-tests/server/combo/ndpb" + ngpb "go.unistack.org/micro-tests/server/combo/ngpb" + pb "go.unistack.org/micro-tests/server/combo/proto" + "go.unistack.org/micro/v3/client" + "go.unistack.org/micro/v3/codec" + "go.unistack.org/micro/v3/logger" + "go.unistack.org/micro/v3/metadata" + "go.unistack.org/micro/v3/register" + "go.unistack.org/micro/v3/server" + "golang.org/x/net/http2" + "golang.org/x/net/http2/h2c" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/encoding" + gmetadata "google.golang.org/grpc/metadata" + "google.golang.org/grpc/peer" + "google.golang.org/grpc/status" + "storj.io/drpc" + "storj.io/drpc/drpcconn" + "storj.io/drpc/drpchttp" +) + +type Handler struct { + t *testing.T +} + +const ( + grpcDefaultContentType = "application/grpc+proto" + drpcDefaultContentType = "application/drpc+proto" + httpDefaultContentType = "application/json" +) + +type wrapMicroCodec struct{ codec.Codec } + +func (w *wrapMicroCodec) Name() string { + return w.Codec.String() +} + +func (w *wrapMicroCodec) Marshal(v interface{}) ([]byte, error) { + return w.Codec.Marshal(v) +} + +func (w *wrapMicroCodec) Unmarshal(d []byte, v interface{}) error { + return w.Codec.Unmarshal(d, v) +} + +func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // ctx := r.Context() + w.Header().Add("Content-Type", httpDefaultContentType) + w.WriteHeader(http.StatusOK) + _ = jsonpbcodec.NewCodec().Write(w, nil, &pb.CallRsp{Rsp: "name_my_name"}) +} + +func (h *Handler) ServeGRPC(_ interface{}, stream grpc.ServerStream) error { + ctx := stream.Context() + + fullMethod, ok := grpc.MethodFromServerStream(stream) + if !ok { + return status.Errorf(codes.Internal, "method does not exist in context") + } + + serviceName, methodName, err := grpcServiceMethod(fullMethod) + if err != nil { + return status.New(codes.InvalidArgument, err.Error()).Err() + } + _, _ = serviceName, methodName + // get grpc metadata + gmd, ok := gmetadata.FromIncomingContext(stream.Context()) + if !ok { + gmd = gmetadata.MD{} + } + + md := metadata.New(len(gmd)) + for k, v := range gmd { + md.Set(k, strings.Join(v, ", ")) + } + + // timeout for server deadline + to, ok := md.Get("timeout") + if ok { + md.Del("timeout") + } + + // get content type + ct := grpcDefaultContentType + + if ctype, ok := md.Get("content-type"); ok { + ct = ctype + } else if ctype, ok := md.Get("x-content-type"); ok { + ct = ctype + md.Del("x-content-type") + } + + _ = ct + + // get peer from context + if p, ok := peer.FromContext(ctx); ok { + md["Remote"] = p.Addr.String() + ctx = peer.NewContext(ctx, p) + } + + // create new context + ctx = metadata.NewIncomingContext(ctx, md) + + // set the timeout if we have it + if len(to) > 0 { + if n, err := strconv.ParseUint(to, 10, 64); err == nil { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, time.Duration(n)) + defer cancel() + } + } + + frame := &codec.Frame{} + if err := stream.RecvMsg(frame); err != nil { + return err + } + + // logger.Infof(ctx, "frame: %s", frame.Data) + + if err := stream.SendMsg(&pb.CallRsp{Rsp: "name_my_name"}); err != nil { + return err + } + + return nil +} + +func grpcServiceMethod(m string) (string, string, error) { + if len(m) == 0 { + return "", "", fmt.Errorf("malformed method name: %q", m) + } + + // grpc method + if m[0] == '/' { + // [ , Foo, Bar] + // [ , package.Foo, Bar] + // [ , a.package.Foo, Bar] + parts := strings.Split(m, "/") + if len(parts) != 3 || len(parts[1]) == 0 || len(parts[2]) == 0 { + return "", "", fmt.Errorf("malformed method name: %q", m) + } + service := strings.Split(parts[1], ".") + return service[len(service)-1], parts[2], nil + } + + // non grpc method + parts := strings.Split(m, ".") + + // expect [Foo, Bar] + if len(parts) != 2 { + return "", "", fmt.Errorf("malformed method name: %q", m) + } + + return parts[0], parts[1], nil +} + +func (h *Handler) ServeDRPC(stream drpc.Stream, rpc string) error { + ctx := stream.Context() + logger.Infof(ctx, "drpc: %#+v", rpc) + return nil +} + +func (h *Handler) ServeWS(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + logger.Infof(ctx, "ws: %#+v", r) +} + +func (h *Handler) HandleRPC(stream drpc.Stream, rpc string) error { + return h.ServeDRPC(stream, rpc) +} + +func TestComboServer(t *testing.T) { + req := &pb.CallReq{Req: "my_name"} + var rsp *pb.CallRsp + + reg := register.NewRegister() + ctx := context.Background() + + h := &Handler{t: t} + + _ = logger.DefaultLogger.Init(logger.WithCallerSkipCount(3)) + encoding.RegisterCodec(&wrapMicroCodec{protocodec.NewCodec()}) + + gsrv := grpc.NewServer(grpc.UnknownServiceHandler(h.ServeGRPC)) + + comboHandler := newComboMux(h, gsrv, drpchttp.New(h)) + http2Server := &http2.Server{} + hs := &http.Server{Handler: h2c.NewHandler(comboHandler, http2Server)} + + // create server + srv := httpsrv.NewServer( + server.Address("127.0.0.1:0"), + server.Name("helloworld"), + server.Register(reg), + httpsrv.Server(hs), + ) + + // init server + if err := srv.Init(); err != nil { + t.Fatal(err) + } + + // start server + if err := srv.Start(); err != nil { + t.Fatal(err) + } + + // lookup server + service, err := reg.LookupService(ctx, "helloworld") + if err != nil { + t.Fatal(err) + } + + if len(service) != 1 { + t.Fatalf("Expected 1 service got %d: %+v", len(service), service) + } + + if len(service[0].Nodes) != 1 { + t.Fatalf("Expected 1 node got %d: %+v", len(service[0].Nodes), service[0].Nodes) + } + + mhcli := client.NewClientCallOptions(httpcli.NewClient(client.ContentType(httpDefaultContentType), client.Codec(httpDefaultContentType, jsonpbcodec.NewCodec())), client.WithAddress("http://"+service[0].Nodes[0].Address)) + + mhttpsvc := mhpb.NewTestClient("helloworld", mhcli) + + mgcli := client.NewClientCallOptions(grpccli.NewClient(client.ContentType(grpcDefaultContentType), client.Codec(grpcDefaultContentType, protocodec.NewCodec())), client.WithAddress("http://"+service[0].Nodes[0].Address)) + + mgrpcsvc := mgpb.NewTestClient("helloworld", mgcli) + + mdcli := client.NewClientCallOptions(drpccli.NewClient(client.ContentType(drpcDefaultContentType), client.Codec(drpcDefaultContentType, protocodec.NewCodec())), client.WithAddress("http://"+service[0].Nodes[0].Address)) + + mdrpcsvc := mdpb.NewTestClient("helloworld", mdcli) + + t.Logf("call via micro grpc") + rsp, err = mgrpcsvc.Call(ctx, req) + if err != nil { + t.Fatal(err) + } else { + if rsp.Rsp != "name_my_name" { + t.Fatalf("invalid response: %#+v\n", rsp) + } + } + + ngcli, err := grpc.DialContext(ctx, service[0].Nodes[0].Address, grpc.WithTransportCredentials(insecure.NewCredentials())) + if err != nil { + t.Fatal(err) + } + defer ngcli.Close() + + ngrpcsvc := ngpb.NewTestClient(ngcli) + t.Logf("call via native grpc") + rsp, err = ngrpcsvc.Call(ctx, req) + if err != nil { + t.Fatal(err) + } else { + if rsp.Rsp != "name_my_name" { + t.Fatalf("invalid response: %#+v\n", rsp) + } + } + + t.Logf("call via micro http") + rsp, err = mhttpsvc.Call(ctx, req) + if err != nil { + t.Fatal(err) + } else { + if rsp.Rsp != "name_my_name" { + t.Fatalf("invalid response: %#+v\n", rsp) + } + } + + tc, err := net.Dial("tcp", service[0].Nodes[0].Address) + if err != nil { + t.Fatal(err) + } + + ndcli := drpcconn.New(tc) + defer ndcli.Close() + + ndrpcsvc := ndpb.NewDRPCTestClient(ndcli) + + t.Logf("call via native drpc") + rsp, err = ndrpcsvc.Call(context.TODO(), req) + if err != nil { + t.Logf("native drpc err: %v", err) + // t.Fatal(err) + } else { + if rsp.Rsp != "name_my_name" { + t.Fatalf("invalid response: %#+v\n", rsp) + } + } + + t.Logf("call via micro drpc") + rsp, err = mdrpcsvc.Call(ctx, req) + if err != nil { + t.Logf("micro drpc err: %v", err) + // t.Fatal(err) + } else { + if rsp.Rsp != "name_my_name" { + t.Fatalf("invalid response: %#+v\n", rsp) + } + } +} + +func newComboMux(httph http.Handler, grpch http.Handler, drpch http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.ProtoMajor == 2 { + ct := r.Header.Get("content-type") + switch { + case strings.HasPrefix(ct, "application/grpc"): + grpch.ServeHTTP(w, r) + return + case strings.HasPrefix(ct, "application/drpc"): + drpch.ServeHTTP(w, r) + return + } + } + ws := false + for _, header := range r.Header["Upgrade"] { + if header == "websocket" { + ws = true + break + } + } + if ws { + httph.(*Handler).ServeWS(w, r) + return + } + httph.ServeHTTP(w, r) + }) +} diff --git a/server/combo/generate.go b/server/combo/generate.go new file mode 100644 index 0000000..23feaec --- /dev/null +++ b/server/combo/generate.go @@ -0,0 +1,13 @@ +package combo + +//go:generate sh -c "protoc -I./proto -I. -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v3) --go_out=paths=source_relative:./proto proto/test.proto" + +//go:generate sh -c "protoc -I./proto -I. -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v3) --go-micro_out=components='micro|http',standalone=true,debug=true,paths=source_relative:./mhpb proto/test.proto" + +//go:generate sh -c "protoc -I./proto -I. -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v3) --go-micro_out=components='micro|grpc',standalone=true,debug=true,paths=source_relative:./mgpb proto/test.proto" + +//go:generate sh -c "protoc -I./proto -I. -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v3) --go-micro_out=components='micro|drpc',standalone=true,debug=true,paths=source_relative:./mdpb proto/test.proto" + +//go:generate sh -c "protoc -I./proto -I. -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v3) --go-grpc_out=standalone=true,paths=source_relative:./ngpb proto/test.proto" + +//go:generate sh -c "protoc -I./proto -I. -I$(go list -f '{{ .Dir }}' -m go.unistack.org/micro-proto/v3) --go-drpc_out=standalone=true,json=false,paths=source_relative:./ndpb proto/test.proto" diff --git a/server/combo/mdpb/test_micro.pb.go b/server/combo/mdpb/test_micro.pb.go new file mode 100644 index 0000000..e14302e --- /dev/null +++ b/server/combo/mdpb/test_micro.pb.go @@ -0,0 +1,38 @@ +// Code generated by protoc-gen-go-micro. DO NOT EDIT. +// protoc-gen-go-micro version: v3.5.3 +// source: test.proto + +package pb + +import ( + context "context" + proto "go.unistack.org/micro-tests/server/combo/proto" + api "go.unistack.org/micro/v3/api" + client "go.unistack.org/micro/v3/client" +) + +var ( + TestName = "Test" + + TestEndpoints = []api.Endpoint{ + { + Name: "Test.Call", + Path: []string{"/v1/call"}, + Method: []string{"POST"}, + Body: "*", + Handler: "rpc", + }, + } +) + +func NewTestEndpoints() []api.Endpoint { + return TestEndpoints +} + +type TestClient interface { + Call(ctx context.Context, req *proto.CallReq, opts ...client.CallOption) (*proto.CallRsp, error) +} + +type TestServer interface { + Call(ctx context.Context, req *proto.CallReq, rsp *proto.CallRsp) error +} diff --git a/server/combo/mdpb/test_micro_drpc.pb.go b/server/combo/mdpb/test_micro_drpc.pb.go new file mode 100644 index 0000000..f7da140 --- /dev/null +++ b/server/combo/mdpb/test_micro_drpc.pb.go @@ -0,0 +1,59 @@ +// Code generated by protoc-gen-go-micro. DO NOT EDIT. +// protoc-gen-go-micro version: v3.5.3 +// source: test.proto + +package pb + +import ( + context "context" + proto "go.unistack.org/micro-tests/server/combo/proto" + api "go.unistack.org/micro/v3/api" + client "go.unistack.org/micro/v3/client" + server "go.unistack.org/micro/v3/server" + time "time" +) + +type testClient struct { + c client.Client + name string +} + +func NewTestClient(name string, c client.Client) TestClient { + return &testClient{c: c, name: name} +} + +func (c *testClient) Call(ctx context.Context, req *proto.CallReq, opts ...client.CallOption) (*proto.CallRsp, error) { + opts = append(opts, client.WithRequestTimeout(time.Second*5)) + rsp := &proto.CallRsp{} + err := c.c.Call(ctx, c.c.NewRequest(c.name, "test.v1.Test.Call", req), rsp, opts...) + if err != nil { + return nil, err + } + return rsp, nil +} + +type testServer struct { + TestServer +} + +func (h *testServer) Call(ctx context.Context, req *proto.CallReq, rsp *proto.CallRsp) error { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, time.Second*5) + defer cancel() + return h.TestServer.Call(ctx, req, rsp) +} + +func RegisterTestServer(s server.Server, sh TestServer, opts ...server.HandlerOption) error { + type test interface { + Call(ctx context.Context, req *proto.CallReq, rsp *proto.CallRsp) error + } + type Test struct { + test + } + h := &testServer{sh} + var nopts []server.HandlerOption + for _, endpoint := range TestEndpoints { + nopts = append(nopts, api.WithEndpoint(&endpoint)) + } + return s.Handle(s.NewHandler(&Test{h}, append(nopts, opts...)...)) +} diff --git a/server/combo/mgpb/test_micro.pb.go b/server/combo/mgpb/test_micro.pb.go new file mode 100644 index 0000000..e14302e --- /dev/null +++ b/server/combo/mgpb/test_micro.pb.go @@ -0,0 +1,38 @@ +// Code generated by protoc-gen-go-micro. DO NOT EDIT. +// protoc-gen-go-micro version: v3.5.3 +// source: test.proto + +package pb + +import ( + context "context" + proto "go.unistack.org/micro-tests/server/combo/proto" + api "go.unistack.org/micro/v3/api" + client "go.unistack.org/micro/v3/client" +) + +var ( + TestName = "Test" + + TestEndpoints = []api.Endpoint{ + { + Name: "Test.Call", + Path: []string{"/v1/call"}, + Method: []string{"POST"}, + Body: "*", + Handler: "rpc", + }, + } +) + +func NewTestEndpoints() []api.Endpoint { + return TestEndpoints +} + +type TestClient interface { + Call(ctx context.Context, req *proto.CallReq, opts ...client.CallOption) (*proto.CallRsp, error) +} + +type TestServer interface { + Call(ctx context.Context, req *proto.CallReq, rsp *proto.CallRsp) error +} diff --git a/server/combo/mgpb/test_micro_grpc.pb.go b/server/combo/mgpb/test_micro_grpc.pb.go new file mode 100644 index 0000000..282dcb0 --- /dev/null +++ b/server/combo/mgpb/test_micro_grpc.pb.go @@ -0,0 +1,59 @@ +// Code generated by protoc-gen-go-micro. DO NOT EDIT. +// protoc-gen-go-micro version: v3.5.3 +// source: test.proto + +package pb + +import ( + context "context" + proto "go.unistack.org/micro-tests/server/combo/proto" + api "go.unistack.org/micro/v3/api" + client "go.unistack.org/micro/v3/client" + server "go.unistack.org/micro/v3/server" + time "time" +) + +type testClient struct { + c client.Client + name string +} + +func NewTestClient(name string, c client.Client) TestClient { + return &testClient{c: c, name: name} +} + +func (c *testClient) Call(ctx context.Context, req *proto.CallReq, opts ...client.CallOption) (*proto.CallRsp, error) { + opts = append(opts, client.WithRequestTimeout(time.Second*5)) + rsp := &proto.CallRsp{} + err := c.c.Call(ctx, c.c.NewRequest(c.name, "Test.Call", req), rsp, opts...) + if err != nil { + return nil, err + } + return rsp, nil +} + +type testServer struct { + TestServer +} + +func (h *testServer) Call(ctx context.Context, req *proto.CallReq, rsp *proto.CallRsp) error { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, time.Second*5) + defer cancel() + return h.TestServer.Call(ctx, req, rsp) +} + +func RegisterTestServer(s server.Server, sh TestServer, opts ...server.HandlerOption) error { + type test interface { + Call(ctx context.Context, req *proto.CallReq, rsp *proto.CallRsp) error + } + type Test struct { + test + } + h := &testServer{sh} + var nopts []server.HandlerOption + for _, endpoint := range TestEndpoints { + nopts = append(nopts, api.WithEndpoint(&endpoint)) + } + return s.Handle(s.NewHandler(&Test{h}, append(nopts, opts...)...)) +} diff --git a/server/combo/mhpb/test_micro.pb.go b/server/combo/mhpb/test_micro.pb.go new file mode 100644 index 0000000..e14302e --- /dev/null +++ b/server/combo/mhpb/test_micro.pb.go @@ -0,0 +1,38 @@ +// Code generated by protoc-gen-go-micro. DO NOT EDIT. +// protoc-gen-go-micro version: v3.5.3 +// source: test.proto + +package pb + +import ( + context "context" + proto "go.unistack.org/micro-tests/server/combo/proto" + api "go.unistack.org/micro/v3/api" + client "go.unistack.org/micro/v3/client" +) + +var ( + TestName = "Test" + + TestEndpoints = []api.Endpoint{ + { + Name: "Test.Call", + Path: []string{"/v1/call"}, + Method: []string{"POST"}, + Body: "*", + Handler: "rpc", + }, + } +) + +func NewTestEndpoints() []api.Endpoint { + return TestEndpoints +} + +type TestClient interface { + Call(ctx context.Context, req *proto.CallReq, opts ...client.CallOption) (*proto.CallRsp, error) +} + +type TestServer interface { + Call(ctx context.Context, req *proto.CallReq, rsp *proto.CallRsp) error +} diff --git a/server/combo/mhpb/test_micro_http.pb.go b/server/combo/mhpb/test_micro_http.pb.go new file mode 100644 index 0000000..db9d474 --- /dev/null +++ b/server/combo/mhpb/test_micro_http.pb.go @@ -0,0 +1,71 @@ +// Code generated by protoc-gen-go-micro. DO NOT EDIT. +// protoc-gen-go-micro version: v3.5.3 +// source: test.proto + +package pb + +import ( + context "context" + v3 "go.unistack.org/micro-client-http/v3" + proto "go.unistack.org/micro-tests/server/combo/proto" + api "go.unistack.org/micro/v3/api" + client "go.unistack.org/micro/v3/client" + server "go.unistack.org/micro/v3/server" + http "net/http" + time "time" +) + +type testClient struct { + c client.Client + name string +} + +func NewTestClient(name string, c client.Client) TestClient { + return &testClient{c: c, name: name} +} + +func (c *testClient) Call(ctx context.Context, req *proto.CallReq, opts ...client.CallOption) (*proto.CallRsp, error) { + errmap := make(map[string]interface{}, 1) + errmap["default"] = &proto.Error{} + opts = append(opts, + v3.ErrorMap(errmap), + ) + opts = append(opts, + v3.Method(http.MethodPost), + v3.Path("/v1/call"), + v3.Body("*"), + ) + opts = append(opts, client.WithRequestTimeout(time.Second*5)) + rsp := &proto.CallRsp{} + err := c.c.Call(ctx, c.c.NewRequest(c.name, "Test.Call", req), rsp, opts...) + if err != nil { + return nil, err + } + return rsp, nil +} + +type testServer struct { + TestServer +} + +func (h *testServer) Call(ctx context.Context, req *proto.CallReq, rsp *proto.CallRsp) error { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, time.Second*5) + defer cancel() + return h.TestServer.Call(ctx, req, rsp) +} + +func RegisterTestServer(s server.Server, sh TestServer, opts ...server.HandlerOption) error { + type test interface { + Call(ctx context.Context, req *proto.CallReq, rsp *proto.CallRsp) error + } + type Test struct { + test + } + h := &testServer{sh} + var nopts []server.HandlerOption + for _, endpoint := range TestEndpoints { + nopts = append(nopts, api.WithEndpoint(&endpoint)) + } + return s.Handle(s.NewHandler(&Test{h}, append(nopts, opts...)...)) +} diff --git a/server/combo/ndpb/test_drpc.pb.go b/server/combo/ndpb/test_drpc.pb.go new file mode 100644 index 0000000..f56210a --- /dev/null +++ b/server/combo/ndpb/test_drpc.pb.go @@ -0,0 +1,103 @@ +// Code generated by protoc-gen-go-drpc. DO NOT EDIT. +// protoc-gen-go-drpc version: (devel) +// source: test.proto + +package pb + +import ( + context "context" + errors "errors" + proto1 "go.unistack.org/micro-tests/server/combo/proto" + proto "google.golang.org/protobuf/proto" + drpc "storj.io/drpc" + drpcerr "storj.io/drpc/drpcerr" +) + +type drpcEncoding_File_test_proto struct{} + +func (drpcEncoding_File_test_proto) Marshal(msg drpc.Message) ([]byte, error) { + return proto.Marshal(msg.(proto.Message)) +} + +func (drpcEncoding_File_test_proto) MarshalAppend(buf []byte, msg drpc.Message) ([]byte, error) { + return proto.MarshalOptions{}.MarshalAppend(buf, msg.(proto.Message)) +} + +func (drpcEncoding_File_test_proto) Unmarshal(buf []byte, msg drpc.Message) error { + return proto.Unmarshal(buf, msg.(proto.Message)) +} + +type DRPCTestClient interface { + DRPCConn() drpc.Conn + + Call(ctx context.Context, in *proto1.CallReq) (*proto1.CallRsp, error) +} + +type drpcTestClient struct { + cc drpc.Conn +} + +func NewDRPCTestClient(cc drpc.Conn) DRPCTestClient { + return &drpcTestClient{cc} +} + +func (c *drpcTestClient) DRPCConn() drpc.Conn { return c.cc } + +func (c *drpcTestClient) Call(ctx context.Context, in *proto1.CallReq) (*proto1.CallRsp, error) { + out := new(proto1.CallRsp) + err := c.cc.Invoke(ctx, "/test.v1.Test/Call", drpcEncoding_File_test_proto{}, in, out) + if err != nil { + return nil, err + } + return out, nil +} + +type DRPCTestServer interface { + Call(context.Context, *proto1.CallReq) (*proto1.CallRsp, error) +} + +type DRPCTestUnimplementedServer struct{} + +func (s *DRPCTestUnimplementedServer) Call(context.Context, *proto1.CallReq) (*proto1.CallRsp, error) { + return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented) +} + +type DRPCTestDescription struct{} + +func (DRPCTestDescription) NumMethods() int { return 1 } + +func (DRPCTestDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) { + switch n { + case 0: + return "/test.v1.Test/Call", drpcEncoding_File_test_proto{}, + func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) { + return srv.(DRPCTestServer). + Call( + ctx, + in1.(*proto1.CallReq), + ) + }, DRPCTestServer.Call, true + default: + return "", nil, nil, nil, false + } +} + +func DRPCRegisterTest(mux drpc.Mux, impl DRPCTestServer) error { + return mux.Register(impl, DRPCTestDescription{}) +} + +type DRPCTest_CallStream interface { + drpc.Stream + SendAndClose(*proto1.CallRsp) error +} + +type drpcTest_CallStream struct { + drpc.Stream +} + +func (x *drpcTest_CallStream) SendAndClose(m *proto1.CallRsp) error { + if err := x.MsgSend(m, drpcEncoding_File_test_proto{}); err != nil { + return err + } + return x.CloseSend() +} diff --git a/server/combo/ngpb/test_grpc.pb.go b/server/combo/ngpb/test_grpc.pb.go new file mode 100644 index 0000000..9058f91 --- /dev/null +++ b/server/combo/ngpb/test_grpc.pb.go @@ -0,0 +1,108 @@ +// Code generated by protoc-gen-go-grpc. DO NOT EDIT. +// versions: +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.19.4 +// source: test.proto + +package pb + +import ( + context "context" + proto "go.unistack.org/micro-tests/server/combo/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +// Requires gRPC-Go v1.32.0 or later. +const _ = grpc.SupportPackageIsVersion7 + +// TestClient is the client API for Test service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. +type TestClient interface { + //option (micro.api.micro_service) = { client_wrappers: ["one","two"]; }; + Call(ctx context.Context, in *proto.CallReq, opts ...grpc.CallOption) (*proto.CallRsp, error) +} + +type testClient struct { + cc grpc.ClientConnInterface +} + +func NewTestClient(cc grpc.ClientConnInterface) TestClient { + return &testClient{cc} +} + +func (c *testClient) Call(ctx context.Context, in *proto.CallReq, opts ...grpc.CallOption) (*proto.CallRsp, error) { + out := new(proto.CallRsp) + err := c.cc.Invoke(ctx, "/test.v1.Test/Call", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// TestServer is the server API for Test service. +// All implementations must embed UnimplementedTestServer +// for forward compatibility +type TestServer interface { + //option (micro.api.micro_service) = { client_wrappers: ["one","two"]; }; + Call(context.Context, *proto.CallReq) (*proto.CallRsp, error) + mustEmbedUnimplementedTestServer() +} + +// UnimplementedTestServer must be embedded to have forward compatible implementations. +type UnimplementedTestServer struct { +} + +func (UnimplementedTestServer) Call(context.Context, *proto.CallReq) (*proto.CallRsp, error) { + return nil, status.Errorf(codes.Unimplemented, "method Call not implemented") +} +func (UnimplementedTestServer) mustEmbedUnimplementedTestServer() {} + +// UnsafeTestServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to TestServer will +// result in compilation errors. +type UnsafeTestServer interface { + mustEmbedUnimplementedTestServer() +} + +func RegisterTestServer(s grpc.ServiceRegistrar, srv TestServer) { + s.RegisterService(&Test_ServiceDesc, srv) +} + +func _Test_Call_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(proto.CallReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(TestServer).Call(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/test.v1.Test/Call", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(TestServer).Call(ctx, req.(*proto.CallReq)) + } + return interceptor(ctx, in, info, handler) +} + +// Test_ServiceDesc is the grpc.ServiceDesc for Test service. +// It's only intended for direct use with grpc.RegisterService, +// and not to be introspected or modified (even as a copy) +var Test_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "test.v1.Test", + HandlerType: (*TestServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Call", + Handler: _Test_Call_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "test.proto", +} diff --git a/server/combo/proto/test.pb.go b/server/combo/proto/test.pb.go new file mode 100644 index 0000000..af60ad2 --- /dev/null +++ b/server/combo/proto/test.pb.go @@ -0,0 +1,286 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.19.4 +// source: test.proto + +package pb + +import ( + _ "go.unistack.org/micro-proto/v3/api" + _ "go.unistack.org/micro-proto/v3/openapiv3" + _ "go.unistack.org/micro-proto/v3/tag" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + _ "google.golang.org/protobuf/types/known/wrapperspb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type CallReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Req string `protobuf:"bytes,1,opt,name=req,proto3" json:"req,omitempty"` +} + +func (x *CallReq) Reset() { + *x = CallReq{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CallReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CallReq) ProtoMessage() {} + +func (x *CallReq) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CallReq.ProtoReflect.Descriptor instead. +func (*CallReq) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{0} +} + +func (x *CallReq) GetReq() string { + if x != nil { + return x.Req + } + return "" +} + +type CallRsp struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Rsp string `protobuf:"bytes,1,opt,name=rsp,proto3" json:"rsp,omitempty"` +} + +func (x *CallRsp) Reset() { + *x = CallRsp{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CallRsp) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CallRsp) ProtoMessage() {} + +func (x *CallRsp) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CallRsp.ProtoReflect.Descriptor instead. +func (*CallRsp) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{1} +} + +func (x *CallRsp) GetRsp() string { + if x != nil { + return x.Rsp + } + return "" +} + +type Error struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Err string `protobuf:"bytes,1,opt,name=err,proto3" json:"err,omitempty"` +} + +func (x *Error) Reset() { + *x = Error{} + if protoimpl.UnsafeEnabled { + mi := &file_test_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Error) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Error) ProtoMessage() {} + +func (x *Error) ProtoReflect() protoreflect.Message { + mi := &file_test_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Error.ProtoReflect.Descriptor instead. +func (*Error) Descriptor() ([]byte, []int) { + return file_test_proto_rawDescGZIP(), []int{2} +} + +func (x *Error) GetErr() string { + if x != nil { + return x.Err + } + return "" +} + +var File_test_proto protoreflect.FileDescriptor + +var file_test_proto_rawDesc = []byte{ + 0x0a, 0x0a, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x74, 0x65, + 0x73, 0x74, 0x2e, 0x76, 0x31, 0x1a, 0x0d, 0x74, 0x61, 0x67, 0x2f, 0x74, 0x61, 0x67, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x15, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x6f, 0x70, 0x65, + 0x6e, 0x61, 0x70, 0x69, 0x76, 0x33, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, + 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1b, 0x0a, 0x07, 0x43, 0x61, 0x6c, 0x6c, + 0x52, 0x65, 0x71, 0x12, 0x10, 0x0a, 0x03, 0x72, 0x65, 0x71, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x72, 0x65, 0x71, 0x22, 0x1b, 0x0a, 0x07, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x73, 0x70, + 0x12, 0x10, 0x0a, 0x03, 0x72, 0x73, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x72, + 0x73, 0x70, 0x22, 0x19, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x65, + 0x72, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x65, 0x72, 0x72, 0x32, 0x70, 0x0a, + 0x04, 0x54, 0x65, 0x73, 0x74, 0x12, 0x68, 0x0a, 0x04, 0x43, 0x61, 0x6c, 0x6c, 0x12, 0x10, 0x2e, + 0x74, 0x65, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x1a, + 0x10, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x61, 0x6c, 0x6c, 0x52, 0x73, + 0x70, 0x22, 0x3c, 0xaa, 0x84, 0x9e, 0x03, 0x1c, 0x2a, 0x04, 0x43, 0x61, 0x6c, 0x6c, 0x42, 0x14, + 0x0a, 0x12, 0x12, 0x10, 0x0a, 0x0e, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x76, 0x31, 0x2e, 0x45, + 0x72, 0x72, 0x6f, 0x72, 0xb2, 0xea, 0xff, 0xf9, 0x01, 0x0d, 0x22, 0x08, 0x2f, 0x76, 0x31, 0x2f, + 0x63, 0x61, 0x6c, 0x6c, 0x3a, 0x01, 0x2a, 0xba, 0xea, 0xff, 0xf9, 0x01, 0x02, 0x08, 0x05, 0x42, + 0x33, 0x5a, 0x31, 0x67, 0x6f, 0x2e, 0x75, 0x6e, 0x69, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x2e, 0x6f, + 0x72, 0x67, 0x2f, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x2d, 0x74, 0x65, 0x73, 0x74, 0x73, 0x2f, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x6d, 0x62, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x3b, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_test_proto_rawDescOnce sync.Once + file_test_proto_rawDescData = file_test_proto_rawDesc +) + +func file_test_proto_rawDescGZIP() []byte { + file_test_proto_rawDescOnce.Do(func() { + file_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_proto_rawDescData) + }) + return file_test_proto_rawDescData +} + +var file_test_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_test_proto_goTypes = []interface{}{ + (*CallReq)(nil), // 0: test.v1.CallReq + (*CallRsp)(nil), // 1: test.v1.CallRsp + (*Error)(nil), // 2: test.v1.Error +} +var file_test_proto_depIdxs = []int32{ + 0, // 0: test.v1.Test.Call:input_type -> test.v1.CallReq + 1, // 1: test.v1.Test.Call:output_type -> test.v1.CallRsp + 1, // [1:2] is the sub-list for method output_type + 0, // [0:1] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_test_proto_init() } +func file_test_proto_init() { + if File_test_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CallReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CallRsp); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Error); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_test_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_test_proto_goTypes, + DependencyIndexes: file_test_proto_depIdxs, + MessageInfos: file_test_proto_msgTypes, + }.Build() + File_test_proto = out.File + file_test_proto_rawDesc = nil + file_test_proto_goTypes = nil + file_test_proto_depIdxs = nil +} diff --git a/server/combo/proto/test.proto b/server/combo/proto/test.proto new file mode 100644 index 0000000..4fdde18 --- /dev/null +++ b/server/combo/proto/test.proto @@ -0,0 +1,40 @@ +syntax = "proto3"; + +package test.v1; + +option go_package = "go.unistack.org/micro-tests/server/combo/proto;pb"; + +import "tag/tag.proto"; +import "api/annotations.proto"; +import "openapiv3/annotations.proto"; +import "google/protobuf/wrappers.proto"; + +service Test { + //option (micro.api.micro_service) = { client_wrappers: ["one","two"]; }; + rpc Call(CallReq) returns (CallRsp) { + option (micro.openapiv3.openapiv3_operation) = { + operation_id: "Call"; + responses: { + default: { + reference: { + _ref: ".test.v1.Error"; + }; + }; + }; + }; + option (micro.api.http) = { post: "/v1/call"; body: "*"; }; + option (micro.api.micro_method) = { timeout: 5; }; + }; +}; + +message CallReq { + string req = 1; +}; + +message CallRsp { + string rsp = 1; +}; + +message Error { + string err = 1; +};