diff --git a/Documentation/server-reflection-tutorial.md b/Documentation/server-reflection-tutorial.md index 78117ff5..212d4b37 100644 --- a/Documentation/server-reflection-tutorial.md +++ b/Documentation/server-reflection-tutorial.md @@ -28,7 +28,7 @@ make the following changes: @@ -61,6 +62,8 @@ func main() { } s := grpc.NewServer() - pb.RegisterGreeterServer(s, &server{}) + pb.RegisterGreeterService(s, &pb.GreeterService{SayHello: sayHello}) + // Register reflection service on gRPC server. + reflection.Register(s) if err := s.Serve(lis); err != nil { diff --git a/balancer/grpclb/grpc_lb_v1/load_balancer.pb.go b/balancer/grpclb/grpc_lb_v1/load_balancer.pb.go index 7381dfc1..b59191ac 100644 --- a/balancer/grpclb/grpc_lb_v1/load_balancer.pb.go +++ b/balancer/grpclb/grpc_lb_v1/load_balancer.pb.go @@ -4,10 +4,14 @@ package grpc_lb_v1 import ( + context "context" fmt "fmt" proto "github.com/golang/protobuf/proto" duration "github.com/golang/protobuf/ptypes/duration" timestamp "github.com/golang/protobuf/ptypes/timestamp" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" math "math" ) @@ -638,3 +642,117 @@ var fileDescriptor_7cd3f6d792743fdf = []byte{ 0x6d, 0xe1, 0xbe, 0xfb, 0x2f, 0x00, 0x00, 0xff, 0xff, 0x3f, 0x47, 0x55, 0xac, 0xab, 0x06, 0x00, 0x00, } + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// 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.SupportPackageIsVersion6 + +// LoadBalancerClient is the client API for LoadBalancer service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type LoadBalancerClient interface { + // Bidirectional rpc to get a list of servers. + BalanceLoad(ctx context.Context, opts ...grpc.CallOption) (LoadBalancer_BalanceLoadClient, error) +} + +type loadBalancerClient struct { + cc grpc.ClientConnInterface +} + +func NewLoadBalancerClient(cc grpc.ClientConnInterface) LoadBalancerClient { + return &loadBalancerClient{cc} +} + +func (c *loadBalancerClient) BalanceLoad(ctx context.Context, opts ...grpc.CallOption) (LoadBalancer_BalanceLoadClient, error) { + stream, err := c.cc.NewStream(ctx, &_LoadBalancer_serviceDesc.Streams[0], "/grpc.lb.v1.LoadBalancer/BalanceLoad", opts...) + if err != nil { + return nil, err + } + x := &loadBalancerBalanceLoadClient{stream} + return x, nil +} + +type LoadBalancer_BalanceLoadClient interface { + Send(*LoadBalanceRequest) error + Recv() (*LoadBalanceResponse, error) + grpc.ClientStream +} + +type loadBalancerBalanceLoadClient struct { + grpc.ClientStream +} + +func (x *loadBalancerBalanceLoadClient) Send(m *LoadBalanceRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *loadBalancerBalanceLoadClient) Recv() (*LoadBalanceResponse, error) { + m := new(LoadBalanceResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// LoadBalancerServer is the server API for LoadBalancer service. +type LoadBalancerServer interface { + // Bidirectional rpc to get a list of servers. + BalanceLoad(LoadBalancer_BalanceLoadServer) error +} + +// UnimplementedLoadBalancerServer can be embedded to have forward compatible implementations. +type UnimplementedLoadBalancerServer struct { +} + +func (*UnimplementedLoadBalancerServer) BalanceLoad(srv LoadBalancer_BalanceLoadServer) error { + return status.Errorf(codes.Unimplemented, "method BalanceLoad not implemented") +} + +func RegisterLoadBalancerServer(s *grpc.Server, srv LoadBalancerServer) { + s.RegisterService(&_LoadBalancer_serviceDesc, srv) +} + +func _LoadBalancer_BalanceLoad_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(LoadBalancerServer).BalanceLoad(&loadBalancerBalanceLoadServer{stream}) +} + +type LoadBalancer_BalanceLoadServer interface { + Send(*LoadBalanceResponse) error + Recv() (*LoadBalanceRequest, error) + grpc.ServerStream +} + +type loadBalancerBalanceLoadServer struct { + grpc.ServerStream +} + +func (x *loadBalancerBalanceLoadServer) Send(m *LoadBalanceResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *loadBalancerBalanceLoadServer) Recv() (*LoadBalanceRequest, error) { + m := new(LoadBalanceRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +var _LoadBalancer_serviceDesc = grpc.ServiceDesc{ + ServiceName: "grpc.lb.v1.LoadBalancer", + HandlerType: (*LoadBalancerServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "BalanceLoad", + Handler: _LoadBalancer_BalanceLoad_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "grpc/lb/v1/load_balancer.proto", +} diff --git a/balancer/grpclb/grpc_lb_v1/load_balancer_grpc.pb.go b/balancer/grpclb/grpc_lb_v1/load_balancer_grpc.pb.go index 5a3a2ec5..0079d0fa 100644 --- a/balancer/grpclb/grpc_lb_v1/load_balancer_grpc.pb.go +++ b/balancer/grpclb/grpc_lb_v1/load_balancer_grpc.pb.go @@ -3,7 +3,6 @@ package grpc_lb_v1 import ( - context "context" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -11,112 +10,64 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 -// LoadBalancerClient is the client API for LoadBalancer 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 LoadBalancerClient interface { +// LoadBalancerService is the service API for LoadBalancer service. +// Fields should be assigned to their respective handler implementations only before +// RegisterLoadBalancerService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type LoadBalancerService struct { // Bidirectional rpc to get a list of servers. - BalanceLoad(ctx context.Context, opts ...grpc.CallOption) (LoadBalancer_BalanceLoadClient, error) + BalanceLoad func(LoadBalancer_BalanceLoadServer) error } -type loadBalancerClient struct { - cc grpc.ClientConnInterface -} - -func NewLoadBalancerClient(cc grpc.ClientConnInterface) LoadBalancerClient { - return &loadBalancerClient{cc} -} - -func (c *loadBalancerClient) BalanceLoad(ctx context.Context, opts ...grpc.CallOption) (LoadBalancer_BalanceLoadClient, error) { - stream, err := c.cc.NewStream(ctx, &_LoadBalancer_serviceDesc.Streams[0], "/grpc.lb.v1.LoadBalancer/BalanceLoad", opts...) - if err != nil { - return nil, err +func (s *LoadBalancerService) balanceLoad(_ interface{}, stream grpc.ServerStream) error { + if s.BalanceLoad == nil { + return status.Errorf(codes.Unimplemented, "method BalanceLoad not implemented") } - x := &loadBalancerBalanceLoadClient{stream} - return x, nil + return s.BalanceLoad(&loadBalancerBalanceLoadServer{stream}) } -type LoadBalancer_BalanceLoadClient interface { - Send(*LoadBalanceRequest) error - Recv() (*LoadBalanceResponse, error) - grpc.ClientStream -} - -type loadBalancerBalanceLoadClient struct { - grpc.ClientStream -} - -func (x *loadBalancerBalanceLoadClient) Send(m *LoadBalanceRequest) error { - return x.ClientStream.SendMsg(m) -} - -func (x *loadBalancerBalanceLoadClient) Recv() (*LoadBalanceResponse, error) { - m := new(LoadBalanceResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err +// RegisterLoadBalancerService registers a service implementation with a gRPC server. +func RegisterLoadBalancerService(s grpc.ServiceRegistrar, srv *LoadBalancerService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.lb.v1.LoadBalancer", + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "BalanceLoad", + Handler: srv.balanceLoad, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "grpc/lb/v1/load_balancer.proto", } - return m, nil + + s.RegisterService(&sd, nil) } -// LoadBalancerServer is the server API for LoadBalancer service. -// All implementations should embed UnimplementedLoadBalancerServer -// for forward compatibility -type LoadBalancerServer interface { +// NewLoadBalancerService creates a new LoadBalancerService containing the +// implemented methods of the LoadBalancer service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewLoadBalancerService(s interface{}) *LoadBalancerService { + ns := &LoadBalancerService{} + if h, ok := s.(interface { + BalanceLoad(LoadBalancer_BalanceLoadServer) error + }); ok { + ns.BalanceLoad = h.BalanceLoad + } + return ns +} + +// UnstableLoadBalancerService is the service API for LoadBalancer service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableLoadBalancerService interface { // Bidirectional rpc to get a list of servers. BalanceLoad(LoadBalancer_BalanceLoadServer) error } - -// UnimplementedLoadBalancerServer should be embedded to have forward compatible implementations. -type UnimplementedLoadBalancerServer struct { -} - -func (*UnimplementedLoadBalancerServer) BalanceLoad(LoadBalancer_BalanceLoadServer) error { - return status.Errorf(codes.Unimplemented, "method BalanceLoad not implemented") -} - -func RegisterLoadBalancerServer(s *grpc.Server, srv LoadBalancerServer) { - s.RegisterService(&_LoadBalancer_serviceDesc, srv) -} - -func _LoadBalancer_BalanceLoad_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(LoadBalancerServer).BalanceLoad(&loadBalancerBalanceLoadServer{stream}) -} - -type LoadBalancer_BalanceLoadServer interface { - Send(*LoadBalanceResponse) error - Recv() (*LoadBalanceRequest, error) - grpc.ServerStream -} - -type loadBalancerBalanceLoadServer struct { - grpc.ServerStream -} - -func (x *loadBalancerBalanceLoadServer) Send(m *LoadBalanceResponse) error { - return x.ServerStream.SendMsg(m) -} - -func (x *loadBalancerBalanceLoadServer) Recv() (*LoadBalanceRequest, error) { - m := new(LoadBalanceRequest) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -var _LoadBalancer_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.lb.v1.LoadBalancer", - HandlerType: (*LoadBalancerServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ - { - StreamName: "BalanceLoad", - Handler: _LoadBalancer_BalanceLoad_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "grpc/lb/v1/load_balancer.proto", -} diff --git a/balancer/grpclb/grpclb_test.go b/balancer/grpclb/grpclb_test.go index 48082e20..5a2297d4 100644 --- a/balancer/grpclb/grpclb_test.go +++ b/balancer/grpclb/grpclb_test.go @@ -276,8 +276,6 @@ func (b *remoteBalancer) BalanceLoad(stream lbgrpc.LoadBalancer_BalanceLoadServe } type testServer struct { - testpb.UnimplementedTestServiceServer - addr string fallback bool } @@ -306,7 +304,11 @@ func startBackends(sn string, fallback bool, lis ...net.Listener) (servers []*gr sn: sn, } s := grpc.NewServer(grpc.Creds(creds)) - testpb.RegisterTestServiceServer(s, &testServer{addr: l.Addr().String(), fallback: fallback}) + ts := &testServer{addr: l.Addr().String(), fallback: fallback} + testpb.RegisterTestServiceService(s, &testpb.TestServiceService{ + EmptyCall: ts.EmptyCall, + FullDuplexCall: ts.FullDuplexCall, + }) servers = append(servers, s) go func(s *grpc.Server, l net.Listener) { s.Serve(l) diff --git a/balancer/rls/internal/proto/grpc_lookup_v1/rls.pb.go b/balancer/rls/internal/proto/grpc_lookup_v1/rls.pb.go index 7ec14279..a3a3f811 100644 --- a/balancer/rls/internal/proto/grpc_lookup_v1/rls.pb.go +++ b/balancer/rls/internal/proto/grpc_lookup_v1/rls.pb.go @@ -4,8 +4,12 @@ package grpc_lookup_v1 import ( + context "context" fmt "fmt" proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" math "math" ) @@ -176,3 +180,85 @@ var fileDescriptor_3bab962d3362f3ca = []byte{ 0x29, 0xa7, 0xcf, 0x5e, 0xb3, 0x1d, 0x27, 0xef, 0x01, 0x00, 0x00, 0xff, 0xff, 0xca, 0x8d, 0x5c, 0xc7, 0x39, 0x02, 0x00, 0x00, } + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// 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.SupportPackageIsVersion6 + +// RouteLookupServiceClient is the client API for RouteLookupService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type RouteLookupServiceClient interface { + // Lookup returns a target for a single key. + RouteLookup(ctx context.Context, in *RouteLookupRequest, opts ...grpc.CallOption) (*RouteLookupResponse, error) +} + +type routeLookupServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewRouteLookupServiceClient(cc grpc.ClientConnInterface) RouteLookupServiceClient { + return &routeLookupServiceClient{cc} +} + +func (c *routeLookupServiceClient) RouteLookup(ctx context.Context, in *RouteLookupRequest, opts ...grpc.CallOption) (*RouteLookupResponse, error) { + out := new(RouteLookupResponse) + err := c.cc.Invoke(ctx, "/grpc.lookup.v1.RouteLookupService/RouteLookup", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// RouteLookupServiceServer is the server API for RouteLookupService service. +type RouteLookupServiceServer interface { + // Lookup returns a target for a single key. + RouteLookup(context.Context, *RouteLookupRequest) (*RouteLookupResponse, error) +} + +// UnimplementedRouteLookupServiceServer can be embedded to have forward compatible implementations. +type UnimplementedRouteLookupServiceServer struct { +} + +func (*UnimplementedRouteLookupServiceServer) RouteLookup(ctx context.Context, req *RouteLookupRequest) (*RouteLookupResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method RouteLookup not implemented") +} + +func RegisterRouteLookupServiceServer(s *grpc.Server, srv RouteLookupServiceServer) { + s.RegisterService(&_RouteLookupService_serviceDesc, srv) +} + +func _RouteLookupService_RouteLookup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(RouteLookupRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(RouteLookupServiceServer).RouteLookup(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.lookup.v1.RouteLookupService/RouteLookup", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(RouteLookupServiceServer).RouteLookup(ctx, req.(*RouteLookupRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _RouteLookupService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "grpc.lookup.v1.RouteLookupService", + HandlerType: (*RouteLookupServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "RouteLookup", + Handler: _RouteLookupService_RouteLookup_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "grpc/lookup/v1/rls.proto", +} diff --git a/balancer/rls/internal/proto/grpc_lookup_v1/rls_grpc.pb.go b/balancer/rls/internal/proto/grpc_lookup_v1/rls_grpc.pb.go index 79fa758f..fe1027c7 100644 --- a/balancer/rls/internal/proto/grpc_lookup_v1/rls_grpc.pb.go +++ b/balancer/rls/internal/proto/grpc_lookup_v1/rls_grpc.pb.go @@ -11,80 +11,76 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 -// RouteLookupServiceClient is the client API for RouteLookupService 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 RouteLookupServiceClient interface { +// RouteLookupServiceService is the service API for RouteLookupService service. +// Fields should be assigned to their respective handler implementations only before +// RegisterRouteLookupServiceService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type RouteLookupServiceService struct { // Lookup returns a target for a single key. - RouteLookup(ctx context.Context, in *RouteLookupRequest, opts ...grpc.CallOption) (*RouteLookupResponse, error) + RouteLookup func(context.Context, *RouteLookupRequest) (*RouteLookupResponse, error) } -type routeLookupServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewRouteLookupServiceClient(cc grpc.ClientConnInterface) RouteLookupServiceClient { - return &routeLookupServiceClient{cc} -} - -func (c *routeLookupServiceClient) RouteLookup(ctx context.Context, in *RouteLookupRequest, opts ...grpc.CallOption) (*RouteLookupResponse, error) { - out := new(RouteLookupResponse) - err := c.cc.Invoke(ctx, "/grpc.lookup.v1.RouteLookupService/RouteLookup", in, out, opts...) - if err != nil { - return nil, err +func (s *RouteLookupServiceService) routeLookup(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.RouteLookup == nil { + return nil, status.Errorf(codes.Unimplemented, "method RouteLookup not implemented") } - return out, nil -} - -// RouteLookupServiceServer is the server API for RouteLookupService service. -// All implementations should embed UnimplementedRouteLookupServiceServer -// for forward compatibility -type RouteLookupServiceServer interface { - // Lookup returns a target for a single key. - RouteLookup(context.Context, *RouteLookupRequest) (*RouteLookupResponse, error) -} - -// UnimplementedRouteLookupServiceServer should be embedded to have forward compatible implementations. -type UnimplementedRouteLookupServiceServer struct { -} - -func (*UnimplementedRouteLookupServiceServer) RouteLookup(context.Context, *RouteLookupRequest) (*RouteLookupResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method RouteLookup not implemented") -} - -func RegisterRouteLookupServiceServer(s *grpc.Server, srv RouteLookupServiceServer) { - s.RegisterService(&_RouteLookupService_serviceDesc, srv) -} - -func _RouteLookupService_RouteLookup_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(RouteLookupRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(RouteLookupServiceServer).RouteLookup(ctx, in) + return s.RouteLookup(ctx, in) } info := &grpc.UnaryServerInfo{ - Server: srv, + Server: s, FullMethod: "/grpc.lookup.v1.RouteLookupService/RouteLookup", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RouteLookupServiceServer).RouteLookup(ctx, req.(*RouteLookupRequest)) + return s.RouteLookup(ctx, req.(*RouteLookupRequest)) } return interceptor(ctx, in, info, handler) } -var _RouteLookupService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.lookup.v1.RouteLookupService", - HandlerType: (*RouteLookupServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "RouteLookup", - Handler: _RouteLookupService_RouteLookup_Handler, +// RegisterRouteLookupServiceService registers a service implementation with a gRPC server. +func RegisterRouteLookupServiceService(s grpc.ServiceRegistrar, srv *RouteLookupServiceService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.lookup.v1.RouteLookupService", + Methods: []grpc.MethodDesc{ + { + MethodName: "RouteLookup", + Handler: srv.routeLookup, + }, }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "grpc/lookup/v1/rls.proto", + Streams: []grpc.StreamDesc{}, + Metadata: "grpc/lookup/v1/rls.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewRouteLookupServiceService creates a new RouteLookupServiceService containing the +// implemented methods of the RouteLookupService service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewRouteLookupServiceService(s interface{}) *RouteLookupServiceService { + ns := &RouteLookupServiceService{} + if h, ok := s.(interface { + RouteLookup(context.Context, *RouteLookupRequest) (*RouteLookupResponse, error) + }); ok { + ns.RouteLookup = h.RouteLookup + } + return ns +} + +// UnstableRouteLookupServiceService is the service API for RouteLookupService service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableRouteLookupServiceService interface { + // Lookup returns a target for a single key. + RouteLookup(context.Context, *RouteLookupRequest) (*RouteLookupResponse, error) } diff --git a/balancer/roundrobin/roundrobin_test.go b/balancer/roundrobin/roundrobin_test.go index 5a8ba481..0c54465a 100644 --- a/balancer/roundrobin/roundrobin_test.go +++ b/balancer/roundrobin/roundrobin_test.go @@ -47,15 +47,11 @@ func Test(t *testing.T) { grpctest.RunSubTests(t, s{}) } -type testServer struct { - testpb.UnimplementedTestServiceServer -} - -func (s *testServer) EmptyCall(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { +func emptyCall(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { return &testpb.Empty{}, nil } -func (s *testServer) FullDuplexCall(stream testpb.TestService_FullDuplexCallServer) error { +func fullDuplexCall(stream testpb.TestService_FullDuplexCallServer) error { return nil } @@ -85,7 +81,10 @@ func startTestServers(count int) (_ *test, err error) { } s := grpc.NewServer() - testpb.RegisterTestServiceServer(s, &testServer{}) + testpb.RegisterTestServiceService(s, &testpb.TestServiceService{ + EmptyCall: emptyCall, + FullDuplexCall: fullDuplexCall, + }) t.servers = append(t.servers, s) t.addresses = append(t.addresses, lis.Addr().String()) diff --git a/benchmark/benchmark.go b/benchmark/benchmark.go index 56841e17..d2783a87 100644 --- a/benchmark/benchmark.go +++ b/benchmark/benchmark.go @@ -61,9 +61,9 @@ func NewPayload(t testpb.PayloadType, size int) *testpb.Payload { return p } -type testServer struct { - testpb.UnimplementedBenchmarkServiceServer -} +type testServer struct{} + +var _ testpb.UnstableBenchmarkServiceService = (*testServer)(nil) func (s *testServer) UnaryCall(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { return &testpb.SimpleResponse{ @@ -144,10 +144,11 @@ func (s *testServer) UnconstrainedStreamingCall(stream testpb.BenchmarkService_U // byteBufServer is a gRPC server that sends and receives byte buffer. // The purpose is to benchmark the gRPC performance without protobuf serialization/deserialization overhead. type byteBufServer struct { - testpb.UnimplementedBenchmarkServiceServer respSize int32 } +var _ testpb.UnstableBenchmarkServiceService = (*byteBufServer)(nil) + // UnaryCall is an empty function and is not used for benchmark. // If bytebuf UnaryCall benchmark is needed later, the function body needs to be updated. func (s *byteBufServer) UnaryCall(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { @@ -211,13 +212,13 @@ func StartServer(info ServerInfo, opts ...grpc.ServerOption) func() { s := grpc.NewServer(opts...) switch info.Type { case "protobuf": - testpb.RegisterBenchmarkServiceServer(s, &testServer{}) + testpb.RegisterBenchmarkServiceService(s, testpb.NewBenchmarkServiceService(&testServer{})) case "bytebuf": respSize, ok := info.Metadata.(int32) if !ok { logger.Fatalf("failed to StartServer, invalid metadata: %v, for Type: %v", info.Metadata, info.Type) } - testpb.RegisterBenchmarkServiceServer(s, &byteBufServer{respSize: respSize}) + testpb.RegisterBenchmarkServiceService(s, testpb.NewBenchmarkServiceService(&byteBufServer{respSize: respSize})) default: logger.Fatalf("failed to StartServer, unknown Type: %v", info.Type) } diff --git a/benchmark/grpc_testing/services_grpc.pb.go b/benchmark/grpc_testing/services_grpc.pb.go index 385870ae..60be6cd6 100644 --- a/benchmark/grpc_testing/services_grpc.pb.go +++ b/benchmark/grpc_testing/services_grpc.pb.go @@ -11,7 +11,7 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 // BenchmarkServiceClient is the client API for BenchmarkService service. // @@ -36,6 +36,10 @@ func NewBenchmarkServiceClient(cc grpc.ClientConnInterface) BenchmarkServiceClie return &benchmarkServiceClient{cc} } +var benchmarkServiceUnaryCallStreamDesc = &grpc.StreamDesc{ + StreamName: "UnaryCall", +} + func (c *benchmarkServiceClient) UnaryCall(ctx context.Context, in *SimpleRequest, opts ...grpc.CallOption) (*SimpleResponse, error) { out := new(SimpleResponse) err := c.cc.Invoke(ctx, "/grpc.testing.BenchmarkService/UnaryCall", in, out, opts...) @@ -45,8 +49,14 @@ func (c *benchmarkServiceClient) UnaryCall(ctx context.Context, in *SimpleReques return out, nil } +var benchmarkServiceStreamingCallStreamDesc = &grpc.StreamDesc{ + StreamName: "StreamingCall", + ServerStreams: true, + ClientStreams: true, +} + func (c *benchmarkServiceClient) StreamingCall(ctx context.Context, opts ...grpc.CallOption) (BenchmarkService_StreamingCallClient, error) { - stream, err := c.cc.NewStream(ctx, &_BenchmarkService_serviceDesc.Streams[0], "/grpc.testing.BenchmarkService/StreamingCall", opts...) + stream, err := c.cc.NewStream(ctx, benchmarkServiceStreamingCallStreamDesc, "/grpc.testing.BenchmarkService/StreamingCall", opts...) if err != nil { return nil, err } @@ -76,8 +86,14 @@ func (x *benchmarkServiceStreamingCallClient) Recv() (*SimpleResponse, error) { return m, nil } +var benchmarkServiceUnconstrainedStreamingCallStreamDesc = &grpc.StreamDesc{ + StreamName: "UnconstrainedStreamingCall", + ServerStreams: true, + ClientStreams: true, +} + func (c *benchmarkServiceClient) UnconstrainedStreamingCall(ctx context.Context, opts ...grpc.CallOption) (BenchmarkService_UnconstrainedStreamingCallClient, error) { - stream, err := c.cc.NewStream(ctx, &_BenchmarkService_serviceDesc.Streams[1], "/grpc.testing.BenchmarkService/UnconstrainedStreamingCall", opts...) + stream, err := c.cc.NewStream(ctx, benchmarkServiceUnconstrainedStreamingCallStreamDesc, "/grpc.testing.BenchmarkService/UnconstrainedStreamingCall", opts...) if err != nil { return nil, err } @@ -107,59 +123,53 @@ func (x *benchmarkServiceUnconstrainedStreamingCallClient) Recv() (*SimpleRespon return m, nil } -// BenchmarkServiceServer is the server API for BenchmarkService service. -// All implementations should embed UnimplementedBenchmarkServiceServer -// for forward compatibility -type BenchmarkServiceServer interface { +// BenchmarkServiceService is the service API for BenchmarkService service. +// Fields should be assigned to their respective handler implementations only before +// RegisterBenchmarkServiceService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type BenchmarkServiceService struct { // One request followed by one response. // The server returns the client payload as-is. - UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) + UnaryCall func(context.Context, *SimpleRequest) (*SimpleResponse, error) // One request followed by one response. // The server returns the client payload as-is. - StreamingCall(BenchmarkService_StreamingCallServer) error + StreamingCall func(BenchmarkService_StreamingCallServer) error // Unconstrainted streaming. // Both server and client keep sending & receiving simultaneously. - UnconstrainedStreamingCall(BenchmarkService_UnconstrainedStreamingCallServer) error + UnconstrainedStreamingCall func(BenchmarkService_UnconstrainedStreamingCallServer) error } -// UnimplementedBenchmarkServiceServer should be embedded to have forward compatible implementations. -type UnimplementedBenchmarkServiceServer struct { -} - -func (*UnimplementedBenchmarkServiceServer) UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UnaryCall not implemented") -} -func (*UnimplementedBenchmarkServiceServer) StreamingCall(BenchmarkService_StreamingCallServer) error { - return status.Errorf(codes.Unimplemented, "method StreamingCall not implemented") -} -func (*UnimplementedBenchmarkServiceServer) UnconstrainedStreamingCall(BenchmarkService_UnconstrainedStreamingCallServer) error { - return status.Errorf(codes.Unimplemented, "method UnconstrainedStreamingCall not implemented") -} - -func RegisterBenchmarkServiceServer(s *grpc.Server, srv BenchmarkServiceServer) { - s.RegisterService(&_BenchmarkService_serviceDesc, srv) -} - -func _BenchmarkService_UnaryCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func (s *BenchmarkServiceService) unaryCall(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.UnaryCall == nil { + return nil, status.Errorf(codes.Unimplemented, "method UnaryCall not implemented") + } in := new(SimpleRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(BenchmarkServiceServer).UnaryCall(ctx, in) + return s.UnaryCall(ctx, in) } info := &grpc.UnaryServerInfo{ - Server: srv, + Server: s, FullMethod: "/grpc.testing.BenchmarkService/UnaryCall", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BenchmarkServiceServer).UnaryCall(ctx, req.(*SimpleRequest)) + return s.UnaryCall(ctx, req.(*SimpleRequest)) } return interceptor(ctx, in, info, handler) } - -func _BenchmarkService_StreamingCall_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(BenchmarkServiceServer).StreamingCall(&benchmarkServiceStreamingCallServer{stream}) +func (s *BenchmarkServiceService) streamingCall(_ interface{}, stream grpc.ServerStream) error { + if s.StreamingCall == nil { + return status.Errorf(codes.Unimplemented, "method StreamingCall not implemented") + } + return s.StreamingCall(&benchmarkServiceStreamingCallServer{stream}) +} +func (s *BenchmarkServiceService) unconstrainedStreamingCall(_ interface{}, stream grpc.ServerStream) error { + if s.UnconstrainedStreamingCall == nil { + return status.Errorf(codes.Unimplemented, "method UnconstrainedStreamingCall not implemented") + } + return s.UnconstrainedStreamingCall(&benchmarkServiceUnconstrainedStreamingCallServer{stream}) } type BenchmarkService_StreamingCallServer interface { @@ -184,10 +194,6 @@ func (x *benchmarkServiceStreamingCallServer) Recv() (*SimpleRequest, error) { return m, nil } -func _BenchmarkService_UnconstrainedStreamingCall_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(BenchmarkServiceServer).UnconstrainedStreamingCall(&benchmarkServiceUnconstrainedStreamingCallServer{stream}) -} - type BenchmarkService_UnconstrainedStreamingCallServer interface { Send(*SimpleResponse) error Recv() (*SimpleRequest, error) @@ -210,30 +216,76 @@ func (x *benchmarkServiceUnconstrainedStreamingCallServer) Recv() (*SimpleReques return m, nil } -var _BenchmarkService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.testing.BenchmarkService", - HandlerType: (*BenchmarkServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "UnaryCall", - Handler: _BenchmarkService_UnaryCall_Handler, +// RegisterBenchmarkServiceService registers a service implementation with a gRPC server. +func RegisterBenchmarkServiceService(s grpc.ServiceRegistrar, srv *BenchmarkServiceService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.testing.BenchmarkService", + Methods: []grpc.MethodDesc{ + { + MethodName: "UnaryCall", + Handler: srv.unaryCall, + }, }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "StreamingCall", - Handler: _BenchmarkService_StreamingCall_Handler, - ServerStreams: true, - ClientStreams: true, + Streams: []grpc.StreamDesc{ + { + StreamName: "StreamingCall", + Handler: srv.streamingCall, + ServerStreams: true, + ClientStreams: true, + }, + { + StreamName: "UnconstrainedStreamingCall", + Handler: srv.unconstrainedStreamingCall, + ServerStreams: true, + ClientStreams: true, + }, }, - { - StreamName: "UnconstrainedStreamingCall", - Handler: _BenchmarkService_UnconstrainedStreamingCall_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "benchmark/grpc_testing/services.proto", + Metadata: "benchmark/grpc_testing/services.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewBenchmarkServiceService creates a new BenchmarkServiceService containing the +// implemented methods of the BenchmarkService service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewBenchmarkServiceService(s interface{}) *BenchmarkServiceService { + ns := &BenchmarkServiceService{} + if h, ok := s.(interface { + UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) + }); ok { + ns.UnaryCall = h.UnaryCall + } + if h, ok := s.(interface { + StreamingCall(BenchmarkService_StreamingCallServer) error + }); ok { + ns.StreamingCall = h.StreamingCall + } + if h, ok := s.(interface { + UnconstrainedStreamingCall(BenchmarkService_UnconstrainedStreamingCallServer) error + }); ok { + ns.UnconstrainedStreamingCall = h.UnconstrainedStreamingCall + } + return ns +} + +// UnstableBenchmarkServiceService is the service API for BenchmarkService service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableBenchmarkServiceService interface { + // One request followed by one response. + // The server returns the client payload as-is. + UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) + // One request followed by one response. + // The server returns the client payload as-is. + StreamingCall(BenchmarkService_StreamingCallServer) error + // Unconstrainted streaming. + // Both server and client keep sending & receiving simultaneously. + UnconstrainedStreamingCall(BenchmarkService_UnconstrainedStreamingCallServer) error } // WorkerServiceClient is the client API for WorkerService service. @@ -268,8 +320,14 @@ func NewWorkerServiceClient(cc grpc.ClientConnInterface) WorkerServiceClient { return &workerServiceClient{cc} } +var workerServiceRunServerStreamDesc = &grpc.StreamDesc{ + StreamName: "RunServer", + ServerStreams: true, + ClientStreams: true, +} + func (c *workerServiceClient) RunServer(ctx context.Context, opts ...grpc.CallOption) (WorkerService_RunServerClient, error) { - stream, err := c.cc.NewStream(ctx, &_WorkerService_serviceDesc.Streams[0], "/grpc.testing.WorkerService/RunServer", opts...) + stream, err := c.cc.NewStream(ctx, workerServiceRunServerStreamDesc, "/grpc.testing.WorkerService/RunServer", opts...) if err != nil { return nil, err } @@ -299,8 +357,14 @@ func (x *workerServiceRunServerClient) Recv() (*ServerStatus, error) { return m, nil } +var workerServiceRunClientStreamDesc = &grpc.StreamDesc{ + StreamName: "RunClient", + ServerStreams: true, + ClientStreams: true, +} + func (c *workerServiceClient) RunClient(ctx context.Context, opts ...grpc.CallOption) (WorkerService_RunClientClient, error) { - stream, err := c.cc.NewStream(ctx, &_WorkerService_serviceDesc.Streams[1], "/grpc.testing.WorkerService/RunClient", opts...) + stream, err := c.cc.NewStream(ctx, workerServiceRunClientStreamDesc, "/grpc.testing.WorkerService/RunClient", opts...) if err != nil { return nil, err } @@ -330,6 +394,10 @@ func (x *workerServiceRunClientClient) Recv() (*ClientStatus, error) { return m, nil } +var workerServiceCoreCountStreamDesc = &grpc.StreamDesc{ + StreamName: "CoreCount", +} + func (c *workerServiceClient) CoreCount(ctx context.Context, in *CoreRequest, opts ...grpc.CallOption) (*CoreResponse, error) { out := new(CoreResponse) err := c.cc.Invoke(ctx, "/grpc.testing.WorkerService/CoreCount", in, out, opts...) @@ -339,6 +407,10 @@ func (c *workerServiceClient) CoreCount(ctx context.Context, in *CoreRequest, op return out, nil } +var workerServiceQuitWorkerStreamDesc = &grpc.StreamDesc{ + StreamName: "QuitWorker", +} + func (c *workerServiceClient) QuitWorker(ctx context.Context, in *Void, opts ...grpc.CallOption) (*Void, error) { out := new(Void) err := c.cc.Invoke(ctx, "/grpc.testing.WorkerService/QuitWorker", in, out, opts...) @@ -348,53 +420,82 @@ func (c *workerServiceClient) QuitWorker(ctx context.Context, in *Void, opts ... return out, nil } -// WorkerServiceServer is the server API for WorkerService service. -// All implementations should embed UnimplementedWorkerServiceServer -// for forward compatibility -type WorkerServiceServer interface { +// WorkerServiceService is the service API for WorkerService service. +// Fields should be assigned to their respective handler implementations only before +// RegisterWorkerServiceService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type WorkerServiceService struct { // Start server with specified workload. // First request sent specifies the ServerConfig followed by ServerStatus // response. After that, a "Mark" can be sent anytime to request the latest // stats. Closing the stream will initiate shutdown of the test server // and once the shutdown has finished, the OK status is sent to terminate // this RPC. - RunServer(WorkerService_RunServerServer) error + RunServer func(WorkerService_RunServerServer) error // Start client with specified workload. // First request sent specifies the ClientConfig followed by ClientStatus // response. After that, a "Mark" can be sent anytime to request the latest // stats. Closing the stream will initiate shutdown of the test client // and once the shutdown has finished, the OK status is sent to terminate // this RPC. - RunClient(WorkerService_RunClientServer) error + RunClient func(WorkerService_RunClientServer) error // Just return the core count - unary call - CoreCount(context.Context, *CoreRequest) (*CoreResponse, error) + CoreCount func(context.Context, *CoreRequest) (*CoreResponse, error) // Quit this worker - QuitWorker(context.Context, *Void) (*Void, error) + QuitWorker func(context.Context, *Void) (*Void, error) } -// UnimplementedWorkerServiceServer should be embedded to have forward compatible implementations. -type UnimplementedWorkerServiceServer struct { +func (s *WorkerServiceService) runServer(_ interface{}, stream grpc.ServerStream) error { + if s.RunServer == nil { + return status.Errorf(codes.Unimplemented, "method RunServer not implemented") + } + return s.RunServer(&workerServiceRunServerServer{stream}) } - -func (*UnimplementedWorkerServiceServer) RunServer(WorkerService_RunServerServer) error { - return status.Errorf(codes.Unimplemented, "method RunServer not implemented") +func (s *WorkerServiceService) runClient(_ interface{}, stream grpc.ServerStream) error { + if s.RunClient == nil { + return status.Errorf(codes.Unimplemented, "method RunClient not implemented") + } + return s.RunClient(&workerServiceRunClientServer{stream}) } -func (*UnimplementedWorkerServiceServer) RunClient(WorkerService_RunClientServer) error { - return status.Errorf(codes.Unimplemented, "method RunClient not implemented") +func (s *WorkerServiceService) coreCount(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.CoreCount == nil { + return nil, status.Errorf(codes.Unimplemented, "method CoreCount not implemented") + } + in := new(CoreRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return s.CoreCount(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: s, + FullMethod: "/grpc.testing.WorkerService/CoreCount", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return s.CoreCount(ctx, req.(*CoreRequest)) + } + return interceptor(ctx, in, info, handler) } -func (*UnimplementedWorkerServiceServer) CoreCount(context.Context, *CoreRequest) (*CoreResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method CoreCount not implemented") -} -func (*UnimplementedWorkerServiceServer) QuitWorker(context.Context, *Void) (*Void, error) { - return nil, status.Errorf(codes.Unimplemented, "method QuitWorker not implemented") -} - -func RegisterWorkerServiceServer(s *grpc.Server, srv WorkerServiceServer) { - s.RegisterService(&_WorkerService_serviceDesc, srv) -} - -func _WorkerService_RunServer_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(WorkerServiceServer).RunServer(&workerServiceRunServerServer{stream}) +func (s *WorkerServiceService) quitWorker(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.QuitWorker == nil { + return nil, status.Errorf(codes.Unimplemented, "method QuitWorker not implemented") + } + in := new(Void) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return s.QuitWorker(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: s, + FullMethod: "/grpc.testing.WorkerService/QuitWorker", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return s.QuitWorker(ctx, req.(*Void)) + } + return interceptor(ctx, in, info, handler) } type WorkerService_RunServerServer interface { @@ -419,10 +520,6 @@ func (x *workerServiceRunServerServer) Recv() (*ServerArgs, error) { return m, nil } -func _WorkerService_RunClient_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(WorkerServiceServer).RunClient(&workerServiceRunClientServer{stream}) -} - type WorkerService_RunClientServer interface { Send(*ClientStatus) error Recv() (*ClientArgs, error) @@ -445,68 +542,92 @@ func (x *workerServiceRunClientServer) Recv() (*ClientArgs, error) { return m, nil } -func _WorkerService_CoreCount_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CoreRequest) - if err := dec(in); err != nil { - return nil, err +// RegisterWorkerServiceService registers a service implementation with a gRPC server. +func RegisterWorkerServiceService(s grpc.ServiceRegistrar, srv *WorkerServiceService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.testing.WorkerService", + Methods: []grpc.MethodDesc{ + { + MethodName: "CoreCount", + Handler: srv.coreCount, + }, + { + MethodName: "QuitWorker", + Handler: srv.quitWorker, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "RunServer", + Handler: srv.runServer, + ServerStreams: true, + ClientStreams: true, + }, + { + StreamName: "RunClient", + Handler: srv.runClient, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "benchmark/grpc_testing/services.proto", } - if interceptor == nil { - return srv.(WorkerServiceServer).CoreCount(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpc.testing.WorkerService/CoreCount", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(WorkerServiceServer).CoreCount(ctx, req.(*CoreRequest)) - } - return interceptor(ctx, in, info, handler) + + s.RegisterService(&sd, nil) } -func _WorkerService_QuitWorker_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Void) - if err := dec(in); err != nil { - return nil, err +// NewWorkerServiceService creates a new WorkerServiceService containing the +// implemented methods of the WorkerService service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewWorkerServiceService(s interface{}) *WorkerServiceService { + ns := &WorkerServiceService{} + if h, ok := s.(interface { + RunServer(WorkerService_RunServerServer) error + }); ok { + ns.RunServer = h.RunServer } - if interceptor == nil { - return srv.(WorkerServiceServer).QuitWorker(ctx, in) + if h, ok := s.(interface { + RunClient(WorkerService_RunClientServer) error + }); ok { + ns.RunClient = h.RunClient } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpc.testing.WorkerService/QuitWorker", + if h, ok := s.(interface { + CoreCount(context.Context, *CoreRequest) (*CoreResponse, error) + }); ok { + ns.CoreCount = h.CoreCount } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(WorkerServiceServer).QuitWorker(ctx, req.(*Void)) + if h, ok := s.(interface { + QuitWorker(context.Context, *Void) (*Void, error) + }); ok { + ns.QuitWorker = h.QuitWorker } - return interceptor(ctx, in, info, handler) + return ns } -var _WorkerService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.testing.WorkerService", - HandlerType: (*WorkerServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "CoreCount", - Handler: _WorkerService_CoreCount_Handler, - }, - { - MethodName: "QuitWorker", - Handler: _WorkerService_QuitWorker_Handler, - }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "RunServer", - Handler: _WorkerService_RunServer_Handler, - ServerStreams: true, - ClientStreams: true, - }, - { - StreamName: "RunClient", - Handler: _WorkerService_RunClient_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "benchmark/grpc_testing/services.proto", +// UnstableWorkerServiceService is the service API for WorkerService service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableWorkerServiceService interface { + // Start server with specified workload. + // First request sent specifies the ServerConfig followed by ServerStatus + // response. After that, a "Mark" can be sent anytime to request the latest + // stats. Closing the stream will initiate shutdown of the test server + // and once the shutdown has finished, the OK status is sent to terminate + // this RPC. + RunServer(WorkerService_RunServerServer) error + // Start client with specified workload. + // First request sent specifies the ClientConfig followed by ClientStatus + // response. After that, a "Mark" can be sent anytime to request the latest + // stats. Closing the stream will initiate shutdown of the test client + // and once the shutdown has finished, the OK status is sent to terminate + // this RPC. + RunClient(WorkerService_RunClientServer) error + // Just return the core count - unary call + CoreCount(context.Context, *CoreRequest) (*CoreResponse, error) + // Quit this worker + QuitWorker(context.Context, *Void) (*Void, error) } diff --git a/benchmark/worker/main.go b/benchmark/worker/main.go index 634f09e6..891cd01f 100644 --- a/benchmark/worker/main.go +++ b/benchmark/worker/main.go @@ -75,11 +75,12 @@ func (byteBufCodec) String() string { // workerServer implements WorkerService rpc handlers. // It can create benchmarkServer or benchmarkClient on demand. type workerServer struct { - testpb.UnimplementedWorkerServiceServer stop chan<- bool serverPort int } +var _ testpb.UnstableWorkerServiceService = (*workerServer)(nil) + func (s *workerServer) RunServer(stream testpb.WorkerService_RunServerServer) error { var bs *benchmarkServer defer func() { @@ -209,10 +210,10 @@ func main() { s := grpc.NewServer() stop := make(chan bool) - testpb.RegisterWorkerServiceServer(s, &workerServer{ + testpb.RegisterWorkerServiceService(s, testpb.NewWorkerServiceService(&workerServer{ stop: stop, serverPort: *serverPort, - }) + })) go func() { <-stop diff --git a/channelz/grpc_channelz_v1/channelz.pb.go b/channelz/grpc_channelz_v1/channelz.pb.go index 9c364e1e..34bfa5ab 100644 --- a/channelz/grpc_channelz_v1/channelz.pb.go +++ b/channelz/grpc_channelz_v1/channelz.pb.go @@ -4,12 +4,16 @@ package grpc_channelz_v1 import ( + context "context" fmt "fmt" proto "github.com/golang/protobuf/proto" any "github.com/golang/protobuf/ptypes/any" duration "github.com/golang/protobuf/ptypes/duration" timestamp "github.com/golang/protobuf/ptypes/timestamp" wrappers "github.com/golang/protobuf/ptypes/wrappers" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" math "math" ) @@ -2921,3 +2925,315 @@ var fileDescriptor_6ee37dfd35a8ab00 = []byte{ 0xd3, 0x77, 0xc6, 0x68, 0xe7, 0x3c, 0xcf, 0x4f, 0xf3, 0x5f, 0xfd, 0x37, 0x00, 0x00, 0xff, 0xff, 0x54, 0xae, 0x0b, 0x93, 0xdf, 0x1f, 0x00, 0x00, } + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// 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.SupportPackageIsVersion6 + +// ChannelzClient is the client API for Channelz service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type ChannelzClient interface { + // Gets all root channels (i.e. channels the application has directly + // created). This does not include subchannels nor non-top level channels. + GetTopChannels(ctx context.Context, in *GetTopChannelsRequest, opts ...grpc.CallOption) (*GetTopChannelsResponse, error) + // Gets all servers that exist in the process. + GetServers(ctx context.Context, in *GetServersRequest, opts ...grpc.CallOption) (*GetServersResponse, error) + // Returns a single Server, or else a NOT_FOUND code. + GetServer(ctx context.Context, in *GetServerRequest, opts ...grpc.CallOption) (*GetServerResponse, error) + // Gets all server sockets that exist in the process. + GetServerSockets(ctx context.Context, in *GetServerSocketsRequest, opts ...grpc.CallOption) (*GetServerSocketsResponse, error) + // Returns a single Channel, or else a NOT_FOUND code. + GetChannel(ctx context.Context, in *GetChannelRequest, opts ...grpc.CallOption) (*GetChannelResponse, error) + // Returns a single Subchannel, or else a NOT_FOUND code. + GetSubchannel(ctx context.Context, in *GetSubchannelRequest, opts ...grpc.CallOption) (*GetSubchannelResponse, error) + // Returns a single Socket or else a NOT_FOUND code. + GetSocket(ctx context.Context, in *GetSocketRequest, opts ...grpc.CallOption) (*GetSocketResponse, error) +} + +type channelzClient struct { + cc grpc.ClientConnInterface +} + +func NewChannelzClient(cc grpc.ClientConnInterface) ChannelzClient { + return &channelzClient{cc} +} + +func (c *channelzClient) GetTopChannels(ctx context.Context, in *GetTopChannelsRequest, opts ...grpc.CallOption) (*GetTopChannelsResponse, error) { + out := new(GetTopChannelsResponse) + err := c.cc.Invoke(ctx, "/grpc.channelz.v1.Channelz/GetTopChannels", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *channelzClient) GetServers(ctx context.Context, in *GetServersRequest, opts ...grpc.CallOption) (*GetServersResponse, error) { + out := new(GetServersResponse) + err := c.cc.Invoke(ctx, "/grpc.channelz.v1.Channelz/GetServers", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *channelzClient) GetServer(ctx context.Context, in *GetServerRequest, opts ...grpc.CallOption) (*GetServerResponse, error) { + out := new(GetServerResponse) + err := c.cc.Invoke(ctx, "/grpc.channelz.v1.Channelz/GetServer", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *channelzClient) GetServerSockets(ctx context.Context, in *GetServerSocketsRequest, opts ...grpc.CallOption) (*GetServerSocketsResponse, error) { + out := new(GetServerSocketsResponse) + err := c.cc.Invoke(ctx, "/grpc.channelz.v1.Channelz/GetServerSockets", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *channelzClient) GetChannel(ctx context.Context, in *GetChannelRequest, opts ...grpc.CallOption) (*GetChannelResponse, error) { + out := new(GetChannelResponse) + err := c.cc.Invoke(ctx, "/grpc.channelz.v1.Channelz/GetChannel", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *channelzClient) GetSubchannel(ctx context.Context, in *GetSubchannelRequest, opts ...grpc.CallOption) (*GetSubchannelResponse, error) { + out := new(GetSubchannelResponse) + err := c.cc.Invoke(ctx, "/grpc.channelz.v1.Channelz/GetSubchannel", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *channelzClient) GetSocket(ctx context.Context, in *GetSocketRequest, opts ...grpc.CallOption) (*GetSocketResponse, error) { + out := new(GetSocketResponse) + err := c.cc.Invoke(ctx, "/grpc.channelz.v1.Channelz/GetSocket", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ChannelzServer is the server API for Channelz service. +type ChannelzServer interface { + // Gets all root channels (i.e. channels the application has directly + // created). This does not include subchannels nor non-top level channels. + GetTopChannels(context.Context, *GetTopChannelsRequest) (*GetTopChannelsResponse, error) + // Gets all servers that exist in the process. + GetServers(context.Context, *GetServersRequest) (*GetServersResponse, error) + // Returns a single Server, or else a NOT_FOUND code. + GetServer(context.Context, *GetServerRequest) (*GetServerResponse, error) + // Gets all server sockets that exist in the process. + GetServerSockets(context.Context, *GetServerSocketsRequest) (*GetServerSocketsResponse, error) + // Returns a single Channel, or else a NOT_FOUND code. + GetChannel(context.Context, *GetChannelRequest) (*GetChannelResponse, error) + // Returns a single Subchannel, or else a NOT_FOUND code. + GetSubchannel(context.Context, *GetSubchannelRequest) (*GetSubchannelResponse, error) + // Returns a single Socket or else a NOT_FOUND code. + GetSocket(context.Context, *GetSocketRequest) (*GetSocketResponse, error) +} + +// UnimplementedChannelzServer can be embedded to have forward compatible implementations. +type UnimplementedChannelzServer struct { +} + +func (*UnimplementedChannelzServer) GetTopChannels(ctx context.Context, req *GetTopChannelsRequest) (*GetTopChannelsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetTopChannels not implemented") +} +func (*UnimplementedChannelzServer) GetServers(ctx context.Context, req *GetServersRequest) (*GetServersResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetServers not implemented") +} +func (*UnimplementedChannelzServer) GetServer(ctx context.Context, req *GetServerRequest) (*GetServerResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetServer not implemented") +} +func (*UnimplementedChannelzServer) GetServerSockets(ctx context.Context, req *GetServerSocketsRequest) (*GetServerSocketsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetServerSockets not implemented") +} +func (*UnimplementedChannelzServer) GetChannel(ctx context.Context, req *GetChannelRequest) (*GetChannelResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetChannel not implemented") +} +func (*UnimplementedChannelzServer) GetSubchannel(ctx context.Context, req *GetSubchannelRequest) (*GetSubchannelResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSubchannel not implemented") +} +func (*UnimplementedChannelzServer) GetSocket(ctx context.Context, req *GetSocketRequest) (*GetSocketResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetSocket not implemented") +} + +func RegisterChannelzServer(s *grpc.Server, srv ChannelzServer) { + s.RegisterService(&_Channelz_serviceDesc, srv) +} + +func _Channelz_GetTopChannels_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetTopChannelsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChannelzServer).GetTopChannels(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.channelz.v1.Channelz/GetTopChannels", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChannelzServer).GetTopChannels(ctx, req.(*GetTopChannelsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Channelz_GetServers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetServersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChannelzServer).GetServers(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.channelz.v1.Channelz/GetServers", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChannelzServer).GetServers(ctx, req.(*GetServersRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Channelz_GetServer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetServerRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChannelzServer).GetServer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.channelz.v1.Channelz/GetServer", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChannelzServer).GetServer(ctx, req.(*GetServerRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Channelz_GetServerSockets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetServerSocketsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChannelzServer).GetServerSockets(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.channelz.v1.Channelz/GetServerSockets", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChannelzServer).GetServerSockets(ctx, req.(*GetServerSocketsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Channelz_GetChannel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetChannelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChannelzServer).GetChannel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.channelz.v1.Channelz/GetChannel", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChannelzServer).GetChannel(ctx, req.(*GetChannelRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Channelz_GetSubchannel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetSubchannelRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChannelzServer).GetSubchannel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.channelz.v1.Channelz/GetSubchannel", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChannelzServer).GetSubchannel(ctx, req.(*GetSubchannelRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Channelz_GetSocket_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetSocketRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ChannelzServer).GetSocket(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.channelz.v1.Channelz/GetSocket", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ChannelzServer).GetSocket(ctx, req.(*GetSocketRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Channelz_serviceDesc = grpc.ServiceDesc{ + ServiceName: "grpc.channelz.v1.Channelz", + HandlerType: (*ChannelzServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "GetTopChannels", + Handler: _Channelz_GetTopChannels_Handler, + }, + { + MethodName: "GetServers", + Handler: _Channelz_GetServers_Handler, + }, + { + MethodName: "GetServer", + Handler: _Channelz_GetServer_Handler, + }, + { + MethodName: "GetServerSockets", + Handler: _Channelz_GetServerSockets_Handler, + }, + { + MethodName: "GetChannel", + Handler: _Channelz_GetChannel_Handler, + }, + { + MethodName: "GetSubchannel", + Handler: _Channelz_GetSubchannel_Handler, + }, + { + MethodName: "GetSocket", + Handler: _Channelz_GetSocket_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "grpc/channelz/v1/channelz.proto", +} diff --git a/channelz/grpc_channelz_v1/channelz_grpc.pb.go b/channelz/grpc_channelz_v1/channelz_grpc.pb.go index 20e1fe70..e4815814 100644 --- a/channelz/grpc_channelz_v1/channelz_grpc.pb.go +++ b/channelz/grpc_channelz_v1/channelz_grpc.pb.go @@ -11,104 +11,263 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 -// ChannelzClient is the client API for Channelz 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 ChannelzClient interface { +// ChannelzService is the service API for Channelz service. +// Fields should be assigned to their respective handler implementations only before +// RegisterChannelzService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type ChannelzService struct { // Gets all root channels (i.e. channels the application has directly // created). This does not include subchannels nor non-top level channels. - GetTopChannels(ctx context.Context, in *GetTopChannelsRequest, opts ...grpc.CallOption) (*GetTopChannelsResponse, error) + GetTopChannels func(context.Context, *GetTopChannelsRequest) (*GetTopChannelsResponse, error) // Gets all servers that exist in the process. - GetServers(ctx context.Context, in *GetServersRequest, opts ...grpc.CallOption) (*GetServersResponse, error) + GetServers func(context.Context, *GetServersRequest) (*GetServersResponse, error) // Returns a single Server, or else a NOT_FOUND code. - GetServer(ctx context.Context, in *GetServerRequest, opts ...grpc.CallOption) (*GetServerResponse, error) + GetServer func(context.Context, *GetServerRequest) (*GetServerResponse, error) // Gets all server sockets that exist in the process. - GetServerSockets(ctx context.Context, in *GetServerSocketsRequest, opts ...grpc.CallOption) (*GetServerSocketsResponse, error) + GetServerSockets func(context.Context, *GetServerSocketsRequest) (*GetServerSocketsResponse, error) // Returns a single Channel, or else a NOT_FOUND code. - GetChannel(ctx context.Context, in *GetChannelRequest, opts ...grpc.CallOption) (*GetChannelResponse, error) + GetChannel func(context.Context, *GetChannelRequest) (*GetChannelResponse, error) // Returns a single Subchannel, or else a NOT_FOUND code. - GetSubchannel(ctx context.Context, in *GetSubchannelRequest, opts ...grpc.CallOption) (*GetSubchannelResponse, error) + GetSubchannel func(context.Context, *GetSubchannelRequest) (*GetSubchannelResponse, error) // Returns a single Socket or else a NOT_FOUND code. - GetSocket(ctx context.Context, in *GetSocketRequest, opts ...grpc.CallOption) (*GetSocketResponse, error) + GetSocket func(context.Context, *GetSocketRequest) (*GetSocketResponse, error) } -type channelzClient struct { - cc grpc.ClientConnInterface -} - -func NewChannelzClient(cc grpc.ClientConnInterface) ChannelzClient { - return &channelzClient{cc} -} - -func (c *channelzClient) GetTopChannels(ctx context.Context, in *GetTopChannelsRequest, opts ...grpc.CallOption) (*GetTopChannelsResponse, error) { - out := new(GetTopChannelsResponse) - err := c.cc.Invoke(ctx, "/grpc.channelz.v1.Channelz/GetTopChannels", in, out, opts...) - if err != nil { +func (s *ChannelzService) getTopChannels(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.GetTopChannels == nil { + return nil, status.Errorf(codes.Unimplemented, "method GetTopChannels not implemented") + } + in := new(GetTopChannelsRequest) + if err := dec(in); err != nil { return nil, err } - return out, nil + if interceptor == nil { + return s.GetTopChannels(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: s, + FullMethod: "/grpc.channelz.v1.Channelz/GetTopChannels", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return s.GetTopChannels(ctx, req.(*GetTopChannelsRequest)) + } + return interceptor(ctx, in, info, handler) } - -func (c *channelzClient) GetServers(ctx context.Context, in *GetServersRequest, opts ...grpc.CallOption) (*GetServersResponse, error) { - out := new(GetServersResponse) - err := c.cc.Invoke(ctx, "/grpc.channelz.v1.Channelz/GetServers", in, out, opts...) - if err != nil { +func (s *ChannelzService) getServers(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.GetServers == nil { + return nil, status.Errorf(codes.Unimplemented, "method GetServers not implemented") + } + in := new(GetServersRequest) + if err := dec(in); err != nil { return nil, err } - return out, nil + if interceptor == nil { + return s.GetServers(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: s, + FullMethod: "/grpc.channelz.v1.Channelz/GetServers", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return s.GetServers(ctx, req.(*GetServersRequest)) + } + return interceptor(ctx, in, info, handler) } - -func (c *channelzClient) GetServer(ctx context.Context, in *GetServerRequest, opts ...grpc.CallOption) (*GetServerResponse, error) { - out := new(GetServerResponse) - err := c.cc.Invoke(ctx, "/grpc.channelz.v1.Channelz/GetServer", in, out, opts...) - if err != nil { +func (s *ChannelzService) getServer(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.GetServer == nil { + return nil, status.Errorf(codes.Unimplemented, "method GetServer not implemented") + } + in := new(GetServerRequest) + if err := dec(in); err != nil { return nil, err } - return out, nil + if interceptor == nil { + return s.GetServer(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: s, + FullMethod: "/grpc.channelz.v1.Channelz/GetServer", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return s.GetServer(ctx, req.(*GetServerRequest)) + } + return interceptor(ctx, in, info, handler) } - -func (c *channelzClient) GetServerSockets(ctx context.Context, in *GetServerSocketsRequest, opts ...grpc.CallOption) (*GetServerSocketsResponse, error) { - out := new(GetServerSocketsResponse) - err := c.cc.Invoke(ctx, "/grpc.channelz.v1.Channelz/GetServerSockets", in, out, opts...) - if err != nil { +func (s *ChannelzService) getServerSockets(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.GetServerSockets == nil { + return nil, status.Errorf(codes.Unimplemented, "method GetServerSockets not implemented") + } + in := new(GetServerSocketsRequest) + if err := dec(in); err != nil { return nil, err } - return out, nil + if interceptor == nil { + return s.GetServerSockets(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: s, + FullMethod: "/grpc.channelz.v1.Channelz/GetServerSockets", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return s.GetServerSockets(ctx, req.(*GetServerSocketsRequest)) + } + return interceptor(ctx, in, info, handler) } - -func (c *channelzClient) GetChannel(ctx context.Context, in *GetChannelRequest, opts ...grpc.CallOption) (*GetChannelResponse, error) { - out := new(GetChannelResponse) - err := c.cc.Invoke(ctx, "/grpc.channelz.v1.Channelz/GetChannel", in, out, opts...) - if err != nil { +func (s *ChannelzService) getChannel(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.GetChannel == nil { + return nil, status.Errorf(codes.Unimplemented, "method GetChannel not implemented") + } + in := new(GetChannelRequest) + if err := dec(in); err != nil { return nil, err } - return out, nil + if interceptor == nil { + return s.GetChannel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: s, + FullMethod: "/grpc.channelz.v1.Channelz/GetChannel", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return s.GetChannel(ctx, req.(*GetChannelRequest)) + } + return interceptor(ctx, in, info, handler) } - -func (c *channelzClient) GetSubchannel(ctx context.Context, in *GetSubchannelRequest, opts ...grpc.CallOption) (*GetSubchannelResponse, error) { - out := new(GetSubchannelResponse) - err := c.cc.Invoke(ctx, "/grpc.channelz.v1.Channelz/GetSubchannel", in, out, opts...) - if err != nil { +func (s *ChannelzService) getSubchannel(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.GetSubchannel == nil { + return nil, status.Errorf(codes.Unimplemented, "method GetSubchannel not implemented") + } + in := new(GetSubchannelRequest) + if err := dec(in); err != nil { return nil, err } - return out, nil + if interceptor == nil { + return s.GetSubchannel(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: s, + FullMethod: "/grpc.channelz.v1.Channelz/GetSubchannel", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return s.GetSubchannel(ctx, req.(*GetSubchannelRequest)) + } + return interceptor(ctx, in, info, handler) } - -func (c *channelzClient) GetSocket(ctx context.Context, in *GetSocketRequest, opts ...grpc.CallOption) (*GetSocketResponse, error) { - out := new(GetSocketResponse) - err := c.cc.Invoke(ctx, "/grpc.channelz.v1.Channelz/GetSocket", in, out, opts...) - if err != nil { +func (s *ChannelzService) getSocket(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.GetSocket == nil { + return nil, status.Errorf(codes.Unimplemented, "method GetSocket not implemented") + } + in := new(GetSocketRequest) + if err := dec(in); err != nil { return nil, err } - return out, nil + if interceptor == nil { + return s.GetSocket(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: s, + FullMethod: "/grpc.channelz.v1.Channelz/GetSocket", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return s.GetSocket(ctx, req.(*GetSocketRequest)) + } + return interceptor(ctx, in, info, handler) } -// ChannelzServer is the server API for Channelz service. -// All implementations should embed UnimplementedChannelzServer -// for forward compatibility -type ChannelzServer interface { +// RegisterChannelzService registers a service implementation with a gRPC server. +func RegisterChannelzService(s grpc.ServiceRegistrar, srv *ChannelzService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.channelz.v1.Channelz", + Methods: []grpc.MethodDesc{ + { + MethodName: "GetTopChannels", + Handler: srv.getTopChannels, + }, + { + MethodName: "GetServers", + Handler: srv.getServers, + }, + { + MethodName: "GetServer", + Handler: srv.getServer, + }, + { + MethodName: "GetServerSockets", + Handler: srv.getServerSockets, + }, + { + MethodName: "GetChannel", + Handler: srv.getChannel, + }, + { + MethodName: "GetSubchannel", + Handler: srv.getSubchannel, + }, + { + MethodName: "GetSocket", + Handler: srv.getSocket, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "grpc/channelz/v1/channelz.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewChannelzService creates a new ChannelzService containing the +// implemented methods of the Channelz service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewChannelzService(s interface{}) *ChannelzService { + ns := &ChannelzService{} + if h, ok := s.(interface { + GetTopChannels(context.Context, *GetTopChannelsRequest) (*GetTopChannelsResponse, error) + }); ok { + ns.GetTopChannels = h.GetTopChannels + } + if h, ok := s.(interface { + GetServers(context.Context, *GetServersRequest) (*GetServersResponse, error) + }); ok { + ns.GetServers = h.GetServers + } + if h, ok := s.(interface { + GetServer(context.Context, *GetServerRequest) (*GetServerResponse, error) + }); ok { + ns.GetServer = h.GetServer + } + if h, ok := s.(interface { + GetServerSockets(context.Context, *GetServerSocketsRequest) (*GetServerSocketsResponse, error) + }); ok { + ns.GetServerSockets = h.GetServerSockets + } + if h, ok := s.(interface { + GetChannel(context.Context, *GetChannelRequest) (*GetChannelResponse, error) + }); ok { + ns.GetChannel = h.GetChannel + } + if h, ok := s.(interface { + GetSubchannel(context.Context, *GetSubchannelRequest) (*GetSubchannelResponse, error) + }); ok { + ns.GetSubchannel = h.GetSubchannel + } + if h, ok := s.(interface { + GetSocket(context.Context, *GetSocketRequest) (*GetSocketResponse, error) + }); ok { + ns.GetSocket = h.GetSocket + } + return ns +} + +// UnstableChannelzService is the service API for Channelz service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableChannelzService interface { // Gets all root channels (i.e. channels the application has directly // created). This does not include subchannels nor non-top level channels. GetTopChannels(context.Context, *GetTopChannelsRequest) (*GetTopChannelsResponse, error) @@ -125,196 +284,3 @@ type ChannelzServer interface { // Returns a single Socket or else a NOT_FOUND code. GetSocket(context.Context, *GetSocketRequest) (*GetSocketResponse, error) } - -// UnimplementedChannelzServer should be embedded to have forward compatible implementations. -type UnimplementedChannelzServer struct { -} - -func (*UnimplementedChannelzServer) GetTopChannels(context.Context, *GetTopChannelsRequest) (*GetTopChannelsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetTopChannels not implemented") -} -func (*UnimplementedChannelzServer) GetServers(context.Context, *GetServersRequest) (*GetServersResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetServers not implemented") -} -func (*UnimplementedChannelzServer) GetServer(context.Context, *GetServerRequest) (*GetServerResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetServer not implemented") -} -func (*UnimplementedChannelzServer) GetServerSockets(context.Context, *GetServerSocketsRequest) (*GetServerSocketsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetServerSockets not implemented") -} -func (*UnimplementedChannelzServer) GetChannel(context.Context, *GetChannelRequest) (*GetChannelResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetChannel not implemented") -} -func (*UnimplementedChannelzServer) GetSubchannel(context.Context, *GetSubchannelRequest) (*GetSubchannelResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetSubchannel not implemented") -} -func (*UnimplementedChannelzServer) GetSocket(context.Context, *GetSocketRequest) (*GetSocketResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetSocket not implemented") -} - -func RegisterChannelzServer(s *grpc.Server, srv ChannelzServer) { - s.RegisterService(&_Channelz_serviceDesc, srv) -} - -func _Channelz_GetTopChannels_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetTopChannelsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ChannelzServer).GetTopChannels(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpc.channelz.v1.Channelz/GetTopChannels", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ChannelzServer).GetTopChannels(ctx, req.(*GetTopChannelsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Channelz_GetServers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetServersRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ChannelzServer).GetServers(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpc.channelz.v1.Channelz/GetServers", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ChannelzServer).GetServers(ctx, req.(*GetServersRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Channelz_GetServer_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetServerRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ChannelzServer).GetServer(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpc.channelz.v1.Channelz/GetServer", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ChannelzServer).GetServer(ctx, req.(*GetServerRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Channelz_GetServerSockets_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetServerSocketsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ChannelzServer).GetServerSockets(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpc.channelz.v1.Channelz/GetServerSockets", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ChannelzServer).GetServerSockets(ctx, req.(*GetServerSocketsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Channelz_GetChannel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetChannelRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ChannelzServer).GetChannel(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpc.channelz.v1.Channelz/GetChannel", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ChannelzServer).GetChannel(ctx, req.(*GetChannelRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Channelz_GetSubchannel_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetSubchannelRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ChannelzServer).GetSubchannel(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpc.channelz.v1.Channelz/GetSubchannel", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ChannelzServer).GetSubchannel(ctx, req.(*GetSubchannelRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Channelz_GetSocket_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetSocketRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ChannelzServer).GetSocket(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpc.channelz.v1.Channelz/GetSocket", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ChannelzServer).GetSocket(ctx, req.(*GetSocketRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _Channelz_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.channelz.v1.Channelz", - HandlerType: (*ChannelzServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "GetTopChannels", - Handler: _Channelz_GetTopChannels_Handler, - }, - { - MethodName: "GetServers", - Handler: _Channelz_GetServers_Handler, - }, - { - MethodName: "GetServer", - Handler: _Channelz_GetServer_Handler, - }, - { - MethodName: "GetServerSockets", - Handler: _Channelz_GetServerSockets_Handler, - }, - { - MethodName: "GetChannel", - Handler: _Channelz_GetChannel_Handler, - }, - { - MethodName: "GetSubchannel", - Handler: _Channelz_GetSubchannel_Handler, - }, - { - MethodName: "GetSocket", - Handler: _Channelz_GetSocket_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "grpc/channelz/v1/channelz.proto", -} diff --git a/cmd/protoc-gen-go-grpc/README.md b/cmd/protoc-gen-go-grpc/README.md index f76e419a..6d047f1e 100644 --- a/cmd/protoc-gen-go-grpc/README.md +++ b/cmd/protoc-gen-go-grpc/README.md @@ -4,18 +4,140 @@ This tool generates Go language bindings of `service`s in protobuf definition files for gRPC. For usage information, please see our [quick start guide](https://grpc.io/docs/languages/go/quickstart/). -## Future-proofing services +## Service implementation and registration -By default, to register services using the methods generated by this tool, the -service implementations must embed the corresponding -`UnimplementedServer` for future compatibility. This is a behavior -change from the grpc code generator previously included with `protoc-gen-go`. -To restore this behavior, set the option `requireUnimplementedServers=false`. -E.g.: +**NOTE:** service registration has changed from the previous version of the +code generator. Please read this section carefully if you are migrating. -``` - protoc --go-grpc_out=requireUnimplementedServers=false[,other options...]:. \ +To register your service handlers with a gRPC server, first implement the +methods as either functions or methods on a struct. Examples: + +```go +// As a function: + +func unaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { + // Echo.UnaryEcho implementation +} + +// As a struct + method: + +type myEchoService struct { + // ...fields used by this service... +} + +func (s *myEchoService) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { + // Echo.UnaryEcho implementation +} ``` -Note that this is not recommended, and the option is only provided to restore -backward compatibility with previously-generated code. +Then create an instance of the generated `Service` struct type and initialize +the handlers which have been implemented: + +```go +func main() { + // ... + + // As a function: + echoService := pb.EchoService{ + UnaryEcho: unaryEcho, + // etc + } + + // As a struct+method: + mes := &myEchoService{...} + echoService := pb.EchoService{ + UnaryEcho: mes.UnaryEcho, + // etc + } + + // ... + } +``` + +Finally, pass this `Service` instance to the generated `Register` function: + +```go + pb.RegisterEchoService(grpcServer, echoService) +``` + +### Migration from legacy version + +#### Updating existing code + +The previous version of protoc-gen-go-grpc used a different method to register +services. In that version, it was only possible to register a service +implementation that was a complete implementation of the service. It was also +possible to embed an `Unimplemented` implementation of the service, which was +also generated and returned an UNIMPLEMENTED status for all methods. To make +it easier to migrate from the previous version, two new symbols are generated: +`NewService` and `UnstableService`. + +`NewService` allows for easy wrapping of a service implementation into +an instance of the new generated `Service` struct type. *This has drawbacks, +however: `NewService` accepts any parameter, and does not panic or +error if any methods are missing, are misspelled, or have the wrong signature.* +These methods will return an UNIMPLEMENTED status if called by a client. + +`UnstableService` allows for asserting that a type properly implements +all methods of a service. It is generated with the name `Unstable` to denote +that it will be extended whenever new methods are added to the service +definition. This kind of change to the service definition is considered +backward-compatible in protobuf, but is not backward-compatible in Go, because +adding methods to an interface invalidates any existing implementations. *Use +of this symbol could result in future compilation errors.* + +To convert your existing code using the previous code generator, please refer +to the following example: + +```go +type myEchoService{ + // ...fields used by this service... +} +// ... method handler implementation ... + + +// Optional; not recommended: to guarantee myEchoService fully implements +// EchoService: +var _ pb.UnstableEchoService = &myEchoService{} + +func main() { + // ... + + // OLD: + pb.RegisterEchoServer(grpcServer, &myEchoService{}) + + // NEW: + pb.RegisterEchoService(grpcServer, pb.NewEchoService(&myEchoService{})) + + + // Optional: to gracefully detect missing methods: + if _, ok := &myEchoService{}.(pb.UnstableEchoService); !ok { + fmt.Println("myEchoService does not implement all methods of EchoService.") + } + + + // ... +} +``` + +#### Updating generated code to support both legacy and new code + +`protoc-gen-go-grpc` supports a flag, `migration_mode`, which enables it to be +run in tandem with the previous tool (`protoc-gen-go` with the grpc plugin). +It can be used as follows: + +```sh +go install github.com/golang/protobuf/protoc-gen-go + +# Example 1: with OPTS set to common options for protoc-gen-go and +# protoc-gen-go-grpc +protoc --go_out=${OPTS},plugins=grpc:. --go-grpc_out=${OPTS},migration_mode=true:. *.proto + +# Example 2: if no special options are needed +protoc --go_out=plugins=grpc:. --go-grpc_out=migration_mode=true:. *.proto +``` + +This is recommended for temporary use only to ease migration from the legacy +version. The `RegisterServer` and `Server` symbols it +produced are not backward compatible in the presence of newly added methods to +a service. \ No newline at end of file diff --git a/cmd/protoc-gen-go-grpc/grpc.go b/cmd/protoc-gen-go-grpc/grpc.go index 4f78bdd4..47503bdc 100644 --- a/cmd/protoc-gen-go-grpc/grpc.go +++ b/cmd/protoc-gen-go-grpc/grpc.go @@ -58,14 +58,19 @@ func generateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen. g.P("// This is a compile-time assertion to ensure that this generated file") g.P("// is compatible with the grpc package it is being compiled against.") - g.P("const _ = ", grpcPackage.Ident("SupportPackageIsVersion6")) + g.P("const _ = ", grpcPackage.Ident("SupportPackageIsVersion7")) g.P() for _, service := range file.Services { + genClient(gen, file, g, service) genService(gen, file, g, service) + genUnstableServiceInterface(gen, file, g, service) } } -func genService(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, service *protogen.Service) { +func genClient(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, service *protogen.Service) { + if *migrationMode { + return + } clientName := service.GoName + "Client" g.P("// ", clientName, " is the client API for ", service.GoName, " service.") @@ -105,121 +110,10 @@ func genService(gen *protogen.Plugin, file *protogen.File, g *protogen.Generated g.P("}") g.P() - var methodIndex, streamIndex int // Client method implementations. for _, method := range service.Methods { - if !method.Desc.IsStreamingServer() && !method.Desc.IsStreamingClient() { - // Unary RPC method - genClientMethod(gen, file, g, method, methodIndex) - methodIndex++ - } else { - // Streaming RPC method - genClientMethod(gen, file, g, method, streamIndex) - streamIndex++ - } + genClientMethod(gen, g, method) } - - mustOrShould := "must" - if !*requireUnimplemented { - mustOrShould = "should" - } - - // Server interface. - serverType := service.GoName + "Server" - g.P("// ", serverType, " is the server API for ", service.GoName, " service.") - g.P("// All implementations ", mustOrShould, " embed Unimplemented", serverType) - g.P("// for forward compatibility") - if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() { - g.P("//") - g.P(deprecationComment) - } - g.Annotate(serverType, service.Location) - g.P("type ", serverType, " interface {") - for _, method := range service.Methods { - g.Annotate(serverType+"."+method.GoName, method.Location) - if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() { - g.P(deprecationComment) - } - g.P(method.Comments.Leading, - serverSignature(g, method)) - } - if *requireUnimplemented { - g.P("mustEmbedUnimplemented", serverType, "()") - } - g.P("}") - g.P() - - // Server Unimplemented struct for forward compatibility. - g.P("// Unimplemented", serverType, " ", mustOrShould, " be embedded to have forward compatible implementations.") - g.P("type Unimplemented", serverType, " struct {") - g.P("}") - g.P() - for _, method := range service.Methods { - nilArg := "" - if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { - nilArg = "nil," - } - g.P("func (*Unimplemented", serverType, ") ", serverSignature(g, method), "{") - g.P("return ", nilArg, statusPackage.Ident("Errorf"), "(", codesPackage.Ident("Unimplemented"), `, "method `, method.GoName, ` not implemented")`) - g.P("}") - } - if *requireUnimplemented { - g.P("func (*Unimplemented", serverType, ") mustEmbedUnimplemented", serverType, "() {}") - } - g.P() - - // Server registration. - if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() { - g.P(deprecationComment) - } - serviceDescVar := "_" + service.GoName + "_serviceDesc" - g.P("func Register", service.GoName, "Server(s *", grpcPackage.Ident("Server"), ", srv ", serverType, ") {") - g.P("s.RegisterService(&", serviceDescVar, `, srv)`) - g.P("}") - g.P() - - // Server handler implementations. - var handlerNames []string - for _, method := range service.Methods { - hname := genServerMethod(gen, file, g, method) - handlerNames = append(handlerNames, hname) - } - - // Service descriptor. - g.P("var ", serviceDescVar, " = ", grpcPackage.Ident("ServiceDesc"), " {") - g.P("ServiceName: ", strconv.Quote(string(service.Desc.FullName())), ",") - g.P("HandlerType: (*", serverType, ")(nil),") - g.P("Methods: []", grpcPackage.Ident("MethodDesc"), "{") - for i, method := range service.Methods { - if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() { - continue - } - g.P("{") - g.P("MethodName: ", strconv.Quote(string(method.Desc.Name())), ",") - g.P("Handler: ", handlerNames[i], ",") - g.P("},") - } - g.P("},") - g.P("Streams: []", grpcPackage.Ident("StreamDesc"), "{") - for i, method := range service.Methods { - if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { - continue - } - g.P("{") - g.P("StreamName: ", strconv.Quote(string(method.Desc.Name())), ",") - g.P("Handler: ", handlerNames[i], ",") - if method.Desc.IsStreamingServer() { - g.P("ServerStreams: true,") - } - if method.Desc.IsStreamingClient() { - g.P("ClientStreams: true,") - } - g.P("},") - } - g.P("},") - g.P("Metadata: \"", file.Desc.Path(), "\",") - g.P("}") - g.P() } func clientSignature(g *protogen.GeneratedFile, method *protogen.Method) string { @@ -237,13 +131,25 @@ func clientSignature(g *protogen.GeneratedFile, method *protogen.Method) string return s } -func genClientMethod(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, method *protogen.Method, index int) { +func genClientMethod(gen *protogen.Plugin, g *protogen.GeneratedFile, method *protogen.Method) { service := method.Parent sname := fmt.Sprintf("/%s/%s", service.Desc.FullName(), method.Desc.Name()) if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() { g.P(deprecationComment) } + + streamDescName := unexport(service.GoName) + method.GoName + "StreamDesc" + g.P("var ", streamDescName, " = &", grpcPackage.Ident("StreamDesc"), "{") + g.P("StreamName: ", strconv.Quote(string(method.Desc.Name())), ",") + if method.Desc.IsStreamingServer() { + g.P("ServerStreams: true,") + } + if method.Desc.IsStreamingClient() { + g.P("ClientStreams: true,") + } + g.P("}") + g.P("func (c *", unexport(service.GoName), "Client) ", clientSignature(g, method), "{") if !method.Desc.IsStreamingServer() && !method.Desc.IsStreamingClient() { g.P("out := new(", method.Output.GoIdent, ")") @@ -255,8 +161,8 @@ func genClientMethod(gen *protogen.Plugin, file *protogen.File, g *protogen.Gene return } streamType := unexport(service.GoName) + method.GoName + "Client" - serviceDescVar := "_" + service.GoName + "_serviceDesc" - g.P("stream, err := c.cc.NewStream(ctx, &", serviceDescVar, ".Streams[", index, `], "`, sname, `", opts...)`) + + g.P(`stream, err := c.cc.NewStream(ctx, `, streamDescName, `, "`, sname, `", opts...)`) g.P("if err != nil { return nil, err }") g.P("x := &", streamType, "{stream}") if !method.Desc.IsStreamingClient() { @@ -316,7 +222,140 @@ func genClientMethod(gen *protogen.Plugin, file *protogen.File, g *protogen.Gene } } -func serverSignature(g *protogen.GeneratedFile, method *protogen.Method) string { +func genService(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, service *protogen.Service) { + // Server struct. + serviceType := service.GoName + "Service" + g.P("// ", serviceType, " is the service API for ", service.GoName, " service.") + g.P("// Fields should be assigned to their respective handler implementations only before") + g.P("// Register", serviceType, " is called. Any unassigned fields will result in the") + g.P("// handler for that method returning an Unimplemented error.") + if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() { + g.P("//") + g.P(deprecationComment) + } + g.Annotate(serviceType, service.Location) + g.P("type ", serviceType, " struct {") + for _, method := range service.Methods { + if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() { + g.P(deprecationComment) + } + g.Annotate(serviceType+"."+method.GoName, method.Location) + g.P(method.Comments.Leading, + handlerSignature(g, method)) + } + g.P("}") + g.P() + + // Method handler implementations. + for _, method := range service.Methods { + genMethodHandler(gen, g, method) + } + + // Stream interfaces and implementations. + for _, method := range service.Methods { + genServerStreamTypes(gen, g, method) + } + + // Service registration. + genRegisterFunction(gen, file, g, service) + + // Short-cut service constructor. + genServiceConstructor(gen, g, service) +} + +func genRegisterFunction(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, service *protogen.Service) { + g.P("// Register", service.GoName, "Service registers a service implementation with a gRPC server.") + if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() { + g.P("//") + g.P(deprecationComment) + } + g.P("func Register", service.GoName, "Service(s ", grpcPackage.Ident("ServiceRegistrar"), ", srv *", service.GoName, "Service) {") + + // Service descriptor. + g.P("sd := ", grpcPackage.Ident("ServiceDesc"), " {") + g.P("ServiceName: ", strconv.Quote(string(service.Desc.FullName())), ",") + g.P("Methods: []", grpcPackage.Ident("MethodDesc"), "{") + for _, method := range service.Methods { + if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() { + continue + } + g.P("{") + g.P("MethodName: ", strconv.Quote(string(method.Desc.Name())), ",") + g.P("Handler: srv.", unexport(method.GoName), ",") + g.P("},") + } + g.P("},") + g.P("Streams: []", grpcPackage.Ident("StreamDesc"), "{") + for _, method := range service.Methods { + if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { + continue + } + g.P("{") + g.P("StreamName: ", strconv.Quote(string(method.Desc.Name())), ",") + g.P("Handler: srv.", unexport(method.GoName), ",") + if method.Desc.IsStreamingServer() { + g.P("ServerStreams: true,") + } + if method.Desc.IsStreamingClient() { + g.P("ClientStreams: true,") + } + g.P("},") + } + g.P("},") + g.P("Metadata: \"", file.Desc.Path(), "\",") + g.P("}") + g.P() + + g.P("s.RegisterService(&sd, nil)") + g.P("}") + g.P() +} + +func genServiceConstructor(gen *protogen.Plugin, g *protogen.GeneratedFile, service *protogen.Service) { + g.P("// New", service.GoName, "Service creates a new ", service.GoName, "Service containing the") + g.P("// implemented methods of the ", service.GoName, " service in s. Any unimplemented") + g.P("// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client.") + g.P("// This includes situations where the method handler is misspelled or has the wrong") + g.P("// signature. For this reason, this function should be used with great care and") + g.P("// is not recommended to be used by most users.") + g.P("func New", service.GoName, "Service(s interface{}) *", service.GoName, "Service {") + g.P("ns := &", service.GoName, "Service{}") + for _, method := range service.Methods { + g.P("if h, ok := s.(interface {", methodSignature(g, method), "}); ok {") + g.P("ns.", method.GoName, " = h.", method.GoName) + g.P("}") + } + g.P("return ns") + g.P("}") + g.P() +} + +func genUnstableServiceInterface(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, service *protogen.Service) { + // Service interface. + serviceType := service.GoName + "Service" + g.P("// Unstable", serviceType, " is the service API for ", service.GoName, " service.") + g.P("// New methods may be added to this interface if they are added to the service") + g.P("// definition, which is not a backward-compatible change. For this reason, ") + g.P("// use of this type is not recommended.") + if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() { + g.P("//") + g.P(deprecationComment) + } + g.Annotate("Unstable"+serviceType, service.Location) + g.P("type Unstable", serviceType, " interface {") + for _, method := range service.Methods { + g.Annotate("Unstable"+serviceType+"."+method.GoName, method.Location) + if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() { + g.P(deprecationComment) + } + g.P(method.Comments.Leading, + methodSignature(g, method)) + } + g.P("}") + g.P() +} + +func methodSignature(g *protogen.GeneratedFile, method *protogen.Method) string { var reqArgs []string ret := "error" if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { @@ -332,39 +371,88 @@ func serverSignature(g *protogen.GeneratedFile, method *protogen.Method) string return method.GoName + "(" + strings.Join(reqArgs, ", ") + ") " + ret } -func genServerMethod(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, method *protogen.Method) string { - service := method.Parent - hname := fmt.Sprintf("_%s_%s_Handler", service.GoName, method.GoName) - +func handlerSignature(g *protogen.GeneratedFile, method *protogen.Method) string { + var reqArgs []string + ret := "error" + if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { + reqArgs = append(reqArgs, g.QualifiedGoIdent(contextPackage.Ident("Context"))) + ret = "(*" + g.QualifiedGoIdent(method.Output.GoIdent) + ", error)" + } + if !method.Desc.IsStreamingClient() { + reqArgs = append(reqArgs, "*"+g.QualifiedGoIdent(method.Input.GoIdent)) + } + if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() { + reqArgs = append(reqArgs, method.Parent.GoName+"_"+method.GoName+"Server") + } + return method.GoName + " func(" + strings.Join(reqArgs, ", ") + ") " + ret +} + +func unaryHandlerSignature(g *protogen.GeneratedFile) string { + return "(_ interface{}, ctx " + g.QualifiedGoIdent(contextPackage.Ident("Context")) + + ", dec func(interface{}) error, interceptor " + g.QualifiedGoIdent(grpcPackage.Ident("UnaryServerInterceptor")) + ") (interface{}, error)" +} + +func streamHandlerSignature(g *protogen.GeneratedFile) string { + return "(_ interface{}, stream " + g.QualifiedGoIdent(grpcPackage.Ident("ServerStream")) + ") error" +} + +func genMethodHandler(gen *protogen.Plugin, g *protogen.GeneratedFile, method *protogen.Method) { + service := method.Parent + + nilArg := "" + signature := streamHandlerSignature(g) + if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { + nilArg = "nil," + signature = unaryHandlerSignature(g) + } + g.P("func (s *", service.GoName, "Service) ", unexport(method.GoName), signature, " {") + + g.P("if s.", method.GoName, " == nil {") + g.P("return ", nilArg, statusPackage.Ident("Errorf"), "(", codesPackage.Ident("Unimplemented"), `, "method `, method.GoName, ` not implemented")`) + g.P("}") + genHandlerBody(gen, g, method) + + g.P("}") +} + +func genHandlerBody(gen *protogen.Plugin, g *protogen.GeneratedFile, method *protogen.Method) { + service := method.Parent if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { - g.P("func ", hname, "(srv interface{}, ctx ", contextPackage.Ident("Context"), ", dec func(interface{}) error, interceptor ", grpcPackage.Ident("UnaryServerInterceptor"), ") (interface{}, error) {") g.P("in := new(", method.Input.GoIdent, ")") g.P("if err := dec(in); err != nil { return nil, err }") - g.P("if interceptor == nil { return srv.(", service.GoName, "Server).", method.GoName, "(ctx, in) }") + g.P("if interceptor == nil { return s.", method.GoName, "(ctx, in) }") g.P("info := &", grpcPackage.Ident("UnaryServerInfo"), "{") - g.P("Server: srv,") + g.P("Server: s,") g.P("FullMethod: ", strconv.Quote(fmt.Sprintf("/%s/%s", service.Desc.FullName(), method.GoName)), ",") g.P("}") g.P("handler := func(ctx ", contextPackage.Ident("Context"), ", req interface{}) (interface{}, error) {") - g.P("return srv.(", service.GoName, "Server).", method.GoName, "(ctx, req.(*", method.Input.GoIdent, "))") + g.P("return s.", method.GoName, "(ctx, req.(*", method.Input.GoIdent, "))") g.P("}") g.P("return interceptor(ctx, in, info, handler)") - g.P("}") - g.P() - return hname + return } streamType := unexport(service.GoName) + method.GoName + "Server" - g.P("func ", hname, "(srv interface{}, stream ", grpcPackage.Ident("ServerStream"), ") error {") if !method.Desc.IsStreamingClient() { + // Server-streaming g.P("m := new(", method.Input.GoIdent, ")") g.P("if err := stream.RecvMsg(m); err != nil { return err }") - g.P("return srv.(", service.GoName, "Server).", method.GoName, "(m, &", streamType, "{stream})") + g.P("return s.", method.GoName, "(m, &", streamType, "{stream})") } else { - g.P("return srv.(", service.GoName, "Server).", method.GoName, "(&", streamType, "{stream})") + // Bidi-streaming + g.P("return s.", method.GoName, "(&", streamType, "{stream})") } - g.P("}") - g.P() +} +func genServerStreamTypes(gen *protogen.Plugin, g *protogen.GeneratedFile, method *protogen.Method) { + if *migrationMode { + return + } + if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() { + // Unary method + return + } + service := method.Parent + streamType := unexport(service.GoName) + method.GoName + "Server" genSend := method.Desc.IsStreamingServer() genSendAndClose := !method.Desc.IsStreamingServer() genRecv := method.Desc.IsStreamingClient() @@ -410,7 +498,7 @@ func genServerMethod(gen *protogen.Plugin, file *protogen.File, g *protogen.Gene g.P() } - return hname + return } const deprecationComment = "// Deprecated: Do not use." diff --git a/cmd/protoc-gen-go-grpc/main.go b/cmd/protoc-gen-go-grpc/main.go index 9165761d..0d7e76c6 100644 --- a/cmd/protoc-gen-go-grpc/main.go +++ b/cmd/protoc-gen-go-grpc/main.go @@ -37,11 +37,11 @@ import ( "google.golang.org/protobuf/types/pluginpb" ) -var requireUnimplemented *bool +var migrationMode *bool func main() { var flags flag.FlagSet - requireUnimplemented = flags.Bool("requireUnimplementedServers", true, "unset to match legacy behavior") + migrationMode = flags.Bool("migration_mode", false, "set to generate new symbols only; requires symbols produced by legacy protoc-gen-go") protogen.Options{ ParamFunc: flags.Set, diff --git a/credentials/alts/internal/proto/grpc_gcp/handshaker.pb.go b/credentials/alts/internal/proto/grpc_gcp/handshaker.pb.go index 6d9c304e..a2060de4 100644 --- a/credentials/alts/internal/proto/grpc_gcp/handshaker.pb.go +++ b/credentials/alts/internal/proto/grpc_gcp/handshaker.pb.go @@ -4,8 +4,12 @@ package grpc_gcp import ( + context "context" fmt "fmt" proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" math "math" ) @@ -975,3 +979,127 @@ var fileDescriptor_54c074f40c7c7e99 = []byte{ 0x5f, 0xef, 0xa8, 0xf5, 0x83, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc1, 0xf9, 0x9d, 0xf2, 0xd9, 0x0b, 0x00, 0x00, } + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// 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.SupportPackageIsVersion6 + +// HandshakerServiceClient is the client API for HandshakerService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type HandshakerServiceClient interface { + // Handshaker service accepts a stream of handshaker request, returning a + // stream of handshaker response. Client is expected to send exactly one + // message with either client_start or server_start followed by one or more + // messages with next. Each time client sends a request, the handshaker + // service expects to respond. Client does not have to wait for service's + // response before sending next request. + DoHandshake(ctx context.Context, opts ...grpc.CallOption) (HandshakerService_DoHandshakeClient, error) +} + +type handshakerServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewHandshakerServiceClient(cc grpc.ClientConnInterface) HandshakerServiceClient { + return &handshakerServiceClient{cc} +} + +func (c *handshakerServiceClient) DoHandshake(ctx context.Context, opts ...grpc.CallOption) (HandshakerService_DoHandshakeClient, error) { + stream, err := c.cc.NewStream(ctx, &_HandshakerService_serviceDesc.Streams[0], "/grpc.gcp.HandshakerService/DoHandshake", opts...) + if err != nil { + return nil, err + } + x := &handshakerServiceDoHandshakeClient{stream} + return x, nil +} + +type HandshakerService_DoHandshakeClient interface { + Send(*HandshakerReq) error + Recv() (*HandshakerResp, error) + grpc.ClientStream +} + +type handshakerServiceDoHandshakeClient struct { + grpc.ClientStream +} + +func (x *handshakerServiceDoHandshakeClient) Send(m *HandshakerReq) error { + return x.ClientStream.SendMsg(m) +} + +func (x *handshakerServiceDoHandshakeClient) Recv() (*HandshakerResp, error) { + m := new(HandshakerResp) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// HandshakerServiceServer is the server API for HandshakerService service. +type HandshakerServiceServer interface { + // Handshaker service accepts a stream of handshaker request, returning a + // stream of handshaker response. Client is expected to send exactly one + // message with either client_start or server_start followed by one or more + // messages with next. Each time client sends a request, the handshaker + // service expects to respond. Client does not have to wait for service's + // response before sending next request. + DoHandshake(HandshakerService_DoHandshakeServer) error +} + +// UnimplementedHandshakerServiceServer can be embedded to have forward compatible implementations. +type UnimplementedHandshakerServiceServer struct { +} + +func (*UnimplementedHandshakerServiceServer) DoHandshake(srv HandshakerService_DoHandshakeServer) error { + return status.Errorf(codes.Unimplemented, "method DoHandshake not implemented") +} + +func RegisterHandshakerServiceServer(s *grpc.Server, srv HandshakerServiceServer) { + s.RegisterService(&_HandshakerService_serviceDesc, srv) +} + +func _HandshakerService_DoHandshake_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(HandshakerServiceServer).DoHandshake(&handshakerServiceDoHandshakeServer{stream}) +} + +type HandshakerService_DoHandshakeServer interface { + Send(*HandshakerResp) error + Recv() (*HandshakerReq, error) + grpc.ServerStream +} + +type handshakerServiceDoHandshakeServer struct { + grpc.ServerStream +} + +func (x *handshakerServiceDoHandshakeServer) Send(m *HandshakerResp) error { + return x.ServerStream.SendMsg(m) +} + +func (x *handshakerServiceDoHandshakeServer) Recv() (*HandshakerReq, error) { + m := new(HandshakerReq) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +var _HandshakerService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "grpc.gcp.HandshakerService", + HandlerType: (*HandshakerServiceServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "DoHandshake", + Handler: _HandshakerService_DoHandshake_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "grpc/gcp/handshaker.proto", +} diff --git a/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go b/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go index 0e973b82..bf7ff0a7 100644 --- a/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go +++ b/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go @@ -3,7 +3,6 @@ package grpc_gcp import ( - context "context" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -11,64 +10,69 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 -// HandshakerServiceClient is the client API for HandshakerService 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 HandshakerServiceClient interface { +// HandshakerServiceService is the service API for HandshakerService service. +// Fields should be assigned to their respective handler implementations only before +// RegisterHandshakerServiceService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type HandshakerServiceService struct { // Handshaker service accepts a stream of handshaker request, returning a // stream of handshaker response. Client is expected to send exactly one // message with either client_start or server_start followed by one or more // messages with next. Each time client sends a request, the handshaker // service expects to respond. Client does not have to wait for service's // response before sending next request. - DoHandshake(ctx context.Context, opts ...grpc.CallOption) (HandshakerService_DoHandshakeClient, error) + DoHandshake func(HandshakerService_DoHandshakeServer) error } -type handshakerServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewHandshakerServiceClient(cc grpc.ClientConnInterface) HandshakerServiceClient { - return &handshakerServiceClient{cc} -} - -func (c *handshakerServiceClient) DoHandshake(ctx context.Context, opts ...grpc.CallOption) (HandshakerService_DoHandshakeClient, error) { - stream, err := c.cc.NewStream(ctx, &_HandshakerService_serviceDesc.Streams[0], "/grpc.gcp.HandshakerService/DoHandshake", opts...) - if err != nil { - return nil, err +func (s *HandshakerServiceService) doHandshake(_ interface{}, stream grpc.ServerStream) error { + if s.DoHandshake == nil { + return status.Errorf(codes.Unimplemented, "method DoHandshake not implemented") } - x := &handshakerServiceDoHandshakeClient{stream} - return x, nil + return s.DoHandshake(&handshakerServiceDoHandshakeServer{stream}) } -type HandshakerService_DoHandshakeClient interface { - Send(*HandshakerReq) error - Recv() (*HandshakerResp, error) - grpc.ClientStream -} - -type handshakerServiceDoHandshakeClient struct { - grpc.ClientStream -} - -func (x *handshakerServiceDoHandshakeClient) Send(m *HandshakerReq) error { - return x.ClientStream.SendMsg(m) -} - -func (x *handshakerServiceDoHandshakeClient) Recv() (*HandshakerResp, error) { - m := new(HandshakerResp) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err +// RegisterHandshakerServiceService registers a service implementation with a gRPC server. +func RegisterHandshakerServiceService(s grpc.ServiceRegistrar, srv *HandshakerServiceService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.gcp.HandshakerService", + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "DoHandshake", + Handler: srv.doHandshake, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "grpc/gcp/handshaker.proto", } - return m, nil + + s.RegisterService(&sd, nil) } -// HandshakerServiceServer is the server API for HandshakerService service. -// All implementations should embed UnimplementedHandshakerServiceServer -// for forward compatibility -type HandshakerServiceServer interface { +// NewHandshakerServiceService creates a new HandshakerServiceService containing the +// implemented methods of the HandshakerService service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewHandshakerServiceService(s interface{}) *HandshakerServiceService { + ns := &HandshakerServiceService{} + if h, ok := s.(interface { + DoHandshake(HandshakerService_DoHandshakeServer) error + }); ok { + ns.DoHandshake = h.DoHandshake + } + return ns +} + +// UnstableHandshakerServiceService is the service API for HandshakerService service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableHandshakerServiceService interface { // Handshaker service accepts a stream of handshaker request, returning a // stream of handshaker response. Client is expected to send exactly one // message with either client_start or server_start followed by one or more @@ -77,56 +81,3 @@ type HandshakerServiceServer interface { // response before sending next request. DoHandshake(HandshakerService_DoHandshakeServer) error } - -// UnimplementedHandshakerServiceServer should be embedded to have forward compatible implementations. -type UnimplementedHandshakerServiceServer struct { -} - -func (*UnimplementedHandshakerServiceServer) DoHandshake(HandshakerService_DoHandshakeServer) error { - return status.Errorf(codes.Unimplemented, "method DoHandshake not implemented") -} - -func RegisterHandshakerServiceServer(s *grpc.Server, srv HandshakerServiceServer) { - s.RegisterService(&_HandshakerService_serviceDesc, srv) -} - -func _HandshakerService_DoHandshake_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(HandshakerServiceServer).DoHandshake(&handshakerServiceDoHandshakeServer{stream}) -} - -type HandshakerService_DoHandshakeServer interface { - Send(*HandshakerResp) error - Recv() (*HandshakerReq, error) - grpc.ServerStream -} - -type handshakerServiceDoHandshakeServer struct { - grpc.ServerStream -} - -func (x *handshakerServiceDoHandshakeServer) Send(m *HandshakerResp) error { - return x.ServerStream.SendMsg(m) -} - -func (x *handshakerServiceDoHandshakeServer) Recv() (*HandshakerReq, error) { - m := new(HandshakerReq) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -var _HandshakerService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.gcp.HandshakerService", - HandlerType: (*HandshakerServiceServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ - { - StreamName: "DoHandshake", - Handler: _HandshakerService_DoHandshake_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "grpc/gcp/handshaker.proto", -} diff --git a/credentials/tls/certprovider/meshca/internal/v1/meshca.pb.go b/credentials/tls/certprovider/meshca/internal/v1/meshca.pb.go index 16122f76..b09de93b 100644 --- a/credentials/tls/certprovider/meshca/internal/v1/meshca.pb.go +++ b/credentials/tls/certprovider/meshca/internal/v1/meshca.pb.go @@ -4,9 +4,13 @@ package google_security_meshca_v1 import ( + context "context" fmt "fmt" proto "github.com/golang/protobuf/proto" duration "github.com/golang/protobuf/ptypes/duration" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" math "math" ) @@ -153,3 +157,87 @@ var fileDescriptor_f72841047b94fe5e = []byte{ 0x75, 0x36, 0xec, 0xba, 0x62, 0xee, 0x66, 0x99, 0x93, 0xe5, 0x45, 0xb7, 0xcf, 0xc3, 0x77, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb7, 0x0d, 0xfd, 0xff, 0xf7, 0x01, 0x00, 0x00, } + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// 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.SupportPackageIsVersion6 + +// MeshCertificateServiceClient is the client API for MeshCertificateService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type MeshCertificateServiceClient interface { + // Using provided CSR, returns a signed certificate that represents a GCP + // service account identity. + CreateCertificate(ctx context.Context, in *MeshCertificateRequest, opts ...grpc.CallOption) (*MeshCertificateResponse, error) +} + +type meshCertificateServiceClient struct { + cc grpc.ClientConnInterface +} + +func NewMeshCertificateServiceClient(cc grpc.ClientConnInterface) MeshCertificateServiceClient { + return &meshCertificateServiceClient{cc} +} + +func (c *meshCertificateServiceClient) CreateCertificate(ctx context.Context, in *MeshCertificateRequest, opts ...grpc.CallOption) (*MeshCertificateResponse, error) { + out := new(MeshCertificateResponse) + err := c.cc.Invoke(ctx, "/google.security.meshca.v1.MeshCertificateService/CreateCertificate", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// MeshCertificateServiceServer is the server API for MeshCertificateService service. +type MeshCertificateServiceServer interface { + // Using provided CSR, returns a signed certificate that represents a GCP + // service account identity. + CreateCertificate(context.Context, *MeshCertificateRequest) (*MeshCertificateResponse, error) +} + +// UnimplementedMeshCertificateServiceServer can be embedded to have forward compatible implementations. +type UnimplementedMeshCertificateServiceServer struct { +} + +func (*UnimplementedMeshCertificateServiceServer) CreateCertificate(ctx context.Context, req *MeshCertificateRequest) (*MeshCertificateResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateCertificate not implemented") +} + +func RegisterMeshCertificateServiceServer(s *grpc.Server, srv MeshCertificateServiceServer) { + s.RegisterService(&_MeshCertificateService_serviceDesc, srv) +} + +func _MeshCertificateService_CreateCertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(MeshCertificateRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(MeshCertificateServiceServer).CreateCertificate(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/google.security.meshca.v1.MeshCertificateService/CreateCertificate", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(MeshCertificateServiceServer).CreateCertificate(ctx, req.(*MeshCertificateRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _MeshCertificateService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "google.security.meshca.v1.MeshCertificateService", + HandlerType: (*MeshCertificateServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateCertificate", + Handler: _MeshCertificateService_CreateCertificate_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "istio/google/security/meshca/v1/meshca.proto", +} diff --git a/credentials/tls/certprovider/meshca/internal/v1/meshca_grpc.pb.go b/credentials/tls/certprovider/meshca/internal/v1/meshca_grpc.pb.go index 2361ac63..a063519d 100644 --- a/credentials/tls/certprovider/meshca/internal/v1/meshca_grpc.pb.go +++ b/credentials/tls/certprovider/meshca/internal/v1/meshca_grpc.pb.go @@ -11,82 +11,78 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 -// MeshCertificateServiceClient is the client API for MeshCertificateService 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 MeshCertificateServiceClient interface { +// MeshCertificateServiceService is the service API for MeshCertificateService service. +// Fields should be assigned to their respective handler implementations only before +// RegisterMeshCertificateServiceService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type MeshCertificateServiceService struct { // Using provided CSR, returns a signed certificate that represents a GCP // service account identity. - CreateCertificate(ctx context.Context, in *MeshCertificateRequest, opts ...grpc.CallOption) (*MeshCertificateResponse, error) + CreateCertificate func(context.Context, *MeshCertificateRequest) (*MeshCertificateResponse, error) } -type meshCertificateServiceClient struct { - cc grpc.ClientConnInterface -} - -func NewMeshCertificateServiceClient(cc grpc.ClientConnInterface) MeshCertificateServiceClient { - return &meshCertificateServiceClient{cc} -} - -func (c *meshCertificateServiceClient) CreateCertificate(ctx context.Context, in *MeshCertificateRequest, opts ...grpc.CallOption) (*MeshCertificateResponse, error) { - out := new(MeshCertificateResponse) - err := c.cc.Invoke(ctx, "/google.security.meshca.v1.MeshCertificateService/CreateCertificate", in, out, opts...) - if err != nil { - return nil, err +func (s *MeshCertificateServiceService) createCertificate(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.CreateCertificate == nil { + return nil, status.Errorf(codes.Unimplemented, "method CreateCertificate not implemented") } - return out, nil -} - -// MeshCertificateServiceServer is the server API for MeshCertificateService service. -// All implementations should embed UnimplementedMeshCertificateServiceServer -// for forward compatibility -type MeshCertificateServiceServer interface { - // Using provided CSR, returns a signed certificate that represents a GCP - // service account identity. - CreateCertificate(context.Context, *MeshCertificateRequest) (*MeshCertificateResponse, error) -} - -// UnimplementedMeshCertificateServiceServer should be embedded to have forward compatible implementations. -type UnimplementedMeshCertificateServiceServer struct { -} - -func (*UnimplementedMeshCertificateServiceServer) CreateCertificate(context.Context, *MeshCertificateRequest) (*MeshCertificateResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method CreateCertificate not implemented") -} - -func RegisterMeshCertificateServiceServer(s *grpc.Server, srv MeshCertificateServiceServer) { - s.RegisterService(&_MeshCertificateService_serviceDesc, srv) -} - -func _MeshCertificateService_CreateCertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(MeshCertificateRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(MeshCertificateServiceServer).CreateCertificate(ctx, in) + return s.CreateCertificate(ctx, in) } info := &grpc.UnaryServerInfo{ - Server: srv, + Server: s, FullMethod: "/google.security.meshca.v1.MeshCertificateService/CreateCertificate", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MeshCertificateServiceServer).CreateCertificate(ctx, req.(*MeshCertificateRequest)) + return s.CreateCertificate(ctx, req.(*MeshCertificateRequest)) } return interceptor(ctx, in, info, handler) } -var _MeshCertificateService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "google.security.meshca.v1.MeshCertificateService", - HandlerType: (*MeshCertificateServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "CreateCertificate", - Handler: _MeshCertificateService_CreateCertificate_Handler, +// RegisterMeshCertificateServiceService registers a service implementation with a gRPC server. +func RegisterMeshCertificateServiceService(s grpc.ServiceRegistrar, srv *MeshCertificateServiceService) { + sd := grpc.ServiceDesc{ + ServiceName: "google.security.meshca.v1.MeshCertificateService", + Methods: []grpc.MethodDesc{ + { + MethodName: "CreateCertificate", + Handler: srv.createCertificate, + }, }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "istio/google/security/meshca/v1/meshca.proto", + Streams: []grpc.StreamDesc{}, + Metadata: "istio/google/security/meshca/v1/meshca.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewMeshCertificateServiceService creates a new MeshCertificateServiceService containing the +// implemented methods of the MeshCertificateService service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewMeshCertificateServiceService(s interface{}) *MeshCertificateServiceService { + ns := &MeshCertificateServiceService{} + if h, ok := s.(interface { + CreateCertificate(context.Context, *MeshCertificateRequest) (*MeshCertificateResponse, error) + }); ok { + ns.CreateCertificate = h.CreateCertificate + } + return ns +} + +// UnstableMeshCertificateServiceService is the service API for MeshCertificateService service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableMeshCertificateServiceService interface { + // Using provided CSR, returns a signed certificate that represents a GCP + // service account identity. + CreateCertificate(context.Context, *MeshCertificateRequest) (*MeshCertificateResponse, error) } diff --git a/examples/features/authentication/server/main.go b/examples/features/authentication/server/main.go index 5163fc31..505e8cb0 100644 --- a/examples/features/authentication/server/main.go +++ b/examples/features/authentication/server/main.go @@ -63,7 +63,7 @@ func main() { grpc.Creds(credentials.NewServerTLSFromCert(&cert)), } s := grpc.NewServer(opts...) - pb.RegisterEchoServer(s, &ecServer{}) + pb.RegisterEchoService(s, &pb.EchoService{UnaryEcho: unaryEcho}) lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port)) if err != nil { log.Fatalf("failed to listen: %v", err) @@ -73,11 +73,7 @@ func main() { } } -type ecServer struct { - pb.UnimplementedEchoServer -} - -func (s *ecServer) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { +func unaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { return &pb.EchoResponse{Message: req.Message}, nil } diff --git a/examples/features/cancellation/server/main.go b/examples/features/cancellation/server/main.go index 520286bf..1896828f 100644 --- a/examples/features/cancellation/server/main.go +++ b/examples/features/cancellation/server/main.go @@ -33,11 +33,7 @@ import ( var port = flag.Int("port", 50051, "the port to serve on") -type server struct { - pb.UnimplementedEchoServer -} - -func (s *server) BidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamingEchoServer) error { +func bidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamingEchoServer) error { for { in, err := stream.Recv() if err != nil { @@ -61,6 +57,6 @@ func main() { } fmt.Printf("server listening at port %v\n", lis.Addr()) s := grpc.NewServer() - pb.RegisterEchoServer(s, &server{}) + pb.RegisterEchoService(s, &pb.EchoService{BidirectionalStreamingEcho: bidirectionalStreamingEcho}) s.Serve(lis) } diff --git a/examples/features/compression/server/main.go b/examples/features/compression/server/main.go index e495cc89..442d1960 100644 --- a/examples/features/compression/server/main.go +++ b/examples/features/compression/server/main.go @@ -34,11 +34,7 @@ import ( var port = flag.Int("port", 50051, "the port to serve on") -type server struct { - pb.UnimplementedEchoServer -} - -func (s *server) UnaryEcho(ctx context.Context, in *pb.EchoRequest) (*pb.EchoResponse, error) { +func unaryEcho(ctx context.Context, in *pb.EchoRequest) (*pb.EchoResponse, error) { fmt.Printf("UnaryEcho called with message %q\n", in.GetMessage()) return &pb.EchoResponse{Message: in.Message}, nil } @@ -53,6 +49,6 @@ func main() { fmt.Printf("server listening at %v\n", lis.Addr()) s := grpc.NewServer() - pb.RegisterEchoServer(s, &server{}) + pb.RegisterEchoService(s, &pb.EchoService{UnaryEcho: unaryEcho}) s.Serve(lis) } diff --git a/examples/features/deadline/server/main.go b/examples/features/deadline/server/main.go index 11cd47a6..f5a033db 100644 --- a/examples/features/deadline/server/main.go +++ b/examples/features/deadline/server/main.go @@ -40,7 +40,6 @@ var port = flag.Int("port", 50052, "port number") // server is used to implement EchoServer. type server struct { - pb.UnimplementedEchoServer client pb.EchoClient cc *grpc.ClientConn } @@ -112,9 +111,12 @@ func main() { echoServer := newEchoServer() defer echoServer.Close() - grpcServer := grpc.NewServer() - pb.RegisterEchoServer(grpcServer, echoServer) + + pb.RegisterEchoService(grpcServer, &pb.EchoService{ + UnaryEcho: echoServer.UnaryEcho, + BidirectionalStreamingEcho: echoServer.BidirectionalStreamingEcho, + }) if err := grpcServer.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) diff --git a/examples/features/debugging/server/main.go b/examples/features/debugging/server/main.go index 397cb0c7..839212c9 100644 --- a/examples/features/debugging/server/main.go +++ b/examples/features/debugging/server/main.go @@ -36,23 +36,13 @@ var ( ports = []string{":10001", ":10002", ":10003"} ) -// server is used to implement helloworld.GreeterServer. -type server struct { - pb.UnimplementedGreeterServer -} - -// SayHello implements helloworld.GreeterServer -func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { +// sayHello implements helloworld.GreeterServer.SayHello +func sayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { return &pb.HelloReply{Message: "Hello " + in.Name}, nil } -// slow server is used to simulate a server that has a variable delay in its response. -type slowServer struct { - pb.UnimplementedGreeterServer -} - -// SayHello implements helloworld.GreeterServer -func (s *slowServer) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { +// sayHelloSlow implements helloworld.GreeterServer.SayHello +func sayHelloSlow(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { // Delay 100ms ~ 200ms before replying time.Sleep(time.Duration(100+grpcrand.Intn(100)) * time.Millisecond) return &pb.HelloReply{Message: "Hello " + in.Name}, nil @@ -70,7 +60,7 @@ func main() { go s.Serve(lis) defer s.Stop() - /***** Start three GreeterServers(with one of them to be the slowServer). *****/ + /***** Start three GreeterServers(with one of them to be the slow server). *****/ for i := 0; i < 3; i++ { lis, err := net.Listen("tcp", ports[i]) if err != nil { @@ -79,9 +69,9 @@ func main() { defer lis.Close() s := grpc.NewServer() if i == 2 { - pb.RegisterGreeterServer(s, &slowServer{}) + pb.RegisterGreeterService(s, &pb.GreeterService{SayHello: sayHelloSlow}) } else { - pb.RegisterGreeterServer(s, &server{}) + pb.RegisterGreeterService(s, &pb.GreeterService{SayHello: sayHello}) } go s.Serve(lis) } diff --git a/examples/features/encryption/ALTS/server/main.go b/examples/features/encryption/ALTS/server/main.go index 87bedd81..a72ccd11 100644 --- a/examples/features/encryption/ALTS/server/main.go +++ b/examples/features/encryption/ALTS/server/main.go @@ -34,11 +34,7 @@ import ( var port = flag.Int("port", 50051, "the port to serve on") -type ecServer struct { - pb.UnimplementedEchoServer -} - -func (s *ecServer) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { +func unaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { return &pb.EchoResponse{Message: req.Message}, nil } @@ -54,8 +50,8 @@ func main() { s := grpc.NewServer(grpc.Creds(altsTC)) - // Register EchoServer on the server. - pb.RegisterEchoServer(s, &ecServer{}) + // Register EchoService on the server. + pb.RegisterEchoService(s, &pb.EchoService{UnaryEcho: unaryEcho}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) diff --git a/examples/features/encryption/TLS/server/main.go b/examples/features/encryption/TLS/server/main.go index 81bf1f3a..d5ea6ccf 100644 --- a/examples/features/encryption/TLS/server/main.go +++ b/examples/features/encryption/TLS/server/main.go @@ -35,11 +35,7 @@ import ( var port = flag.Int("port", 50051, "the port to serve on") -type ecServer struct { - pb.UnimplementedEchoServer -} - -func (s *ecServer) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { +func unaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { return &pb.EchoResponse{Message: req.Message}, nil } @@ -60,7 +56,7 @@ func main() { s := grpc.NewServer(grpc.Creds(creds)) // Register EchoServer on the server. - pb.RegisterEchoServer(s, &ecServer{}) + pb.RegisterEchoService(s, &pb.EchoService{UnaryEcho: unaryEcho}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) diff --git a/examples/features/errors/server/main.go b/examples/features/errors/server/main.go index dc337741..c6c06a2b 100644 --- a/examples/features/errors/server/main.go +++ b/examples/features/errors/server/main.go @@ -39,7 +39,6 @@ var port = flag.Int("port", 50052, "port number") // server is used to implement helloworld.GreeterServer. type server struct { - pb.UnimplementedGreeterServer mu sync.Mutex count map[string]int } @@ -78,7 +77,8 @@ func main() { } s := grpc.NewServer() - pb.RegisterGreeterServer(s, &server{count: make(map[string]int)}) + hw := &server{count: make(map[string]int)} + pb.RegisterGreeterService(s, &pb.GreeterService{SayHello: hw.SayHello}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } diff --git a/examples/features/health/server/main.go b/examples/features/health/server/main.go index 3f79c8ba..670518da 100644 --- a/examples/features/health/server/main.go +++ b/examples/features/health/server/main.go @@ -40,18 +40,12 @@ var ( system = "" // empty string represents the health of the system ) -type echoServer struct { - pb.UnimplementedEchoServer -} - -func (e *echoServer) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { +func unaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { return &pb.EchoResponse{ Message: fmt.Sprintf("hello from localhost:%d", *port), }, nil } -var _ pb.EchoServer = &echoServer{} - func main() { flag.Parse() @@ -63,7 +57,7 @@ func main() { s := grpc.NewServer() healthcheck := health.NewServer() healthpb.RegisterHealthServer(s, healthcheck) - pb.RegisterEchoServer(s, &echoServer{}) + pb.RegisterEchoService(s, &pb.EchoService{UnaryEcho: unaryEcho}) go func() { // asynchronously inspect dependencies and toggle serving status as needed diff --git a/examples/features/interceptor/server/main.go b/examples/features/interceptor/server/main.go index 1b07cdec..5ca5a843 100644 --- a/examples/features/interceptor/server/main.go +++ b/examples/features/interceptor/server/main.go @@ -51,16 +51,12 @@ func logger(format string, a ...interface{}) { fmt.Printf("LOG:\t"+format+"\n", a...) } -type server struct { - pb.UnimplementedEchoServer -} - -func (s *server) UnaryEcho(ctx context.Context, in *pb.EchoRequest) (*pb.EchoResponse, error) { +func unaryEcho(ctx context.Context, in *pb.EchoRequest) (*pb.EchoResponse, error) { fmt.Printf("unary echoing message %q\n", in.Message) return &pb.EchoResponse{Message: in.Message}, nil } -func (s *server) BidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamingEchoServer) error { +func bidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamingEchoServer) error { for { in, err := stream.Recv() if err != nil { @@ -156,8 +152,11 @@ func main() { s := grpc.NewServer(grpc.Creds(creds), grpc.UnaryInterceptor(unaryInterceptor), grpc.StreamInterceptor(streamInterceptor)) - // Register EchoServer on the server. - pb.RegisterEchoServer(s, &server{}) + // Register EchoService on the server. + pb.RegisterEchoService(s, &pb.EchoService{ + UnaryEcho: unaryEcho, + BidirectionalStreamingEcho: bidirectionalStreamingEcho, + }) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) diff --git a/examples/features/keepalive/server/main.go b/examples/features/keepalive/server/main.go index beaa8f71..e3ec8ae0 100644 --- a/examples/features/keepalive/server/main.go +++ b/examples/features/keepalive/server/main.go @@ -48,12 +48,7 @@ var kasp = keepalive.ServerParameters{ Timeout: 1 * time.Second, // Wait 1 second for the ping ack before assuming the connection is dead } -// server implements EchoServer. -type server struct { - pb.UnimplementedEchoServer -} - -func (s *server) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { +func unaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { return &pb.EchoResponse{Message: req.Message}, nil } @@ -67,7 +62,7 @@ func main() { } s := grpc.NewServer(grpc.KeepaliveEnforcementPolicy(kaep), grpc.KeepaliveParams(kasp)) - pb.RegisterEchoServer(s, &server{}) + pb.RegisterEchoService(s, &pb.EchoService{UnaryEcho: unaryEcho}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) diff --git a/examples/features/load_balancing/server/main.go b/examples/features/load_balancing/server/main.go index 9d179579..680895fe 100644 --- a/examples/features/load_balancing/server/main.go +++ b/examples/features/load_balancing/server/main.go @@ -36,7 +36,6 @@ var ( ) type ecServer struct { - pb.UnimplementedEchoServer addr string } @@ -50,7 +49,8 @@ func startServer(addr string) { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() - pb.RegisterEchoServer(s, &ecServer{addr: addr}) + e := &ecServer{addr: addr} + pb.RegisterEchoService(s, &pb.EchoService{UnaryEcho: e.UnaryEcho}) log.Printf("serving on %s\n", addr) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) diff --git a/examples/features/metadata/server/main.go b/examples/features/metadata/server/main.go index cda3b497..af12a3a6 100644 --- a/examples/features/metadata/server/main.go +++ b/examples/features/metadata/server/main.go @@ -44,11 +44,7 @@ const ( streamingCount = 10 ) -type server struct { - pb.UnimplementedEchoServer -} - -func (s *server) UnaryEcho(ctx context.Context, in *pb.EchoRequest) (*pb.EchoResponse, error) { +func unaryEcho(ctx context.Context, in *pb.EchoRequest) (*pb.EchoResponse, error) { fmt.Printf("--- UnaryEcho ---\n") // Create trailer in defer to record function return time. defer func() { @@ -77,7 +73,7 @@ func (s *server) UnaryEcho(ctx context.Context, in *pb.EchoRequest) (*pb.EchoRes return &pb.EchoResponse{Message: in.Message}, nil } -func (s *server) ServerStreamingEcho(in *pb.EchoRequest, stream pb.Echo_ServerStreamingEchoServer) error { +func serverStreamingEcho(in *pb.EchoRequest, stream pb.Echo_ServerStreamingEchoServer) error { fmt.Printf("--- ServerStreamingEcho ---\n") // Create trailer in defer to record function return time. defer func() { @@ -114,7 +110,7 @@ func (s *server) ServerStreamingEcho(in *pb.EchoRequest, stream pb.Echo_ServerSt return nil } -func (s *server) ClientStreamingEcho(stream pb.Echo_ClientStreamingEchoServer) error { +func clientStreamingEcho(stream pb.Echo_ClientStreamingEchoServer) error { fmt.Printf("--- ClientStreamingEcho ---\n") // Create trailer in defer to record function return time. defer func() { @@ -154,7 +150,7 @@ func (s *server) ClientStreamingEcho(stream pb.Echo_ClientStreamingEchoServer) e } } -func (s *server) BidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamingEchoServer) error { +func bidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamingEchoServer) error { fmt.Printf("--- BidirectionalStreamingEcho ---\n") // Create trailer in defer to record function return time. defer func() { @@ -205,6 +201,11 @@ func main() { fmt.Printf("server listening at %v\n", lis.Addr()) s := grpc.NewServer() - pb.RegisterEchoServer(s, &server{}) + pb.RegisterEchoService(s, &pb.EchoService{ + UnaryEcho: unaryEcho, + ServerStreamingEcho: serverStreamingEcho, + ClientStreamingEcho: clientStreamingEcho, + BidirectionalStreamingEcho: bidirectionalStreamingEcho, + }) s.Serve(lis) } diff --git a/examples/features/multiplex/server/main.go b/examples/features/multiplex/server/main.go index 18da09ad..d8b13305 100644 --- a/examples/features/multiplex/server/main.go +++ b/examples/features/multiplex/server/main.go @@ -34,21 +34,13 @@ import ( var port = flag.Int("port", 50051, "the port to serve on") -// hwServer is used to implement helloworld.GreeterServer. -type hwServer struct { - hwpb.UnimplementedGreeterServer -} - -// SayHello implements helloworld.GreeterServer -func (s *hwServer) SayHello(ctx context.Context, in *hwpb.HelloRequest) (*hwpb.HelloReply, error) { +// sayHello implements helloworld.GreeterServer.SayHello +func sayHello(ctx context.Context, in *hwpb.HelloRequest) (*hwpb.HelloReply, error) { return &hwpb.HelloReply{Message: "Hello " + in.Name}, nil } -type ecServer struct { - ecpb.UnimplementedEchoServer -} - -func (s *ecServer) UnaryEcho(ctx context.Context, req *ecpb.EchoRequest) (*ecpb.EchoResponse, error) { +// unaryEcho implements echo.Echo.UnaryEcho +func unaryEcho(ctx context.Context, req *ecpb.EchoRequest) (*ecpb.EchoResponse, error) { return &ecpb.EchoResponse{Message: req.Message}, nil } @@ -63,10 +55,10 @@ func main() { s := grpc.NewServer() // Register Greeter on the server. - hwpb.RegisterGreeterServer(s, &hwServer{}) + hwpb.RegisterGreeterService(s, &hwpb.GreeterService{SayHello: sayHello}) - // Register RouteGuide on the same server. - ecpb.RegisterEchoServer(s, &ecServer{}) + // Register Echo on the same server. + ecpb.RegisterEchoService(s, &ecpb.EchoService{UnaryEcho: unaryEcho}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) diff --git a/examples/features/name_resolving/server/main.go b/examples/features/name_resolving/server/main.go index 1977f44d..77d35eb2 100644 --- a/examples/features/name_resolving/server/main.go +++ b/examples/features/name_resolving/server/main.go @@ -32,13 +32,8 @@ import ( const addr = "localhost:50051" -type ecServer struct { - pb.UnimplementedEchoServer - addr string -} - -func (s *ecServer) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { - return &pb.EchoResponse{Message: fmt.Sprintf("%s (from %s)", req.Message, s.addr)}, nil +func unaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { + return &pb.EchoResponse{Message: fmt.Sprintf("%s (from %s)", req.Message, addr)}, nil } func main() { @@ -47,7 +42,7 @@ func main() { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() - pb.RegisterEchoServer(s, &ecServer{addr: addr}) + pb.RegisterEchoService(s, &pb.EchoService{UnaryEcho: unaryEcho}) log.Printf("serving on %s\n", addr) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) diff --git a/examples/features/profiling/README.md b/examples/features/profiling/README.md index 1fd80e9a..8c30a3db 100644 --- a/examples/features/profiling/README.md +++ b/examples/features/profiling/README.md @@ -41,7 +41,7 @@ type server struct{} func main() error { s := grpc.NewServer() - pb.RegisterEchoServer(s, &server{}) + pb.RegisterEchoService(s, &pb.EchoService{...}) // Include this to register a profiling-specific service within your server. if err := profsvc.Init(&profsvc.ProfilingConfig{Server: s}); err != nil { diff --git a/examples/features/profiling/server/main.go b/examples/features/profiling/server/main.go index ee0a4f55..aa0bf11b 100644 --- a/examples/features/profiling/server/main.go +++ b/examples/features/profiling/server/main.go @@ -33,11 +33,7 @@ import ( var port = flag.Int("port", 50051, "the port to serve on") -type server struct { - pb.UnimplementedEchoServer -} - -func (s *server) UnaryEcho(ctx context.Context, in *pb.EchoRequest) (*pb.EchoResponse, error) { +func unaryEcho(ctx context.Context, in *pb.EchoRequest) (*pb.EchoResponse, error) { fmt.Printf("UnaryEcho called with message %q\n", in.GetMessage()) return &pb.EchoResponse{Message: in.Message}, nil } @@ -52,7 +48,7 @@ func main() { fmt.Printf("server listening at %v\n", lis.Addr()) s := grpc.NewServer() - pb.RegisterEchoServer(s, &server{}) + pb.RegisterEchoService(s, &pb.EchoService{UnaryEcho: unaryEcho}) // Register your grpc.Server with profiling. pc := &profsvc.ProfilingConfig{ diff --git a/examples/features/proto/echo/echo_grpc.pb.go b/examples/features/proto/echo/echo_grpc.pb.go index ff366435..a3597048 100644 --- a/examples/features/proto/echo/echo_grpc.pb.go +++ b/examples/features/proto/echo/echo_grpc.pb.go @@ -11,7 +11,7 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 // EchoClient is the client API for Echo service. // @@ -35,6 +35,10 @@ func NewEchoClient(cc grpc.ClientConnInterface) EchoClient { return &echoClient{cc} } +var echoUnaryEchoStreamDesc = &grpc.StreamDesc{ + StreamName: "UnaryEcho", +} + func (c *echoClient) UnaryEcho(ctx context.Context, in *EchoRequest, opts ...grpc.CallOption) (*EchoResponse, error) { out := new(EchoResponse) err := c.cc.Invoke(ctx, "/grpc.examples.echo.Echo/UnaryEcho", in, out, opts...) @@ -44,8 +48,13 @@ func (c *echoClient) UnaryEcho(ctx context.Context, in *EchoRequest, opts ...grp return out, nil } +var echoServerStreamingEchoStreamDesc = &grpc.StreamDesc{ + StreamName: "ServerStreamingEcho", + ServerStreams: true, +} + func (c *echoClient) ServerStreamingEcho(ctx context.Context, in *EchoRequest, opts ...grpc.CallOption) (Echo_ServerStreamingEchoClient, error) { - stream, err := c.cc.NewStream(ctx, &_Echo_serviceDesc.Streams[0], "/grpc.examples.echo.Echo/ServerStreamingEcho", opts...) + stream, err := c.cc.NewStream(ctx, echoServerStreamingEchoStreamDesc, "/grpc.examples.echo.Echo/ServerStreamingEcho", opts...) if err != nil { return nil, err } @@ -76,8 +85,13 @@ func (x *echoServerStreamingEchoClient) Recv() (*EchoResponse, error) { return m, nil } +var echoClientStreamingEchoStreamDesc = &grpc.StreamDesc{ + StreamName: "ClientStreamingEcho", + ClientStreams: true, +} + func (c *echoClient) ClientStreamingEcho(ctx context.Context, opts ...grpc.CallOption) (Echo_ClientStreamingEchoClient, error) { - stream, err := c.cc.NewStream(ctx, &_Echo_serviceDesc.Streams[1], "/grpc.examples.echo.Echo/ClientStreamingEcho", opts...) + stream, err := c.cc.NewStream(ctx, echoClientStreamingEchoStreamDesc, "/grpc.examples.echo.Echo/ClientStreamingEcho", opts...) if err != nil { return nil, err } @@ -110,8 +124,14 @@ func (x *echoClientStreamingEchoClient) CloseAndRecv() (*EchoResponse, error) { return m, nil } +var echoBidirectionalStreamingEchoStreamDesc = &grpc.StreamDesc{ + StreamName: "BidirectionalStreamingEcho", + ServerStreams: true, + ClientStreams: true, +} + func (c *echoClient) BidirectionalStreamingEcho(ctx context.Context, opts ...grpc.CallOption) (Echo_BidirectionalStreamingEchoClient, error) { - stream, err := c.cc.NewStream(ctx, &_Echo_serviceDesc.Streams[2], "/grpc.examples.echo.Echo/BidirectionalStreamingEcho", opts...) + stream, err := c.cc.NewStream(ctx, echoBidirectionalStreamingEchoStreamDesc, "/grpc.examples.echo.Echo/BidirectionalStreamingEcho", opts...) if err != nil { return nil, err } @@ -141,65 +161,62 @@ func (x *echoBidirectionalStreamingEchoClient) Recv() (*EchoResponse, error) { return m, nil } -// EchoServer is the server API for Echo service. -// All implementations should embed UnimplementedEchoServer -// for forward compatibility -type EchoServer interface { +// EchoService is the service API for Echo service. +// Fields should be assigned to their respective handler implementations only before +// RegisterEchoService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type EchoService struct { // UnaryEcho is unary echo. - UnaryEcho(context.Context, *EchoRequest) (*EchoResponse, error) + UnaryEcho func(context.Context, *EchoRequest) (*EchoResponse, error) // ServerStreamingEcho is server side streaming. - ServerStreamingEcho(*EchoRequest, Echo_ServerStreamingEchoServer) error + ServerStreamingEcho func(*EchoRequest, Echo_ServerStreamingEchoServer) error // ClientStreamingEcho is client side streaming. - ClientStreamingEcho(Echo_ClientStreamingEchoServer) error + ClientStreamingEcho func(Echo_ClientStreamingEchoServer) error // BidirectionalStreamingEcho is bidi streaming. - BidirectionalStreamingEcho(Echo_BidirectionalStreamingEchoServer) error + BidirectionalStreamingEcho func(Echo_BidirectionalStreamingEchoServer) error } -// UnimplementedEchoServer should be embedded to have forward compatible implementations. -type UnimplementedEchoServer struct { -} - -func (*UnimplementedEchoServer) UnaryEcho(context.Context, *EchoRequest) (*EchoResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UnaryEcho not implemented") -} -func (*UnimplementedEchoServer) ServerStreamingEcho(*EchoRequest, Echo_ServerStreamingEchoServer) error { - return status.Errorf(codes.Unimplemented, "method ServerStreamingEcho not implemented") -} -func (*UnimplementedEchoServer) ClientStreamingEcho(Echo_ClientStreamingEchoServer) error { - return status.Errorf(codes.Unimplemented, "method ClientStreamingEcho not implemented") -} -func (*UnimplementedEchoServer) BidirectionalStreamingEcho(Echo_BidirectionalStreamingEchoServer) error { - return status.Errorf(codes.Unimplemented, "method BidirectionalStreamingEcho not implemented") -} - -func RegisterEchoServer(s *grpc.Server, srv EchoServer) { - s.RegisterService(&_Echo_serviceDesc, srv) -} - -func _Echo_UnaryEcho_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func (s *EchoService) unaryEcho(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.UnaryEcho == nil { + return nil, status.Errorf(codes.Unimplemented, "method UnaryEcho not implemented") + } in := new(EchoRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(EchoServer).UnaryEcho(ctx, in) + return s.UnaryEcho(ctx, in) } info := &grpc.UnaryServerInfo{ - Server: srv, + Server: s, FullMethod: "/grpc.examples.echo.Echo/UnaryEcho", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(EchoServer).UnaryEcho(ctx, req.(*EchoRequest)) + return s.UnaryEcho(ctx, req.(*EchoRequest)) } return interceptor(ctx, in, info, handler) } - -func _Echo_ServerStreamingEcho_Handler(srv interface{}, stream grpc.ServerStream) error { +func (s *EchoService) serverStreamingEcho(_ interface{}, stream grpc.ServerStream) error { + if s.ServerStreamingEcho == nil { + return status.Errorf(codes.Unimplemented, "method ServerStreamingEcho not implemented") + } m := new(EchoRequest) if err := stream.RecvMsg(m); err != nil { return err } - return srv.(EchoServer).ServerStreamingEcho(m, &echoServerStreamingEchoServer{stream}) + return s.ServerStreamingEcho(m, &echoServerStreamingEchoServer{stream}) +} +func (s *EchoService) clientStreamingEcho(_ interface{}, stream grpc.ServerStream) error { + if s.ClientStreamingEcho == nil { + return status.Errorf(codes.Unimplemented, "method ClientStreamingEcho not implemented") + } + return s.ClientStreamingEcho(&echoClientStreamingEchoServer{stream}) +} +func (s *EchoService) bidirectionalStreamingEcho(_ interface{}, stream grpc.ServerStream) error { + if s.BidirectionalStreamingEcho == nil { + return status.Errorf(codes.Unimplemented, "method BidirectionalStreamingEcho not implemented") + } + return s.BidirectionalStreamingEcho(&echoBidirectionalStreamingEchoServer{stream}) } type Echo_ServerStreamingEchoServer interface { @@ -215,10 +232,6 @@ func (x *echoServerStreamingEchoServer) Send(m *EchoResponse) error { return x.ServerStream.SendMsg(m) } -func _Echo_ClientStreamingEcho_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(EchoServer).ClientStreamingEcho(&echoClientStreamingEchoServer{stream}) -} - type Echo_ClientStreamingEchoServer interface { SendAndClose(*EchoResponse) error Recv() (*EchoRequest, error) @@ -241,10 +254,6 @@ func (x *echoClientStreamingEchoServer) Recv() (*EchoRequest, error) { return m, nil } -func _Echo_BidirectionalStreamingEcho_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(EchoServer).BidirectionalStreamingEcho(&echoBidirectionalStreamingEchoServer{stream}) -} - type Echo_BidirectionalStreamingEchoServer interface { Send(*EchoResponse) error Recv() (*EchoRequest, error) @@ -267,32 +276,82 @@ func (x *echoBidirectionalStreamingEchoServer) Recv() (*EchoRequest, error) { return m, nil } -var _Echo_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.examples.echo.Echo", - HandlerType: (*EchoServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "UnaryEcho", - Handler: _Echo_UnaryEcho_Handler, +// RegisterEchoService registers a service implementation with a gRPC server. +func RegisterEchoService(s grpc.ServiceRegistrar, srv *EchoService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.examples.echo.Echo", + Methods: []grpc.MethodDesc{ + { + MethodName: "UnaryEcho", + Handler: srv.unaryEcho, + }, }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "ServerStreamingEcho", - Handler: _Echo_ServerStreamingEcho_Handler, - ServerStreams: true, + Streams: []grpc.StreamDesc{ + { + StreamName: "ServerStreamingEcho", + Handler: srv.serverStreamingEcho, + ServerStreams: true, + }, + { + StreamName: "ClientStreamingEcho", + Handler: srv.clientStreamingEcho, + ClientStreams: true, + }, + { + StreamName: "BidirectionalStreamingEcho", + Handler: srv.bidirectionalStreamingEcho, + ServerStreams: true, + ClientStreams: true, + }, }, - { - StreamName: "ClientStreamingEcho", - Handler: _Echo_ClientStreamingEcho_Handler, - ClientStreams: true, - }, - { - StreamName: "BidirectionalStreamingEcho", - Handler: _Echo_BidirectionalStreamingEcho_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "examples/features/proto/echo/echo.proto", + Metadata: "examples/features/proto/echo/echo.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewEchoService creates a new EchoService containing the +// implemented methods of the Echo service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewEchoService(s interface{}) *EchoService { + ns := &EchoService{} + if h, ok := s.(interface { + UnaryEcho(context.Context, *EchoRequest) (*EchoResponse, error) + }); ok { + ns.UnaryEcho = h.UnaryEcho + } + if h, ok := s.(interface { + ServerStreamingEcho(*EchoRequest, Echo_ServerStreamingEchoServer) error + }); ok { + ns.ServerStreamingEcho = h.ServerStreamingEcho + } + if h, ok := s.(interface { + ClientStreamingEcho(Echo_ClientStreamingEchoServer) error + }); ok { + ns.ClientStreamingEcho = h.ClientStreamingEcho + } + if h, ok := s.(interface { + BidirectionalStreamingEcho(Echo_BidirectionalStreamingEchoServer) error + }); ok { + ns.BidirectionalStreamingEcho = h.BidirectionalStreamingEcho + } + return ns +} + +// UnstableEchoService is the service API for Echo service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableEchoService interface { + // UnaryEcho is unary echo. + UnaryEcho(context.Context, *EchoRequest) (*EchoResponse, error) + // ServerStreamingEcho is server side streaming. + ServerStreamingEcho(*EchoRequest, Echo_ServerStreamingEchoServer) error + // ClientStreamingEcho is client side streaming. + ClientStreamingEcho(Echo_ClientStreamingEchoServer) error + // BidirectionalStreamingEcho is bidi streaming. + BidirectionalStreamingEcho(Echo_BidirectionalStreamingEchoServer) error } diff --git a/examples/features/reflection/server/main.go b/examples/features/reflection/server/main.go index 569273df..1501c01f 100644 --- a/examples/features/reflection/server/main.go +++ b/examples/features/reflection/server/main.go @@ -35,21 +35,13 @@ import ( var port = flag.Int("port", 50051, "the port to serve on") -// hwServer is used to implement helloworld.GreeterServer. -type hwServer struct { - hwpb.UnimplementedGreeterServer -} - -// SayHello implements helloworld.GreeterServer -func (s *hwServer) SayHello(ctx context.Context, in *hwpb.HelloRequest) (*hwpb.HelloReply, error) { +// sayHello implements helloworld.GreeterServer.SayHello +func sayHello(ctx context.Context, in *hwpb.HelloRequest) (*hwpb.HelloReply, error) { return &hwpb.HelloReply{Message: "Hello " + in.Name}, nil } -type ecServer struct { - ecpb.UnimplementedEchoServer -} - -func (s *ecServer) UnaryEcho(ctx context.Context, req *ecpb.EchoRequest) (*ecpb.EchoResponse, error) { +// unaryEcho implements echo.Echo.UnaryEcho +func unaryEcho(ctx context.Context, req *ecpb.EchoRequest) (*ecpb.EchoResponse, error) { return &ecpb.EchoResponse{Message: req.Message}, nil } @@ -64,10 +56,10 @@ func main() { s := grpc.NewServer() // Register Greeter on the server. - hwpb.RegisterGreeterServer(s, &hwServer{}) + hwpb.RegisterGreeterService(s, &hwpb.GreeterService{SayHello: sayHello}) // Register RouteGuide on the same server. - ecpb.RegisterEchoServer(s, &ecServer{}) + ecpb.RegisterEchoService(s, &ecpb.EchoService{UnaryEcho: unaryEcho}) // Register reflection service on gRPC server. reflection.Register(s) diff --git a/examples/features/retry/server/main.go b/examples/features/retry/server/main.go index fdec2f05..08dd40c9 100644 --- a/examples/features/retry/server/main.go +++ b/examples/features/retry/server/main.go @@ -37,7 +37,6 @@ import ( var port = flag.Int("port", 50052, "port number") type failingServer struct { - pb.UnimplementedEchoServer mu sync.Mutex reqCounter uint @@ -86,7 +85,7 @@ func main() { reqModulo: 4, } - pb.RegisterEchoServer(s, failingservice) + pb.RegisterEchoService(s, &pb.EchoService{UnaryEcho: failingservice.UnaryEcho}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } diff --git a/examples/features/wait_for_ready/main.go b/examples/features/wait_for_ready/main.go index f865410f..f3669e98 100644 --- a/examples/features/wait_for_ready/main.go +++ b/examples/features/wait_for_ready/main.go @@ -34,12 +34,7 @@ import ( pb "google.golang.org/grpc/examples/features/proto/echo" ) -// server is used to implement EchoServer. -type server struct { - pb.UnimplementedEchoServer -} - -func (s *server) UnaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { +func unaryEcho(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { return &pb.EchoResponse{Message: req.Message}, nil } @@ -50,7 +45,7 @@ func serve() { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() - pb.RegisterEchoServer(s, &server{}) + pb.RegisterEchoService(s, &pb.EchoService{UnaryEcho: unaryEcho}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) diff --git a/examples/features/xds/server/main.go b/examples/features/xds/server/main.go index 7e081564..96cd6e46 100644 --- a/examples/features/xds/server/main.go +++ b/examples/features/xds/server/main.go @@ -45,8 +45,6 @@ const ( // server is used to implement helloworld.GreeterServer. type server struct { - pb.UnimplementedGreeterServer - serverName string } @@ -124,7 +122,8 @@ func main() { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() - pb.RegisterGreeterServer(s, newServer(hostname)) + hw := newServer(hostname) + pb.RegisterGreeterService(s, &pb.GreeterService{SayHello: hw.SayHello}) reflection.Register(s) healthServer := health.NewServer() diff --git a/examples/go.mod b/examples/go.mod index 5235f543..d4e2b7c3 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -3,8 +3,11 @@ module google.golang.org/grpc/examples go 1.11 require ( + cloud.google.com/go v0.63.0 // indirect github.com/golang/protobuf v1.4.2 - golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be - google.golang.org/genproto v0.0.0-20200624020401-64a14ca9d1ad + golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d + google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98 google.golang.org/grpc v1.31.0 ) + +replace google.golang.org/grpc => ../ diff --git a/examples/go.sum b/examples/go.sum index f55a4617..1ef62013 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -1,22 +1,68 @@ -cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ= -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.63.0 h1:A+DfAZQ/eWca7gvu42CS6FNSDX4R8cghF+XfWLn4R6g= +cloud.google.com/go v0.63.0/go.mod h1:GmezbQc7T2snqkEXWfZ0sy0VfkB/ivI2DdtJL2DEmlg= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.4 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -26,53 +72,259 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642 h1:B6caxRw+hozq68X2MY7jEpZh/cr4/aHLv9xU8Kkadrw= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200806022845-90696ccdc692/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200624020401-64a14ca9d1ad h1:uAwc13+y0Y8QZLTYhLCu6lHhnG99ecQU5FYTj8zxAng= -google.golang.org/genproto v0.0.0-20200624020401-64a14ca9d1ad/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.31.0 h1:T7P4R73V3SSDPhH7WW7ATbfViLtmamH0DKrP3f9AuDI= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98 h1:LCO0fg4kb6WwkXQXRQQgUYsFeFb5taTX5WAx5O/Vt28= +google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -84,5 +336,19 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/examples/gotutorial.md b/examples/gotutorial.md index 86993562..2862b0a2 100644 --- a/examples/gotutorial.md +++ b/examples/gotutorial.md @@ -268,7 +268,13 @@ if err != nil { log.Fatalf("failed to listen: %v", err) } grpcServer := grpc.NewServer() -pb.RegisterRouteGuideServer(grpcServer, &routeGuideServer{}) +rgs := &routeGuideServer{} +pb.RegisterRouteGuideService(grpcServer, pb.RouteGuideService{ + GetFeature: rgs.GetFeature, + ListFeatures: rgs.ListFeatures, + RecordRoute: rgs.RecordRoute, + RouteChat: rgs.RouteChat, +}) ... // determine whether to use TLS grpcServer.Serve(lis) ``` diff --git a/examples/helloworld/greeter_server/main.go b/examples/helloworld/greeter_server/main.go index 15604f9f..4406f420 100644 --- a/examples/helloworld/greeter_server/main.go +++ b/examples/helloworld/greeter_server/main.go @@ -32,13 +32,8 @@ const ( port = ":50051" ) -// server is used to implement helloworld.GreeterServer. -type server struct { - pb.UnimplementedGreeterServer -} - -// SayHello implements helloworld.GreeterServer -func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { +// sayHello implements helloworld.GreeterServer.SayHello +func sayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { log.Printf("Received: %v", in.GetName()) return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil } @@ -49,7 +44,7 @@ func main() { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() - pb.RegisterGreeterServer(s, &server{}) + pb.RegisterGreeterService(s, &pb.GreeterService{SayHello: sayHello}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } diff --git a/examples/helloworld/helloworld/helloworld_grpc.pb.go b/examples/helloworld/helloworld/helloworld_grpc.pb.go index 435df1a0..b45a600c 100644 --- a/examples/helloworld/helloworld/helloworld_grpc.pb.go +++ b/examples/helloworld/helloworld/helloworld_grpc.pb.go @@ -11,7 +11,7 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 // GreeterClient is the client API for Greeter service. // @@ -29,6 +29,10 @@ func NewGreeterClient(cc grpc.ClientConnInterface) GreeterClient { return &greeterClient{cc} } +var greeterSayHelloStreamDesc = &grpc.StreamDesc{ + StreamName: "SayHello", +} + func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) { out := new(HelloReply) err := c.cc.Invoke(ctx, "/helloworld.Greeter/SayHello", in, out, opts...) @@ -38,53 +42,74 @@ func (c *greeterClient) SayHello(ctx context.Context, in *HelloRequest, opts ... return out, nil } -// GreeterServer is the server API for Greeter service. -// All implementations should embed UnimplementedGreeterServer -// for forward compatibility -type GreeterServer interface { +// GreeterService is the service API for Greeter service. +// Fields should be assigned to their respective handler implementations only before +// RegisterGreeterService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type GreeterService struct { // Sends a greeting - SayHello(context.Context, *HelloRequest) (*HelloReply, error) + SayHello func(context.Context, *HelloRequest) (*HelloReply, error) } -// UnimplementedGreeterServer should be embedded to have forward compatible implementations. -type UnimplementedGreeterServer struct { -} - -func (*UnimplementedGreeterServer) SayHello(context.Context, *HelloRequest) (*HelloReply, error) { - return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") -} - -func RegisterGreeterServer(s *grpc.Server, srv GreeterServer) { - s.RegisterService(&_Greeter_serviceDesc, srv) -} - -func _Greeter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func (s *GreeterService) sayHello(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.SayHello == nil { + return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented") + } in := new(HelloRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(GreeterServer).SayHello(ctx, in) + return s.SayHello(ctx, in) } info := &grpc.UnaryServerInfo{ - Server: srv, + Server: s, FullMethod: "/helloworld.Greeter/SayHello", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(GreeterServer).SayHello(ctx, req.(*HelloRequest)) + return s.SayHello(ctx, req.(*HelloRequest)) } return interceptor(ctx, in, info, handler) } -var _Greeter_serviceDesc = grpc.ServiceDesc{ - ServiceName: "helloworld.Greeter", - HandlerType: (*GreeterServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "SayHello", - Handler: _Greeter_SayHello_Handler, +// RegisterGreeterService registers a service implementation with a gRPC server. +func RegisterGreeterService(s grpc.ServiceRegistrar, srv *GreeterService) { + sd := grpc.ServiceDesc{ + ServiceName: "helloworld.Greeter", + Methods: []grpc.MethodDesc{ + { + MethodName: "SayHello", + Handler: srv.sayHello, + }, }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "examples/helloworld/helloworld/helloworld.proto", + Streams: []grpc.StreamDesc{}, + Metadata: "examples/helloworld/helloworld/helloworld.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewGreeterService creates a new GreeterService containing the +// implemented methods of the Greeter service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewGreeterService(s interface{}) *GreeterService { + ns := &GreeterService{} + if h, ok := s.(interface { + SayHello(context.Context, *HelloRequest) (*HelloReply, error) + }); ok { + ns.SayHello = h.SayHello + } + return ns +} + +// UnstableGreeterService is the service API for Greeter service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableGreeterService interface { + // Sends a greeting + SayHello(context.Context, *HelloRequest) (*HelloReply, error) } diff --git a/examples/route_guide/routeguide/route_guide_grpc.pb.go b/examples/route_guide/routeguide/route_guide_grpc.pb.go index 9ae8b448..f9c59a7f 100644 --- a/examples/route_guide/routeguide/route_guide_grpc.pb.go +++ b/examples/route_guide/routeguide/route_guide_grpc.pb.go @@ -11,7 +11,7 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 // RouteGuideClient is the client API for RouteGuide service. // @@ -51,6 +51,10 @@ func NewRouteGuideClient(cc grpc.ClientConnInterface) RouteGuideClient { return &routeGuideClient{cc} } +var routeGuideGetFeatureStreamDesc = &grpc.StreamDesc{ + StreamName: "GetFeature", +} + func (c *routeGuideClient) GetFeature(ctx context.Context, in *Point, opts ...grpc.CallOption) (*Feature, error) { out := new(Feature) err := c.cc.Invoke(ctx, "/routeguide.RouteGuide/GetFeature", in, out, opts...) @@ -60,8 +64,13 @@ func (c *routeGuideClient) GetFeature(ctx context.Context, in *Point, opts ...gr return out, nil } +var routeGuideListFeaturesStreamDesc = &grpc.StreamDesc{ + StreamName: "ListFeatures", + ServerStreams: true, +} + func (c *routeGuideClient) ListFeatures(ctx context.Context, in *Rectangle, opts ...grpc.CallOption) (RouteGuide_ListFeaturesClient, error) { - stream, err := c.cc.NewStream(ctx, &_RouteGuide_serviceDesc.Streams[0], "/routeguide.RouteGuide/ListFeatures", opts...) + stream, err := c.cc.NewStream(ctx, routeGuideListFeaturesStreamDesc, "/routeguide.RouteGuide/ListFeatures", opts...) if err != nil { return nil, err } @@ -92,8 +101,13 @@ func (x *routeGuideListFeaturesClient) Recv() (*Feature, error) { return m, nil } +var routeGuideRecordRouteStreamDesc = &grpc.StreamDesc{ + StreamName: "RecordRoute", + ClientStreams: true, +} + func (c *routeGuideClient) RecordRoute(ctx context.Context, opts ...grpc.CallOption) (RouteGuide_RecordRouteClient, error) { - stream, err := c.cc.NewStream(ctx, &_RouteGuide_serviceDesc.Streams[1], "/routeguide.RouteGuide/RecordRoute", opts...) + stream, err := c.cc.NewStream(ctx, routeGuideRecordRouteStreamDesc, "/routeguide.RouteGuide/RecordRoute", opts...) if err != nil { return nil, err } @@ -126,8 +140,14 @@ func (x *routeGuideRecordRouteClient) CloseAndRecv() (*RouteSummary, error) { return m, nil } +var routeGuideRouteChatStreamDesc = &grpc.StreamDesc{ + StreamName: "RouteChat", + ServerStreams: true, + ClientStreams: true, +} + func (c *routeGuideClient) RouteChat(ctx context.Context, opts ...grpc.CallOption) (RouteGuide_RouteChatClient, error) { - stream, err := c.cc.NewStream(ctx, &_RouteGuide_serviceDesc.Streams[2], "/routeguide.RouteGuide/RouteChat", opts...) + stream, err := c.cc.NewStream(ctx, routeGuideRouteChatStreamDesc, "/routeguide.RouteGuide/RouteChat", opts...) if err != nil { return nil, err } @@ -157,10 +177,207 @@ func (x *routeGuideRouteChatClient) Recv() (*RouteNote, error) { return m, nil } -// RouteGuideServer is the server API for RouteGuide service. -// All implementations should embed UnimplementedRouteGuideServer -// for forward compatibility -type RouteGuideServer interface { +// RouteGuideService is the service API for RouteGuide service. +// Fields should be assigned to their respective handler implementations only before +// RegisterRouteGuideService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type RouteGuideService struct { + // A simple RPC. + // + // Obtains the feature at a given position. + // + // A feature with an empty name is returned if there's no feature at the given + // position. + GetFeature func(context.Context, *Point) (*Feature, error) + // A server-to-client streaming RPC. + // + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + ListFeatures func(*Rectangle, RouteGuide_ListFeaturesServer) error + // A client-to-server streaming RPC. + // + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + RecordRoute func(RouteGuide_RecordRouteServer) error + // A Bidirectional streaming RPC. + // + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + RouteChat func(RouteGuide_RouteChatServer) error +} + +func (s *RouteGuideService) getFeature(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.GetFeature == nil { + return nil, status.Errorf(codes.Unimplemented, "method GetFeature not implemented") + } + in := new(Point) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return s.GetFeature(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: s, + FullMethod: "/routeguide.RouteGuide/GetFeature", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return s.GetFeature(ctx, req.(*Point)) + } + return interceptor(ctx, in, info, handler) +} +func (s *RouteGuideService) listFeatures(_ interface{}, stream grpc.ServerStream) error { + if s.ListFeatures == nil { + return status.Errorf(codes.Unimplemented, "method ListFeatures not implemented") + } + m := new(Rectangle) + if err := stream.RecvMsg(m); err != nil { + return err + } + return s.ListFeatures(m, &routeGuideListFeaturesServer{stream}) +} +func (s *RouteGuideService) recordRoute(_ interface{}, stream grpc.ServerStream) error { + if s.RecordRoute == nil { + return status.Errorf(codes.Unimplemented, "method RecordRoute not implemented") + } + return s.RecordRoute(&routeGuideRecordRouteServer{stream}) +} +func (s *RouteGuideService) routeChat(_ interface{}, stream grpc.ServerStream) error { + if s.RouteChat == nil { + return status.Errorf(codes.Unimplemented, "method RouteChat not implemented") + } + return s.RouteChat(&routeGuideRouteChatServer{stream}) +} + +type RouteGuide_ListFeaturesServer interface { + Send(*Feature) error + grpc.ServerStream +} + +type routeGuideListFeaturesServer struct { + grpc.ServerStream +} + +func (x *routeGuideListFeaturesServer) Send(m *Feature) error { + return x.ServerStream.SendMsg(m) +} + +type RouteGuide_RecordRouteServer interface { + SendAndClose(*RouteSummary) error + Recv() (*Point, error) + grpc.ServerStream +} + +type routeGuideRecordRouteServer struct { + grpc.ServerStream +} + +func (x *routeGuideRecordRouteServer) SendAndClose(m *RouteSummary) error { + return x.ServerStream.SendMsg(m) +} + +func (x *routeGuideRecordRouteServer) Recv() (*Point, error) { + m := new(Point) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +type RouteGuide_RouteChatServer interface { + Send(*RouteNote) error + Recv() (*RouteNote, error) + grpc.ServerStream +} + +type routeGuideRouteChatServer struct { + grpc.ServerStream +} + +func (x *routeGuideRouteChatServer) Send(m *RouteNote) error { + return x.ServerStream.SendMsg(m) +} + +func (x *routeGuideRouteChatServer) Recv() (*RouteNote, error) { + m := new(RouteNote) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// RegisterRouteGuideService registers a service implementation with a gRPC server. +func RegisterRouteGuideService(s grpc.ServiceRegistrar, srv *RouteGuideService) { + sd := grpc.ServiceDesc{ + ServiceName: "routeguide.RouteGuide", + Methods: []grpc.MethodDesc{ + { + MethodName: "GetFeature", + Handler: srv.getFeature, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "ListFeatures", + Handler: srv.listFeatures, + ServerStreams: true, + }, + { + StreamName: "RecordRoute", + Handler: srv.recordRoute, + ClientStreams: true, + }, + { + StreamName: "RouteChat", + Handler: srv.routeChat, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "examples/route_guide/routeguide/route_guide.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewRouteGuideService creates a new RouteGuideService containing the +// implemented methods of the RouteGuide service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewRouteGuideService(s interface{}) *RouteGuideService { + ns := &RouteGuideService{} + if h, ok := s.(interface { + GetFeature(context.Context, *Point) (*Feature, error) + }); ok { + ns.GetFeature = h.GetFeature + } + if h, ok := s.(interface { + ListFeatures(*Rectangle, RouteGuide_ListFeaturesServer) error + }); ok { + ns.ListFeatures = h.ListFeatures + } + if h, ok := s.(interface { + RecordRoute(RouteGuide_RecordRouteServer) error + }); ok { + ns.RecordRoute = h.RecordRoute + } + if h, ok := s.(interface { + RouteChat(RouteGuide_RouteChatServer) error + }); ok { + ns.RouteChat = h.RouteChat + } + return ns +} + +// UnstableRouteGuideService is the service API for RouteGuide service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableRouteGuideService interface { // A simple RPC. // // Obtains the feature at a given position. @@ -186,145 +403,3 @@ type RouteGuideServer interface { // while receiving other RouteNotes (e.g. from other users). RouteChat(RouteGuide_RouteChatServer) error } - -// UnimplementedRouteGuideServer should be embedded to have forward compatible implementations. -type UnimplementedRouteGuideServer struct { -} - -func (*UnimplementedRouteGuideServer) GetFeature(context.Context, *Point) (*Feature, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetFeature not implemented") -} -func (*UnimplementedRouteGuideServer) ListFeatures(*Rectangle, RouteGuide_ListFeaturesServer) error { - return status.Errorf(codes.Unimplemented, "method ListFeatures not implemented") -} -func (*UnimplementedRouteGuideServer) RecordRoute(RouteGuide_RecordRouteServer) error { - return status.Errorf(codes.Unimplemented, "method RecordRoute not implemented") -} -func (*UnimplementedRouteGuideServer) RouteChat(RouteGuide_RouteChatServer) error { - return status.Errorf(codes.Unimplemented, "method RouteChat not implemented") -} - -func RegisterRouteGuideServer(s *grpc.Server, srv RouteGuideServer) { - s.RegisterService(&_RouteGuide_serviceDesc, srv) -} - -func _RouteGuide_GetFeature_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Point) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(RouteGuideServer).GetFeature(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/routeguide.RouteGuide/GetFeature", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RouteGuideServer).GetFeature(ctx, req.(*Point)) - } - return interceptor(ctx, in, info, handler) -} - -func _RouteGuide_ListFeatures_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(Rectangle) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(RouteGuideServer).ListFeatures(m, &routeGuideListFeaturesServer{stream}) -} - -type RouteGuide_ListFeaturesServer interface { - Send(*Feature) error - grpc.ServerStream -} - -type routeGuideListFeaturesServer struct { - grpc.ServerStream -} - -func (x *routeGuideListFeaturesServer) Send(m *Feature) error { - return x.ServerStream.SendMsg(m) -} - -func _RouteGuide_RecordRoute_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(RouteGuideServer).RecordRoute(&routeGuideRecordRouteServer{stream}) -} - -type RouteGuide_RecordRouteServer interface { - SendAndClose(*RouteSummary) error - Recv() (*Point, error) - grpc.ServerStream -} - -type routeGuideRecordRouteServer struct { - grpc.ServerStream -} - -func (x *routeGuideRecordRouteServer) SendAndClose(m *RouteSummary) error { - return x.ServerStream.SendMsg(m) -} - -func (x *routeGuideRecordRouteServer) Recv() (*Point, error) { - m := new(Point) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -func _RouteGuide_RouteChat_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(RouteGuideServer).RouteChat(&routeGuideRouteChatServer{stream}) -} - -type RouteGuide_RouteChatServer interface { - Send(*RouteNote) error - Recv() (*RouteNote, error) - grpc.ServerStream -} - -type routeGuideRouteChatServer struct { - grpc.ServerStream -} - -func (x *routeGuideRouteChatServer) Send(m *RouteNote) error { - return x.ServerStream.SendMsg(m) -} - -func (x *routeGuideRouteChatServer) Recv() (*RouteNote, error) { - m := new(RouteNote) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -var _RouteGuide_serviceDesc = grpc.ServiceDesc{ - ServiceName: "routeguide.RouteGuide", - HandlerType: (*RouteGuideServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "GetFeature", - Handler: _RouteGuide_GetFeature_Handler, - }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "ListFeatures", - Handler: _RouteGuide_ListFeatures_Handler, - ServerStreams: true, - }, - { - StreamName: "RecordRoute", - Handler: _RouteGuide_RecordRoute_Handler, - ClientStreams: true, - }, - { - StreamName: "RouteChat", - Handler: _RouteGuide_RouteChat_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "examples/route_guide/routeguide/route_guide.proto", -} diff --git a/examples/route_guide/server/server.go b/examples/route_guide/server/server.go index dd804406..7c959dde 100644 --- a/examples/route_guide/server/server.go +++ b/examples/route_guide/server/server.go @@ -54,7 +54,6 @@ var ( ) type routeGuideServer struct { - pb.UnimplementedRouteGuideServer savedFeatures []*pb.Feature // read-only after initialized mu sync.Mutex // protects routeNotes @@ -238,7 +237,7 @@ func main() { opts = []grpc.ServerOption{grpc.Creds(creds)} } grpcServer := grpc.NewServer(opts...) - pb.RegisterRouteGuideServer(grpcServer, newServer()) + pb.RegisterRouteGuideService(grpcServer, pb.NewRouteGuideService(newServer())) grpcServer.Serve(lis) } diff --git a/health/grpc_health_v1/health.pb.go b/health/grpc_health_v1/health.pb.go index e9919c00..4c2a527e 100644 --- a/health/grpc_health_v1/health.pb.go +++ b/health/grpc_health_v1/health.pb.go @@ -4,8 +4,12 @@ package grpc_health_v1 import ( + context "context" fmt "fmt" proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" math "math" ) @@ -159,3 +163,181 @@ var fileDescriptor_e265fd9d4e077217 = []byte{ 0xd3, 0x20, 0x46, 0xe8, 0x85, 0x19, 0x26, 0xb1, 0x81, 0x93, 0x83, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x12, 0x7d, 0x96, 0xcb, 0x2d, 0x02, 0x00, 0x00, } + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// 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.SupportPackageIsVersion6 + +// HealthClient is the client API for Health service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type HealthClient interface { + // If the requested service is unknown, the call will fail with status + // NOT_FOUND. + Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) + // Performs a watch for the serving status of the requested service. + // The server will immediately send back a message indicating the current + // serving status. It will then subsequently send a new message whenever + // the service's serving status changes. + // + // If the requested service is unknown when the call is received, the + // server will send a message setting the serving status to + // SERVICE_UNKNOWN but will *not* terminate the call. If at some + // future point, the serving status of the service becomes known, the + // server will send a new message with the service's serving status. + // + // If the call terminates with status UNIMPLEMENTED, then clients + // should assume this method is not supported and should not retry the + // call. If the call terminates with any other status (including OK), + // clients should retry the call with appropriate exponential backoff. + Watch(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (Health_WatchClient, error) +} + +type healthClient struct { + cc grpc.ClientConnInterface +} + +func NewHealthClient(cc grpc.ClientConnInterface) HealthClient { + return &healthClient{cc} +} + +func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) { + out := new(HealthCheckResponse) + err := c.cc.Invoke(ctx, "/grpc.health.v1.Health/Check", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *healthClient) Watch(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (Health_WatchClient, error) { + stream, err := c.cc.NewStream(ctx, &_Health_serviceDesc.Streams[0], "/grpc.health.v1.Health/Watch", opts...) + if err != nil { + return nil, err + } + x := &healthWatchClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type Health_WatchClient interface { + Recv() (*HealthCheckResponse, error) + grpc.ClientStream +} + +type healthWatchClient struct { + grpc.ClientStream +} + +func (x *healthWatchClient) Recv() (*HealthCheckResponse, error) { + m := new(HealthCheckResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// HealthServer is the server API for Health service. +type HealthServer interface { + // If the requested service is unknown, the call will fail with status + // NOT_FOUND. + Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) + // Performs a watch for the serving status of the requested service. + // The server will immediately send back a message indicating the current + // serving status. It will then subsequently send a new message whenever + // the service's serving status changes. + // + // If the requested service is unknown when the call is received, the + // server will send a message setting the serving status to + // SERVICE_UNKNOWN but will *not* terminate the call. If at some + // future point, the serving status of the service becomes known, the + // server will send a new message with the service's serving status. + // + // If the call terminates with status UNIMPLEMENTED, then clients + // should assume this method is not supported and should not retry the + // call. If the call terminates with any other status (including OK), + // clients should retry the call with appropriate exponential backoff. + Watch(*HealthCheckRequest, Health_WatchServer) error +} + +// UnimplementedHealthServer can be embedded to have forward compatible implementations. +type UnimplementedHealthServer struct { +} + +func (*UnimplementedHealthServer) Check(ctx context.Context, req *HealthCheckRequest) (*HealthCheckResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Check not implemented") +} +func (*UnimplementedHealthServer) Watch(req *HealthCheckRequest, srv Health_WatchServer) error { + return status.Errorf(codes.Unimplemented, "method Watch not implemented") +} + +func RegisterHealthServer(s *grpc.Server, srv HealthServer) { + s.RegisterService(&_Health_serviceDesc, srv) +} + +func _Health_Check_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(HealthCheckRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(HealthServer).Check(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.health.v1.Health/Check", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(HealthServer).Check(ctx, req.(*HealthCheckRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Health_Watch_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(HealthCheckRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(HealthServer).Watch(m, &healthWatchServer{stream}) +} + +type Health_WatchServer interface { + Send(*HealthCheckResponse) error + grpc.ServerStream +} + +type healthWatchServer struct { + grpc.ServerStream +} + +func (x *healthWatchServer) Send(m *HealthCheckResponse) error { + return x.ServerStream.SendMsg(m) +} + +var _Health_serviceDesc = grpc.ServiceDesc{ + ServiceName: "grpc.health.v1.Health", + HandlerType: (*HealthServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Check", + Handler: _Health_Check_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "Watch", + Handler: _Health_Watch_Handler, + ServerStreams: true, + }, + }, + Metadata: "grpc/health/v1/health.proto", +} diff --git a/health/grpc_health_v1/health_grpc.pb.go b/health/grpc_health_v1/health_grpc.pb.go index f87e3c92..716f8c01 100644 --- a/health/grpc_health_v1/health_grpc.pb.go +++ b/health/grpc_health_v1/health_grpc.pb.go @@ -11,15 +11,16 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 -// HealthClient is the client API for Health 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 HealthClient interface { +// HealthService is the service API for Health service. +// Fields should be assigned to their respective handler implementations only before +// RegisterHealthService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type HealthService struct { // If the requested service is unknown, the call will fail with status // NOT_FOUND. - Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) + Check func(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) // Performs a watch for the serving status of the requested service. // The server will immediately send back a message indicating the current // serving status. It will then subsequently send a new message whenever @@ -35,62 +36,89 @@ type HealthClient interface { // should assume this method is not supported and should not retry the // call. If the call terminates with any other status (including OK), // clients should retry the call with appropriate exponential backoff. - Watch(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (Health_WatchClient, error) + Watch func(*HealthCheckRequest, Health_WatchServer) error } -type healthClient struct { - cc grpc.ClientConnInterface -} - -func NewHealthClient(cc grpc.ClientConnInterface) HealthClient { - return &healthClient{cc} -} - -func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) { - out := new(HealthCheckResponse) - err := c.cc.Invoke(ctx, "/grpc.health.v1.Health/Check", in, out, opts...) - if err != nil { +func (s *HealthService) check(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.Check == nil { + return nil, status.Errorf(codes.Unimplemented, "method Check not implemented") + } + in := new(HealthCheckRequest) + if err := dec(in); err != nil { return nil, err } - return out, nil -} - -func (c *healthClient) Watch(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (Health_WatchClient, error) { - stream, err := c.cc.NewStream(ctx, &_Health_serviceDesc.Streams[0], "/grpc.health.v1.Health/Watch", opts...) - if err != nil { - return nil, err + if interceptor == nil { + return s.Check(ctx, in) } - x := &healthWatchClient{stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err + info := &grpc.UnaryServerInfo{ + Server: s, + FullMethod: "/grpc.health.v1.Health/Check", } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return s.Check(ctx, req.(*HealthCheckRequest)) } - return x, nil + return interceptor(ctx, in, info, handler) } - -type Health_WatchClient interface { - Recv() (*HealthCheckResponse, error) - grpc.ClientStream -} - -type healthWatchClient struct { - grpc.ClientStream -} - -func (x *healthWatchClient) Recv() (*HealthCheckResponse, error) { - m := new(HealthCheckResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err +func (s *HealthService) watch(_ interface{}, stream grpc.ServerStream) error { + if s.Watch == nil { + return status.Errorf(codes.Unimplemented, "method Watch not implemented") } - return m, nil + m := new(HealthCheckRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return s.Watch(m, &healthWatchServer{stream}) } -// HealthServer is the server API for Health service. -// All implementations should embed UnimplementedHealthServer -// for forward compatibility -type HealthServer interface { +// RegisterHealthService registers a service implementation with a gRPC server. +func RegisterHealthService(s grpc.ServiceRegistrar, srv *HealthService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.health.v1.Health", + Methods: []grpc.MethodDesc{ + { + MethodName: "Check", + Handler: srv.check, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "Watch", + Handler: srv.watch, + ServerStreams: true, + }, + }, + Metadata: "grpc/health/v1/health.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewHealthService creates a new HealthService containing the +// implemented methods of the Health service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewHealthService(s interface{}) *HealthService { + ns := &HealthService{} + if h, ok := s.(interface { + Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) + }); ok { + ns.Check = h.Check + } + if h, ok := s.(interface { + Watch(*HealthCheckRequest, Health_WatchServer) error + }); ok { + ns.Watch = h.Watch + } + return ns +} + +// UnstableHealthService is the service API for Health service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableHealthService interface { // If the requested service is unknown, the call will fail with status // NOT_FOUND. Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) @@ -111,76 +139,3 @@ type HealthServer interface { // clients should retry the call with appropriate exponential backoff. Watch(*HealthCheckRequest, Health_WatchServer) error } - -// UnimplementedHealthServer should be embedded to have forward compatible implementations. -type UnimplementedHealthServer struct { -} - -func (*UnimplementedHealthServer) Check(context.Context, *HealthCheckRequest) (*HealthCheckResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Check not implemented") -} -func (*UnimplementedHealthServer) Watch(*HealthCheckRequest, Health_WatchServer) error { - return status.Errorf(codes.Unimplemented, "method Watch not implemented") -} - -func RegisterHealthServer(s *grpc.Server, srv HealthServer) { - s.RegisterService(&_Health_serviceDesc, srv) -} - -func _Health_Check_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(HealthCheckRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(HealthServer).Check(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpc.health.v1.Health/Check", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(HealthServer).Check(ctx, req.(*HealthCheckRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Health_Watch_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(HealthCheckRequest) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(HealthServer).Watch(m, &healthWatchServer{stream}) -} - -type Health_WatchServer interface { - Send(*HealthCheckResponse) error - grpc.ServerStream -} - -type healthWatchServer struct { - grpc.ServerStream -} - -func (x *healthWatchServer) Send(m *HealthCheckResponse) error { - return x.ServerStream.SendMsg(m) -} - -var _Health_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.health.v1.Health", - HandlerType: (*HealthServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Check", - Handler: _Health_Check_Handler, - }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "Watch", - Handler: _Health_Watch_Handler, - ServerStreams: true, - }, - }, - Metadata: "grpc/health/v1/health.proto", -} diff --git a/internal/binarylog/binarylog_end2end_test.go b/internal/binarylog/binarylog_end2end_test.go index 999bd90f..bdce754a 100644 --- a/internal/binarylog/binarylog_end2end_test.go +++ b/internal/binarylog/binarylog_end2end_test.go @@ -115,10 +115,11 @@ var ( ) type testServer struct { - testpb.UnimplementedTestServiceServer te *test } +var _ testpb.UnstableTestServiceService = (*testServer)(nil) + func (s *testServer) UnaryCall(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { md, ok := metadata.FromIncomingContext(ctx) if ok { @@ -216,7 +217,7 @@ func (s *testServer) ServerStreamCall(in *testpb.SimpleRequest, stream testpb.Te type test struct { t *testing.T - testServer testpb.TestServiceServer // nil means none + testService *testpb.TestServiceService // nil means none // srv and srvAddr are set once startServer is called. srv *grpc.Server srvAddr string // Server IP without port. @@ -271,8 +272,8 @@ func (lw *listenerWrapper) Accept() (net.Conn, error) { // startServer starts a gRPC server listening. Callers should defer a // call to te.tearDown to clean up. -func (te *test) startServer(ts testpb.TestServiceServer) { - te.testServer = ts +func (te *test) startServer(ts *testpb.TestServiceService) { + te.testService = ts lis, err := net.Listen("tcp", "localhost:0") lis = &listenerWrapper{ @@ -286,8 +287,8 @@ func (te *test) startServer(ts testpb.TestServiceServer) { var opts []grpc.ServerOption s := grpc.NewServer(opts...) te.srv = s - if te.testServer != nil { - testpb.RegisterTestServiceServer(s, te.testServer) + if te.testService != nil { + testpb.RegisterTestServiceService(s, te.testService) } go s.Serve(lis) @@ -783,7 +784,7 @@ func (ed *expectedData) toServerLogEntries() []*pb.GrpcLogEntry { func runRPCs(t *testing.T, tc *testConfig, cc *rpcConfig) *expectedData { te := newTest(t, tc) - te.startServer(&testServer{te: te}) + te.startServer(testpb.NewTestServiceService(&testServer{te: te})) defer te.tearDown() expect := &expectedData{ diff --git a/interop/alts/server/server.go b/interop/alts/server/server.go index 0d0f375a..0ac7678a 100644 --- a/interop/alts/server/server.go +++ b/interop/alts/server/server.go @@ -64,7 +64,7 @@ func main() { } altsTC := alts.NewServerCreds(opts) grpcServer := grpc.NewServer(grpc.Creds(altsTC), grpc.InTapHandle(authz)) - testpb.RegisterTestServiceServer(grpcServer, interop.NewTestServer()) + testpb.RegisterTestServiceService(grpcServer, interop.NewTestServer()) grpcServer.Serve(lis) } diff --git a/interop/grpc_testing/test_grpc.pb.go b/interop/grpc_testing/test_grpc.pb.go index 07b555a3..d71f6d2a 100644 --- a/interop/grpc_testing/test_grpc.pb.go +++ b/interop/grpc_testing/test_grpc.pb.go @@ -11,7 +11,7 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 // TestServiceClient is the client API for TestService service. // @@ -47,6 +47,10 @@ func NewTestServiceClient(cc grpc.ClientConnInterface) TestServiceClient { return &testServiceClient{cc} } +var testServiceEmptyCallStreamDesc = &grpc.StreamDesc{ + StreamName: "EmptyCall", +} + func (c *testServiceClient) EmptyCall(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/grpc.testing.TestService/EmptyCall", in, out, opts...) @@ -56,6 +60,10 @@ func (c *testServiceClient) EmptyCall(ctx context.Context, in *Empty, opts ...gr return out, nil } +var testServiceUnaryCallStreamDesc = &grpc.StreamDesc{ + StreamName: "UnaryCall", +} + func (c *testServiceClient) UnaryCall(ctx context.Context, in *SimpleRequest, opts ...grpc.CallOption) (*SimpleResponse, error) { out := new(SimpleResponse) err := c.cc.Invoke(ctx, "/grpc.testing.TestService/UnaryCall", in, out, opts...) @@ -65,8 +73,13 @@ func (c *testServiceClient) UnaryCall(ctx context.Context, in *SimpleRequest, op return out, nil } +var testServiceStreamingOutputCallStreamDesc = &grpc.StreamDesc{ + StreamName: "StreamingOutputCall", + ServerStreams: true, +} + func (c *testServiceClient) StreamingOutputCall(ctx context.Context, in *StreamingOutputCallRequest, opts ...grpc.CallOption) (TestService_StreamingOutputCallClient, error) { - stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[0], "/grpc.testing.TestService/StreamingOutputCall", opts...) + stream, err := c.cc.NewStream(ctx, testServiceStreamingOutputCallStreamDesc, "/grpc.testing.TestService/StreamingOutputCall", opts...) if err != nil { return nil, err } @@ -97,8 +110,13 @@ func (x *testServiceStreamingOutputCallClient) Recv() (*StreamingOutputCallRespo return m, nil } +var testServiceStreamingInputCallStreamDesc = &grpc.StreamDesc{ + StreamName: "StreamingInputCall", + ClientStreams: true, +} + func (c *testServiceClient) StreamingInputCall(ctx context.Context, opts ...grpc.CallOption) (TestService_StreamingInputCallClient, error) { - stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[1], "/grpc.testing.TestService/StreamingInputCall", opts...) + stream, err := c.cc.NewStream(ctx, testServiceStreamingInputCallStreamDesc, "/grpc.testing.TestService/StreamingInputCall", opts...) if err != nil { return nil, err } @@ -131,8 +149,14 @@ func (x *testServiceStreamingInputCallClient) CloseAndRecv() (*StreamingInputCal return m, nil } +var testServiceFullDuplexCallStreamDesc = &grpc.StreamDesc{ + StreamName: "FullDuplexCall", + ServerStreams: true, + ClientStreams: true, +} + func (c *testServiceClient) FullDuplexCall(ctx context.Context, opts ...grpc.CallOption) (TestService_FullDuplexCallClient, error) { - stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[2], "/grpc.testing.TestService/FullDuplexCall", opts...) + stream, err := c.cc.NewStream(ctx, testServiceFullDuplexCallStreamDesc, "/grpc.testing.TestService/FullDuplexCall", opts...) if err != nil { return nil, err } @@ -162,8 +186,14 @@ func (x *testServiceFullDuplexCallClient) Recv() (*StreamingOutputCallResponse, return m, nil } +var testServiceHalfDuplexCallStreamDesc = &grpc.StreamDesc{ + StreamName: "HalfDuplexCall", + ServerStreams: true, + ClientStreams: true, +} + func (c *testServiceClient) HalfDuplexCall(ctx context.Context, opts ...grpc.CallOption) (TestService_HalfDuplexCallClient, error) { - stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[3], "/grpc.testing.TestService/HalfDuplexCall", opts...) + stream, err := c.cc.NewStream(ctx, testServiceHalfDuplexCallStreamDesc, "/grpc.testing.TestService/HalfDuplexCall", opts...) if err != nil { return nil, err } @@ -193,101 +223,100 @@ func (x *testServiceHalfDuplexCallClient) Recv() (*StreamingOutputCallResponse, return m, nil } -// TestServiceServer is the server API for TestService service. -// All implementations should embed UnimplementedTestServiceServer -// for forward compatibility -type TestServiceServer interface { +// TestServiceService is the service API for TestService service. +// Fields should be assigned to their respective handler implementations only before +// RegisterTestServiceService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type TestServiceService struct { // One empty request followed by one empty response. - EmptyCall(context.Context, *Empty) (*Empty, error) + EmptyCall func(context.Context, *Empty) (*Empty, error) // One request followed by one response. // The server returns the client payload as-is. - UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) + UnaryCall func(context.Context, *SimpleRequest) (*SimpleResponse, error) // One request followed by a sequence of responses (streamed download). // The server returns the payload with client desired type and sizes. - StreamingOutputCall(*StreamingOutputCallRequest, TestService_StreamingOutputCallServer) error + StreamingOutputCall func(*StreamingOutputCallRequest, TestService_StreamingOutputCallServer) error // A sequence of requests followed by one response (streamed upload). // The server returns the aggregated size of client payload as the result. - StreamingInputCall(TestService_StreamingInputCallServer) error + StreamingInputCall func(TestService_StreamingInputCallServer) error // A sequence of requests with each request served by the server immediately. // As one request could lead to multiple responses, this interface // demonstrates the idea of full duplexing. - FullDuplexCall(TestService_FullDuplexCallServer) error + FullDuplexCall func(TestService_FullDuplexCallServer) error // A sequence of requests followed by a sequence of responses. // The server buffers all the client requests and then serves them in order. A // stream of responses are returned to the client when the server starts with // first request. - HalfDuplexCall(TestService_HalfDuplexCallServer) error + HalfDuplexCall func(TestService_HalfDuplexCallServer) error } -// UnimplementedTestServiceServer should be embedded to have forward compatible implementations. -type UnimplementedTestServiceServer struct { -} - -func (*UnimplementedTestServiceServer) EmptyCall(context.Context, *Empty) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method EmptyCall not implemented") -} -func (*UnimplementedTestServiceServer) UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UnaryCall not implemented") -} -func (*UnimplementedTestServiceServer) StreamingOutputCall(*StreamingOutputCallRequest, TestService_StreamingOutputCallServer) error { - return status.Errorf(codes.Unimplemented, "method StreamingOutputCall not implemented") -} -func (*UnimplementedTestServiceServer) StreamingInputCall(TestService_StreamingInputCallServer) error { - return status.Errorf(codes.Unimplemented, "method StreamingInputCall not implemented") -} -func (*UnimplementedTestServiceServer) FullDuplexCall(TestService_FullDuplexCallServer) error { - return status.Errorf(codes.Unimplemented, "method FullDuplexCall not implemented") -} -func (*UnimplementedTestServiceServer) HalfDuplexCall(TestService_HalfDuplexCallServer) error { - return status.Errorf(codes.Unimplemented, "method HalfDuplexCall not implemented") -} - -func RegisterTestServiceServer(s *grpc.Server, srv TestServiceServer) { - s.RegisterService(&_TestService_serviceDesc, srv) -} - -func _TestService_EmptyCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func (s *TestServiceService) emptyCall(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.EmptyCall == nil { + return nil, status.Errorf(codes.Unimplemented, "method EmptyCall not implemented") + } in := new(Empty) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(TestServiceServer).EmptyCall(ctx, in) + return s.EmptyCall(ctx, in) } info := &grpc.UnaryServerInfo{ - Server: srv, + Server: s, FullMethod: "/grpc.testing.TestService/EmptyCall", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).EmptyCall(ctx, req.(*Empty)) + return s.EmptyCall(ctx, req.(*Empty)) } return interceptor(ctx, in, info, handler) } - -func _TestService_UnaryCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func (s *TestServiceService) unaryCall(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.UnaryCall == nil { + return nil, status.Errorf(codes.Unimplemented, "method UnaryCall not implemented") + } in := new(SimpleRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(TestServiceServer).UnaryCall(ctx, in) + return s.UnaryCall(ctx, in) } info := &grpc.UnaryServerInfo{ - Server: srv, + Server: s, FullMethod: "/grpc.testing.TestService/UnaryCall", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).UnaryCall(ctx, req.(*SimpleRequest)) + return s.UnaryCall(ctx, req.(*SimpleRequest)) } return interceptor(ctx, in, info, handler) } - -func _TestService_StreamingOutputCall_Handler(srv interface{}, stream grpc.ServerStream) error { +func (s *TestServiceService) streamingOutputCall(_ interface{}, stream grpc.ServerStream) error { + if s.StreamingOutputCall == nil { + return status.Errorf(codes.Unimplemented, "method StreamingOutputCall not implemented") + } m := new(StreamingOutputCallRequest) if err := stream.RecvMsg(m); err != nil { return err } - return srv.(TestServiceServer).StreamingOutputCall(m, &testServiceStreamingOutputCallServer{stream}) + return s.StreamingOutputCall(m, &testServiceStreamingOutputCallServer{stream}) +} +func (s *TestServiceService) streamingInputCall(_ interface{}, stream grpc.ServerStream) error { + if s.StreamingInputCall == nil { + return status.Errorf(codes.Unimplemented, "method StreamingInputCall not implemented") + } + return s.StreamingInputCall(&testServiceStreamingInputCallServer{stream}) +} +func (s *TestServiceService) fullDuplexCall(_ interface{}, stream grpc.ServerStream) error { + if s.FullDuplexCall == nil { + return status.Errorf(codes.Unimplemented, "method FullDuplexCall not implemented") + } + return s.FullDuplexCall(&testServiceFullDuplexCallServer{stream}) +} +func (s *TestServiceService) halfDuplexCall(_ interface{}, stream grpc.ServerStream) error { + if s.HalfDuplexCall == nil { + return status.Errorf(codes.Unimplemented, "method HalfDuplexCall not implemented") + } + return s.HalfDuplexCall(&testServiceHalfDuplexCallServer{stream}) } type TestService_StreamingOutputCallServer interface { @@ -303,10 +332,6 @@ func (x *testServiceStreamingOutputCallServer) Send(m *StreamingOutputCallRespon return x.ServerStream.SendMsg(m) } -func _TestService_StreamingInputCall_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(TestServiceServer).StreamingInputCall(&testServiceStreamingInputCallServer{stream}) -} - type TestService_StreamingInputCallServer interface { SendAndClose(*StreamingInputCallResponse) error Recv() (*StreamingInputCallRequest, error) @@ -329,10 +354,6 @@ func (x *testServiceStreamingInputCallServer) Recv() (*StreamingInputCallRequest return m, nil } -func _TestService_FullDuplexCall_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(TestServiceServer).FullDuplexCall(&testServiceFullDuplexCallServer{stream}) -} - type TestService_FullDuplexCallServer interface { Send(*StreamingOutputCallResponse) error Recv() (*StreamingOutputCallRequest, error) @@ -355,10 +376,6 @@ func (x *testServiceFullDuplexCallServer) Recv() (*StreamingOutputCallRequest, e return m, nil } -func _TestService_HalfDuplexCall_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(TestServiceServer).HalfDuplexCall(&testServiceHalfDuplexCallServer{stream}) -} - type TestService_HalfDuplexCallServer interface { Send(*StreamingOutputCallResponse) error Recv() (*StreamingOutputCallRequest, error) @@ -381,44 +398,116 @@ func (x *testServiceHalfDuplexCallServer) Recv() (*StreamingOutputCallRequest, e return m, nil } -var _TestService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.testing.TestService", - HandlerType: (*TestServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "EmptyCall", - Handler: _TestService_EmptyCall_Handler, +// RegisterTestServiceService registers a service implementation with a gRPC server. +func RegisterTestServiceService(s grpc.ServiceRegistrar, srv *TestServiceService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.testing.TestService", + Methods: []grpc.MethodDesc{ + { + MethodName: "EmptyCall", + Handler: srv.emptyCall, + }, + { + MethodName: "UnaryCall", + Handler: srv.unaryCall, + }, }, - { - MethodName: "UnaryCall", - Handler: _TestService_UnaryCall_Handler, + Streams: []grpc.StreamDesc{ + { + StreamName: "StreamingOutputCall", + Handler: srv.streamingOutputCall, + ServerStreams: true, + }, + { + StreamName: "StreamingInputCall", + Handler: srv.streamingInputCall, + ClientStreams: true, + }, + { + StreamName: "FullDuplexCall", + Handler: srv.fullDuplexCall, + ServerStreams: true, + ClientStreams: true, + }, + { + StreamName: "HalfDuplexCall", + Handler: srv.halfDuplexCall, + ServerStreams: true, + ClientStreams: true, + }, }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "StreamingOutputCall", - Handler: _TestService_StreamingOutputCall_Handler, - ServerStreams: true, - }, - { - StreamName: "StreamingInputCall", - Handler: _TestService_StreamingInputCall_Handler, - ClientStreams: true, - }, - { - StreamName: "FullDuplexCall", - Handler: _TestService_FullDuplexCall_Handler, - ServerStreams: true, - ClientStreams: true, - }, - { - StreamName: "HalfDuplexCall", - Handler: _TestService_HalfDuplexCall_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "interop/grpc_testing/test.proto", + Metadata: "interop/grpc_testing/test.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewTestServiceService creates a new TestServiceService containing the +// implemented methods of the TestService service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewTestServiceService(s interface{}) *TestServiceService { + ns := &TestServiceService{} + if h, ok := s.(interface { + EmptyCall(context.Context, *Empty) (*Empty, error) + }); ok { + ns.EmptyCall = h.EmptyCall + } + if h, ok := s.(interface { + UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) + }); ok { + ns.UnaryCall = h.UnaryCall + } + if h, ok := s.(interface { + StreamingOutputCall(*StreamingOutputCallRequest, TestService_StreamingOutputCallServer) error + }); ok { + ns.StreamingOutputCall = h.StreamingOutputCall + } + if h, ok := s.(interface { + StreamingInputCall(TestService_StreamingInputCallServer) error + }); ok { + ns.StreamingInputCall = h.StreamingInputCall + } + if h, ok := s.(interface { + FullDuplexCall(TestService_FullDuplexCallServer) error + }); ok { + ns.FullDuplexCall = h.FullDuplexCall + } + if h, ok := s.(interface { + HalfDuplexCall(TestService_HalfDuplexCallServer) error + }); ok { + ns.HalfDuplexCall = h.HalfDuplexCall + } + return ns +} + +// UnstableTestServiceService is the service API for TestService service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableTestServiceService interface { + // One empty request followed by one empty response. + EmptyCall(context.Context, *Empty) (*Empty, error) + // One request followed by one response. + // The server returns the client payload as-is. + UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) + // One request followed by a sequence of responses (streamed download). + // The server returns the payload with client desired type and sizes. + StreamingOutputCall(*StreamingOutputCallRequest, TestService_StreamingOutputCallServer) error + // A sequence of requests followed by one response (streamed upload). + // The server returns the aggregated size of client payload as the result. + StreamingInputCall(TestService_StreamingInputCallServer) error + // A sequence of requests with each request served by the server immediately. + // As one request could lead to multiple responses, this interface + // demonstrates the idea of full duplexing. + FullDuplexCall(TestService_FullDuplexCallServer) error + // A sequence of requests followed by a sequence of responses. + // The server buffers all the client requests and then serves them in order. A + // stream of responses are returned to the client when the server starts with + // first request. + HalfDuplexCall(TestService_HalfDuplexCallServer) error } // UnimplementedServiceClient is the client API for UnimplementedService service. @@ -437,6 +526,10 @@ func NewUnimplementedServiceClient(cc grpc.ClientConnInterface) UnimplementedSer return &unimplementedServiceClient{cc} } +var unimplementedServiceUnimplementedCallStreamDesc = &grpc.StreamDesc{ + StreamName: "UnimplementedCall", +} + func (c *unimplementedServiceClient) UnimplementedCall(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/grpc.testing.UnimplementedService/UnimplementedCall", in, out, opts...) @@ -446,55 +539,76 @@ func (c *unimplementedServiceClient) UnimplementedCall(ctx context.Context, in * return out, nil } -// UnimplementedServiceServer is the server API for UnimplementedService service. -// All implementations should embed UnimplementedUnimplementedServiceServer -// for forward compatibility -type UnimplementedServiceServer interface { +// UnimplementedServiceService is the service API for UnimplementedService service. +// Fields should be assigned to their respective handler implementations only before +// RegisterUnimplementedServiceService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type UnimplementedServiceService struct { // A call that no server should implement - UnimplementedCall(context.Context, *Empty) (*Empty, error) + UnimplementedCall func(context.Context, *Empty) (*Empty, error) } -// UnimplementedUnimplementedServiceServer should be embedded to have forward compatible implementations. -type UnimplementedUnimplementedServiceServer struct { -} - -func (*UnimplementedUnimplementedServiceServer) UnimplementedCall(context.Context, *Empty) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method UnimplementedCall not implemented") -} - -func RegisterUnimplementedServiceServer(s *grpc.Server, srv UnimplementedServiceServer) { - s.RegisterService(&_UnimplementedService_serviceDesc, srv) -} - -func _UnimplementedService_UnimplementedCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func (s *UnimplementedServiceService) unimplementedCall(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.UnimplementedCall == nil { + return nil, status.Errorf(codes.Unimplemented, "method UnimplementedCall not implemented") + } in := new(Empty) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(UnimplementedServiceServer).UnimplementedCall(ctx, in) + return s.UnimplementedCall(ctx, in) } info := &grpc.UnaryServerInfo{ - Server: srv, + Server: s, FullMethod: "/grpc.testing.UnimplementedService/UnimplementedCall", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(UnimplementedServiceServer).UnimplementedCall(ctx, req.(*Empty)) + return s.UnimplementedCall(ctx, req.(*Empty)) } return interceptor(ctx, in, info, handler) } -var _UnimplementedService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.testing.UnimplementedService", - HandlerType: (*UnimplementedServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "UnimplementedCall", - Handler: _UnimplementedService_UnimplementedCall_Handler, +// RegisterUnimplementedServiceService registers a service implementation with a gRPC server. +func RegisterUnimplementedServiceService(s grpc.ServiceRegistrar, srv *UnimplementedServiceService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.testing.UnimplementedService", + Methods: []grpc.MethodDesc{ + { + MethodName: "UnimplementedCall", + Handler: srv.unimplementedCall, + }, }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "interop/grpc_testing/test.proto", + Streams: []grpc.StreamDesc{}, + Metadata: "interop/grpc_testing/test.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewUnimplementedServiceService creates a new UnimplementedServiceService containing the +// implemented methods of the UnimplementedService service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewUnimplementedServiceService(s interface{}) *UnimplementedServiceService { + ns := &UnimplementedServiceService{} + if h, ok := s.(interface { + UnimplementedCall(context.Context, *Empty) (*Empty, error) + }); ok { + ns.UnimplementedCall = h.UnimplementedCall + } + return ns +} + +// UnstableUnimplementedServiceService is the service API for UnimplementedService service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableUnimplementedServiceService interface { + // A call that no server should implement + UnimplementedCall(context.Context, *Empty) (*Empty, error) } // LoadBalancerStatsServiceClient is the client API for LoadBalancerStatsService service. @@ -513,6 +627,10 @@ func NewLoadBalancerStatsServiceClient(cc grpc.ClientConnInterface) LoadBalancer return &loadBalancerStatsServiceClient{cc} } +var loadBalancerStatsServiceGetClientStatsStreamDesc = &grpc.StreamDesc{ + StreamName: "GetClientStats", +} + func (c *loadBalancerStatsServiceClient) GetClientStats(ctx context.Context, in *LoadBalancerStatsRequest, opts ...grpc.CallOption) (*LoadBalancerStatsResponse, error) { out := new(LoadBalancerStatsResponse) err := c.cc.Invoke(ctx, "/grpc.testing.LoadBalancerStatsService/GetClientStats", in, out, opts...) @@ -522,53 +640,74 @@ func (c *loadBalancerStatsServiceClient) GetClientStats(ctx context.Context, in return out, nil } -// LoadBalancerStatsServiceServer is the server API for LoadBalancerStatsService service. -// All implementations should embed UnimplementedLoadBalancerStatsServiceServer -// for forward compatibility -type LoadBalancerStatsServiceServer interface { +// LoadBalancerStatsServiceService is the service API for LoadBalancerStatsService service. +// Fields should be assigned to their respective handler implementations only before +// RegisterLoadBalancerStatsServiceService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type LoadBalancerStatsServiceService struct { // Gets the backend distribution for RPCs sent by a test client. - GetClientStats(context.Context, *LoadBalancerStatsRequest) (*LoadBalancerStatsResponse, error) + GetClientStats func(context.Context, *LoadBalancerStatsRequest) (*LoadBalancerStatsResponse, error) } -// UnimplementedLoadBalancerStatsServiceServer should be embedded to have forward compatible implementations. -type UnimplementedLoadBalancerStatsServiceServer struct { -} - -func (*UnimplementedLoadBalancerStatsServiceServer) GetClientStats(context.Context, *LoadBalancerStatsRequest) (*LoadBalancerStatsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetClientStats not implemented") -} - -func RegisterLoadBalancerStatsServiceServer(s *grpc.Server, srv LoadBalancerStatsServiceServer) { - s.RegisterService(&_LoadBalancerStatsService_serviceDesc, srv) -} - -func _LoadBalancerStatsService_GetClientStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func (s *LoadBalancerStatsServiceService) getClientStats(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.GetClientStats == nil { + return nil, status.Errorf(codes.Unimplemented, "method GetClientStats not implemented") + } in := new(LoadBalancerStatsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(LoadBalancerStatsServiceServer).GetClientStats(ctx, in) + return s.GetClientStats(ctx, in) } info := &grpc.UnaryServerInfo{ - Server: srv, + Server: s, FullMethod: "/grpc.testing.LoadBalancerStatsService/GetClientStats", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(LoadBalancerStatsServiceServer).GetClientStats(ctx, req.(*LoadBalancerStatsRequest)) + return s.GetClientStats(ctx, req.(*LoadBalancerStatsRequest)) } return interceptor(ctx, in, info, handler) } -var _LoadBalancerStatsService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.testing.LoadBalancerStatsService", - HandlerType: (*LoadBalancerStatsServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "GetClientStats", - Handler: _LoadBalancerStatsService_GetClientStats_Handler, +// RegisterLoadBalancerStatsServiceService registers a service implementation with a gRPC server. +func RegisterLoadBalancerStatsServiceService(s grpc.ServiceRegistrar, srv *LoadBalancerStatsServiceService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.testing.LoadBalancerStatsService", + Methods: []grpc.MethodDesc{ + { + MethodName: "GetClientStats", + Handler: srv.getClientStats, + }, }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "interop/grpc_testing/test.proto", + Streams: []grpc.StreamDesc{}, + Metadata: "interop/grpc_testing/test.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewLoadBalancerStatsServiceService creates a new LoadBalancerStatsServiceService containing the +// implemented methods of the LoadBalancerStatsService service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewLoadBalancerStatsServiceService(s interface{}) *LoadBalancerStatsServiceService { + ns := &LoadBalancerStatsServiceService{} + if h, ok := s.(interface { + GetClientStats(context.Context, *LoadBalancerStatsRequest) (*LoadBalancerStatsResponse, error) + }); ok { + ns.GetClientStats = h.GetClientStats + } + return ns +} + +// UnstableLoadBalancerStatsServiceService is the service API for LoadBalancerStatsService service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableLoadBalancerStatsServiceService interface { + // Gets the backend distribution for RPCs sent by a test client. + GetClientStats(context.Context, *LoadBalancerStatsRequest) (*LoadBalancerStatsResponse, error) } diff --git a/interop/server/server.go b/interop/server/server.go index c70e450b..662fb296 100644 --- a/interop/server/server.go +++ b/interop/server/server.go @@ -76,6 +76,6 @@ func main() { opts = append(opts, grpc.Creds(altsTC)) } server := grpc.NewServer(opts...) - testpb.RegisterTestServiceServer(server, interop.NewTestServer()) + testpb.RegisterTestServiceService(server, interop.NewTestServer()) server.Serve(lis) } diff --git a/interop/test_utils.go b/interop/test_utils.go index 7e3aaa95..7a42116e 100644 --- a/interop/test_utils.go +++ b/interop/test_utils.go @@ -673,13 +673,11 @@ func DoPickFirstUnary(tc testpb.TestServiceClient) { } } -type testServer struct { - testpb.UnimplementedTestServiceServer -} +type testServer struct{} // NewTestServer creates a test server for test service. -func NewTestServer() testpb.TestServiceServer { - return &testServer{} +func NewTestServer() *testpb.TestServiceService { + return testpb.NewTestServiceService(testpb.UnstableTestServiceService(&testServer{})) } func (s *testServer) EmptyCall(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { diff --git a/interop/xds/client/client.go b/interop/xds/client/client.go index b119bcd2..46621906 100644 --- a/interop/xds/client/client.go +++ b/interop/xds/client/client.go @@ -95,10 +95,6 @@ var ( logger = grpclog.Component("interop") ) -type statsService struct { - testpb.UnimplementedLoadBalancerStatsServiceServer -} - func hasRPCSucceeded() bool { return atomic.LoadUint32(&rpcSucceeded) > 0 } @@ -111,7 +107,7 @@ func setRPCSucceeded() { // and return the distribution of remote peers. This is essentially a clientside // LB reporting mechanism that is designed to be queried by an external test // driver when verifying that the client is distributing RPCs as expected. -func (s *statsService) GetClientStats(ctx context.Context, in *testpb.LoadBalancerStatsRequest) (*testpb.LoadBalancerStatsResponse, error) { +func getClientStats(ctx context.Context, in *testpb.LoadBalancerStatsRequest) (*testpb.LoadBalancerStatsResponse, error) { mu.Lock() watcherKey := statsWatcherKey{currentRequestID, currentRequestID + in.GetNumRpcs()} watcher, ok := watchers[watcherKey] @@ -226,7 +222,7 @@ func main() { } s := grpc.NewServer() defer s.Stop() - testpb.RegisterLoadBalancerStatsServiceServer(s, &statsService{}) + testpb.RegisterLoadBalancerStatsServiceService(s, &testpb.LoadBalancerStatsServiceService{GetClientStats: getClientStats}) go s.Serve(lis) clients := make([]testpb.TestServiceClient, *numChannels) diff --git a/interop/xds/server/server.go b/interop/xds/server/server.go index 45b84488..8d2a6248 100644 --- a/interop/xds/server/server.go +++ b/interop/xds/server/server.go @@ -49,16 +49,12 @@ func getHostname() string { return hostname } -type server struct { - testpb.UnimplementedTestServiceServer -} - -func (s *server) EmptyCall(ctx context.Context, _ *testpb.Empty) (*testpb.Empty, error) { +func emptyCall(ctx context.Context, _ *testpb.Empty) (*testpb.Empty, error) { grpc.SetHeader(ctx, metadata.Pairs("hostname", hostname)) return &testpb.Empty{}, nil } -func (s *server) UnaryCall(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { +func unaryCall(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { grpc.SetHeader(ctx, metadata.Pairs("hostname", hostname)) return &testpb.SimpleResponse{ServerId: *serverID, Hostname: hostname}, nil } @@ -71,6 +67,6 @@ func main() { logger.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() - testpb.RegisterTestServiceServer(s, &server{}) + testpb.RegisterTestServiceService(s, &testpb.TestServiceService{EmptyCall: emptyCall, UnaryCall: unaryCall}) s.Serve(lis) } diff --git a/profiling/proto/service.pb.go b/profiling/proto/service.pb.go index 831a6272..90f02824 100644 --- a/profiling/proto/service.pb.go +++ b/profiling/proto/service.pb.go @@ -4,8 +4,12 @@ package proto import ( + context "context" fmt "fmt" proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" math "math" ) @@ -362,3 +366,125 @@ var fileDescriptor_e1ab2aa17b47c6fb = []byte{ 0x95, 0xbb, 0x2e, 0xf9, 0xc9, 0xfd, 0xaf, 0x42, 0xfa, 0xbc, 0xf9, 0x13, 0x00, 0x00, 0xff, 0xff, 0x5d, 0x47, 0x09, 0xa9, 0x19, 0x03, 0x00, 0x00, } + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// 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.SupportPackageIsVersion6 + +// ProfilingClient is the client API for Profiling service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type ProfilingClient interface { + // Enable allows users to toggle profiling on and off remotely. + Enable(ctx context.Context, in *EnableRequest, opts ...grpc.CallOption) (*EnableResponse, error) + // GetStreamStats is used to retrieve an array of stream-level stats from a + // gRPC client/server. + GetStreamStats(ctx context.Context, in *GetStreamStatsRequest, opts ...grpc.CallOption) (*GetStreamStatsResponse, error) +} + +type profilingClient struct { + cc grpc.ClientConnInterface +} + +func NewProfilingClient(cc grpc.ClientConnInterface) ProfilingClient { + return &profilingClient{cc} +} + +func (c *profilingClient) Enable(ctx context.Context, in *EnableRequest, opts ...grpc.CallOption) (*EnableResponse, error) { + out := new(EnableResponse) + err := c.cc.Invoke(ctx, "/grpc.go.profiling.v1alpha.Profiling/Enable", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *profilingClient) GetStreamStats(ctx context.Context, in *GetStreamStatsRequest, opts ...grpc.CallOption) (*GetStreamStatsResponse, error) { + out := new(GetStreamStatsResponse) + err := c.cc.Invoke(ctx, "/grpc.go.profiling.v1alpha.Profiling/GetStreamStats", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ProfilingServer is the server API for Profiling service. +type ProfilingServer interface { + // Enable allows users to toggle profiling on and off remotely. + Enable(context.Context, *EnableRequest) (*EnableResponse, error) + // GetStreamStats is used to retrieve an array of stream-level stats from a + // gRPC client/server. + GetStreamStats(context.Context, *GetStreamStatsRequest) (*GetStreamStatsResponse, error) +} + +// UnimplementedProfilingServer can be embedded to have forward compatible implementations. +type UnimplementedProfilingServer struct { +} + +func (*UnimplementedProfilingServer) Enable(ctx context.Context, req *EnableRequest) (*EnableResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Enable not implemented") +} +func (*UnimplementedProfilingServer) GetStreamStats(ctx context.Context, req *GetStreamStatsRequest) (*GetStreamStatsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetStreamStats not implemented") +} + +func RegisterProfilingServer(s *grpc.Server, srv ProfilingServer) { + s.RegisterService(&_Profiling_serviceDesc, srv) +} + +func _Profiling_Enable_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(EnableRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProfilingServer).Enable(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.go.profiling.v1alpha.Profiling/Enable", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProfilingServer).Enable(ctx, req.(*EnableRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Profiling_GetStreamStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetStreamStatsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ProfilingServer).GetStreamStats(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.go.profiling.v1alpha.Profiling/GetStreamStats", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ProfilingServer).GetStreamStats(ctx, req.(*GetStreamStatsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _Profiling_serviceDesc = grpc.ServiceDesc{ + ServiceName: "grpc.go.profiling.v1alpha.Profiling", + HandlerType: (*ProfilingServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Enable", + Handler: _Profiling_Enable_Handler, + }, + { + MethodName: "GetStreamStats", + Handler: _Profiling_GetStreamStats_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "profiling/proto/service.proto", +} diff --git a/profiling/proto/service_grpc.pb.go b/profiling/proto/service_grpc.pb.go index aed8d587..e32cbb40 100644 --- a/profiling/proto/service_grpc.pb.go +++ b/profiling/proto/service_grpc.pb.go @@ -11,120 +11,111 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 -// ProfilingClient is the client API for Profiling 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 ProfilingClient interface { +// ProfilingService is the service API for Profiling service. +// Fields should be assigned to their respective handler implementations only before +// RegisterProfilingService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type ProfilingService struct { // Enable allows users to toggle profiling on and off remotely. - Enable(ctx context.Context, in *EnableRequest, opts ...grpc.CallOption) (*EnableResponse, error) + Enable func(context.Context, *EnableRequest) (*EnableResponse, error) // GetStreamStats is used to retrieve an array of stream-level stats from a // gRPC client/server. - GetStreamStats(ctx context.Context, in *GetStreamStatsRequest, opts ...grpc.CallOption) (*GetStreamStatsResponse, error) + GetStreamStats func(context.Context, *GetStreamStatsRequest) (*GetStreamStatsResponse, error) } -type profilingClient struct { - cc grpc.ClientConnInterface -} - -func NewProfilingClient(cc grpc.ClientConnInterface) ProfilingClient { - return &profilingClient{cc} -} - -func (c *profilingClient) Enable(ctx context.Context, in *EnableRequest, opts ...grpc.CallOption) (*EnableResponse, error) { - out := new(EnableResponse) - err := c.cc.Invoke(ctx, "/grpc.go.profiling.v1alpha.Profiling/Enable", in, out, opts...) - if err != nil { +func (s *ProfilingService) enable(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.Enable == nil { + return nil, status.Errorf(codes.Unimplemented, "method Enable not implemented") + } + in := new(EnableRequest) + if err := dec(in); err != nil { return nil, err } - return out, nil + if interceptor == nil { + return s.Enable(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: s, + FullMethod: "/grpc.go.profiling.v1alpha.Profiling/Enable", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return s.Enable(ctx, req.(*EnableRequest)) + } + return interceptor(ctx, in, info, handler) } - -func (c *profilingClient) GetStreamStats(ctx context.Context, in *GetStreamStatsRequest, opts ...grpc.CallOption) (*GetStreamStatsResponse, error) { - out := new(GetStreamStatsResponse) - err := c.cc.Invoke(ctx, "/grpc.go.profiling.v1alpha.Profiling/GetStreamStats", in, out, opts...) - if err != nil { +func (s *ProfilingService) getStreamStats(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.GetStreamStats == nil { + return nil, status.Errorf(codes.Unimplemented, "method GetStreamStats not implemented") + } + in := new(GetStreamStatsRequest) + if err := dec(in); err != nil { return nil, err } - return out, nil + if interceptor == nil { + return s.GetStreamStats(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: s, + FullMethod: "/grpc.go.profiling.v1alpha.Profiling/GetStreamStats", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return s.GetStreamStats(ctx, req.(*GetStreamStatsRequest)) + } + return interceptor(ctx, in, info, handler) } -// ProfilingServer is the server API for Profiling service. -// All implementations should embed UnimplementedProfilingServer -// for forward compatibility -type ProfilingServer interface { +// RegisterProfilingService registers a service implementation with a gRPC server. +func RegisterProfilingService(s grpc.ServiceRegistrar, srv *ProfilingService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.go.profiling.v1alpha.Profiling", + Methods: []grpc.MethodDesc{ + { + MethodName: "Enable", + Handler: srv.enable, + }, + { + MethodName: "GetStreamStats", + Handler: srv.getStreamStats, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "profiling/proto/service.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewProfilingService creates a new ProfilingService containing the +// implemented methods of the Profiling service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewProfilingService(s interface{}) *ProfilingService { + ns := &ProfilingService{} + if h, ok := s.(interface { + Enable(context.Context, *EnableRequest) (*EnableResponse, error) + }); ok { + ns.Enable = h.Enable + } + if h, ok := s.(interface { + GetStreamStats(context.Context, *GetStreamStatsRequest) (*GetStreamStatsResponse, error) + }); ok { + ns.GetStreamStats = h.GetStreamStats + } + return ns +} + +// UnstableProfilingService is the service API for Profiling service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableProfilingService interface { // Enable allows users to toggle profiling on and off remotely. Enable(context.Context, *EnableRequest) (*EnableResponse, error) // GetStreamStats is used to retrieve an array of stream-level stats from a // gRPC client/server. GetStreamStats(context.Context, *GetStreamStatsRequest) (*GetStreamStatsResponse, error) } - -// UnimplementedProfilingServer should be embedded to have forward compatible implementations. -type UnimplementedProfilingServer struct { -} - -func (*UnimplementedProfilingServer) Enable(context.Context, *EnableRequest) (*EnableResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Enable not implemented") -} -func (*UnimplementedProfilingServer) GetStreamStats(context.Context, *GetStreamStatsRequest) (*GetStreamStatsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetStreamStats not implemented") -} - -func RegisterProfilingServer(s *grpc.Server, srv ProfilingServer) { - s.RegisterService(&_Profiling_serviceDesc, srv) -} - -func _Profiling_Enable_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(EnableRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ProfilingServer).Enable(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpc.go.profiling.v1alpha.Profiling/Enable", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProfilingServer).Enable(ctx, req.(*EnableRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Profiling_GetStreamStats_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetStreamStatsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ProfilingServer).GetStreamStats(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpc.go.profiling.v1alpha.Profiling/GetStreamStats", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ProfilingServer).GetStreamStats(ctx, req.(*GetStreamStatsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _Profiling_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.go.profiling.v1alpha.Profiling", - HandlerType: (*ProfilingServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Enable", - Handler: _Profiling_Enable_Handler, - }, - { - MethodName: "GetStreamStats", - Handler: _Profiling_GetStreamStats_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "profiling/proto/service.proto", -} diff --git a/reflection/grpc_reflection_v1alpha/reflection.pb.go b/reflection/grpc_reflection_v1alpha/reflection.pb.go index 382612d5..900bd6c0 100644 --- a/reflection/grpc_reflection_v1alpha/reflection.pb.go +++ b/reflection/grpc_reflection_v1alpha/reflection.pb.go @@ -4,8 +4,12 @@ package grpc_reflection_v1alpha import ( + context "context" fmt "fmt" proto "github.com/golang/protobuf/proto" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" math "math" ) @@ -632,3 +636,119 @@ var fileDescriptor_e8cf9f2921ad6c95 = []byte{ 0xcb, 0xb3, 0xdb, 0x8c, 0xdb, 0xea, 0x53, 0xd5, 0xb9, 0xfd, 0xd3, 0x35, 0xdc, 0x54, 0xbe, 0x39, 0xfd, 0x1b, 0x00, 0x00, 0xff, 0xff, 0x6c, 0x74, 0x3a, 0x67, 0xe7, 0x06, 0x00, 0x00, } + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConnInterface + +// 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.SupportPackageIsVersion6 + +// ServerReflectionClient is the client API for ServerReflection service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type ServerReflectionClient interface { + // The reflection service is structured as a bidirectional stream, ensuring + // all related requests go to a single server. + ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (ServerReflection_ServerReflectionInfoClient, error) +} + +type serverReflectionClient struct { + cc grpc.ClientConnInterface +} + +func NewServerReflectionClient(cc grpc.ClientConnInterface) ServerReflectionClient { + return &serverReflectionClient{cc} +} + +func (c *serverReflectionClient) ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (ServerReflection_ServerReflectionInfoClient, error) { + stream, err := c.cc.NewStream(ctx, &_ServerReflection_serviceDesc.Streams[0], "/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo", opts...) + if err != nil { + return nil, err + } + x := &serverReflectionServerReflectionInfoClient{stream} + return x, nil +} + +type ServerReflection_ServerReflectionInfoClient interface { + Send(*ServerReflectionRequest) error + Recv() (*ServerReflectionResponse, error) + grpc.ClientStream +} + +type serverReflectionServerReflectionInfoClient struct { + grpc.ClientStream +} + +func (x *serverReflectionServerReflectionInfoClient) Send(m *ServerReflectionRequest) error { + return x.ClientStream.SendMsg(m) +} + +func (x *serverReflectionServerReflectionInfoClient) Recv() (*ServerReflectionResponse, error) { + m := new(ServerReflectionResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// ServerReflectionServer is the server API for ServerReflection service. +type ServerReflectionServer interface { + // The reflection service is structured as a bidirectional stream, ensuring + // all related requests go to a single server. + ServerReflectionInfo(ServerReflection_ServerReflectionInfoServer) error +} + +// UnimplementedServerReflectionServer can be embedded to have forward compatible implementations. +type UnimplementedServerReflectionServer struct { +} + +func (*UnimplementedServerReflectionServer) ServerReflectionInfo(srv ServerReflection_ServerReflectionInfoServer) error { + return status.Errorf(codes.Unimplemented, "method ServerReflectionInfo not implemented") +} + +func RegisterServerReflectionServer(s *grpc.Server, srv ServerReflectionServer) { + s.RegisterService(&_ServerReflection_serviceDesc, srv) +} + +func _ServerReflection_ServerReflectionInfo_Handler(srv interface{}, stream grpc.ServerStream) error { + return srv.(ServerReflectionServer).ServerReflectionInfo(&serverReflectionServerReflectionInfoServer{stream}) +} + +type ServerReflection_ServerReflectionInfoServer interface { + Send(*ServerReflectionResponse) error + Recv() (*ServerReflectionRequest, error) + grpc.ServerStream +} + +type serverReflectionServerReflectionInfoServer struct { + grpc.ServerStream +} + +func (x *serverReflectionServerReflectionInfoServer) Send(m *ServerReflectionResponse) error { + return x.ServerStream.SendMsg(m) +} + +func (x *serverReflectionServerReflectionInfoServer) Recv() (*ServerReflectionRequest, error) { + m := new(ServerReflectionRequest) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +var _ServerReflection_serviceDesc = grpc.ServiceDesc{ + ServiceName: "grpc.reflection.v1alpha.ServerReflection", + HandlerType: (*ServerReflectionServer)(nil), + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "ServerReflectionInfo", + Handler: _ServerReflection_ServerReflectionInfo_Handler, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "reflection/grpc_reflection_v1alpha/reflection.proto", +} diff --git a/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go b/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go index 2294b2c6..95f9d0cb 100644 --- a/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go +++ b/reflection/grpc_reflection_v1alpha/reflection_grpc.pb.go @@ -3,7 +3,6 @@ package grpc_reflection_v1alpha import ( - context "context" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -11,114 +10,66 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 -// ServerReflectionClient is the client API for ServerReflection 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 ServerReflectionClient interface { +// ServerReflectionService is the service API for ServerReflection service. +// Fields should be assigned to their respective handler implementations only before +// RegisterServerReflectionService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type ServerReflectionService struct { // The reflection service is structured as a bidirectional stream, ensuring // all related requests go to a single server. - ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (ServerReflection_ServerReflectionInfoClient, error) + ServerReflectionInfo func(ServerReflection_ServerReflectionInfoServer) error } -type serverReflectionClient struct { - cc grpc.ClientConnInterface -} - -func NewServerReflectionClient(cc grpc.ClientConnInterface) ServerReflectionClient { - return &serverReflectionClient{cc} -} - -func (c *serverReflectionClient) ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (ServerReflection_ServerReflectionInfoClient, error) { - stream, err := c.cc.NewStream(ctx, &_ServerReflection_serviceDesc.Streams[0], "/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo", opts...) - if err != nil { - return nil, err +func (s *ServerReflectionService) serverReflectionInfo(_ interface{}, stream grpc.ServerStream) error { + if s.ServerReflectionInfo == nil { + return status.Errorf(codes.Unimplemented, "method ServerReflectionInfo not implemented") } - x := &serverReflectionServerReflectionInfoClient{stream} - return x, nil + return s.ServerReflectionInfo(&serverReflectionServerReflectionInfoServer{stream}) } -type ServerReflection_ServerReflectionInfoClient interface { - Send(*ServerReflectionRequest) error - Recv() (*ServerReflectionResponse, error) - grpc.ClientStream -} - -type serverReflectionServerReflectionInfoClient struct { - grpc.ClientStream -} - -func (x *serverReflectionServerReflectionInfoClient) Send(m *ServerReflectionRequest) error { - return x.ClientStream.SendMsg(m) -} - -func (x *serverReflectionServerReflectionInfoClient) Recv() (*ServerReflectionResponse, error) { - m := new(ServerReflectionResponse) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err +// RegisterServerReflectionService registers a service implementation with a gRPC server. +func RegisterServerReflectionService(s grpc.ServiceRegistrar, srv *ServerReflectionService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.reflection.v1alpha.ServerReflection", + Methods: []grpc.MethodDesc{}, + Streams: []grpc.StreamDesc{ + { + StreamName: "ServerReflectionInfo", + Handler: srv.serverReflectionInfo, + ServerStreams: true, + ClientStreams: true, + }, + }, + Metadata: "reflection/grpc_reflection_v1alpha/reflection.proto", } - return m, nil + + s.RegisterService(&sd, nil) } -// ServerReflectionServer is the server API for ServerReflection service. -// All implementations should embed UnimplementedServerReflectionServer -// for forward compatibility -type ServerReflectionServer interface { +// NewServerReflectionService creates a new ServerReflectionService containing the +// implemented methods of the ServerReflection service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewServerReflectionService(s interface{}) *ServerReflectionService { + ns := &ServerReflectionService{} + if h, ok := s.(interface { + ServerReflectionInfo(ServerReflection_ServerReflectionInfoServer) error + }); ok { + ns.ServerReflectionInfo = h.ServerReflectionInfo + } + return ns +} + +// UnstableServerReflectionService is the service API for ServerReflection service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableServerReflectionService interface { // The reflection service is structured as a bidirectional stream, ensuring // all related requests go to a single server. ServerReflectionInfo(ServerReflection_ServerReflectionInfoServer) error } - -// UnimplementedServerReflectionServer should be embedded to have forward compatible implementations. -type UnimplementedServerReflectionServer struct { -} - -func (*UnimplementedServerReflectionServer) ServerReflectionInfo(ServerReflection_ServerReflectionInfoServer) error { - return status.Errorf(codes.Unimplemented, "method ServerReflectionInfo not implemented") -} - -func RegisterServerReflectionServer(s *grpc.Server, srv ServerReflectionServer) { - s.RegisterService(&_ServerReflection_serviceDesc, srv) -} - -func _ServerReflection_ServerReflectionInfo_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(ServerReflectionServer).ServerReflectionInfo(&serverReflectionServerReflectionInfoServer{stream}) -} - -type ServerReflection_ServerReflectionInfoServer interface { - Send(*ServerReflectionResponse) error - Recv() (*ServerReflectionRequest, error) - grpc.ServerStream -} - -type serverReflectionServerReflectionInfoServer struct { - grpc.ServerStream -} - -func (x *serverReflectionServerReflectionInfoServer) Send(m *ServerReflectionResponse) error { - return x.ServerStream.SendMsg(m) -} - -func (x *serverReflectionServerReflectionInfoServer) Recv() (*ServerReflectionRequest, error) { - m := new(ServerReflectionRequest) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -var _ServerReflection_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.reflection.v1alpha.ServerReflection", - HandlerType: (*ServerReflectionServer)(nil), - Methods: []grpc.MethodDesc{}, - Streams: []grpc.StreamDesc{ - { - StreamName: "ServerReflectionInfo", - Handler: _ServerReflection_ServerReflectionInfo_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "reflection/grpc_reflection_v1alpha/reflection.proto", -} diff --git a/reflection/grpc_testing/test_grpc.pb.go b/reflection/grpc_testing/test_grpc.pb.go index 95cd2bab..285cdbc8 100644 --- a/reflection/grpc_testing/test_grpc.pb.go +++ b/reflection/grpc_testing/test_grpc.pb.go @@ -11,7 +11,7 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 // SearchServiceClient is the client API for SearchService service. // @@ -29,6 +29,10 @@ func NewSearchServiceClient(cc grpc.ClientConnInterface) SearchServiceClient { return &searchServiceClient{cc} } +var searchServiceSearchStreamDesc = &grpc.StreamDesc{ + StreamName: "Search", +} + func (c *searchServiceClient) Search(ctx context.Context, in *SearchRequest, opts ...grpc.CallOption) (*SearchResponse, error) { out := new(SearchResponse) err := c.cc.Invoke(ctx, "/grpc.testing.SearchService/Search", in, out, opts...) @@ -38,8 +42,14 @@ func (c *searchServiceClient) Search(ctx context.Context, in *SearchRequest, opt return out, nil } +var searchServiceStreamingSearchStreamDesc = &grpc.StreamDesc{ + StreamName: "StreamingSearch", + ServerStreams: true, + ClientStreams: true, +} + func (c *searchServiceClient) StreamingSearch(ctx context.Context, opts ...grpc.CallOption) (SearchService_StreamingSearchClient, error) { - stream, err := c.cc.NewStream(ctx, &_SearchService_serviceDesc.Streams[0], "/grpc.testing.SearchService/StreamingSearch", opts...) + stream, err := c.cc.NewStream(ctx, searchServiceStreamingSearchStreamDesc, "/grpc.testing.SearchService/StreamingSearch", opts...) if err != nil { return nil, err } @@ -69,49 +79,40 @@ func (x *searchServiceStreamingSearchClient) Recv() (*SearchResponse, error) { return m, nil } -// SearchServiceServer is the server API for SearchService service. -// All implementations should embed UnimplementedSearchServiceServer -// for forward compatibility -type SearchServiceServer interface { - Search(context.Context, *SearchRequest) (*SearchResponse, error) - StreamingSearch(SearchService_StreamingSearchServer) error +// SearchServiceService is the service API for SearchService service. +// Fields should be assigned to their respective handler implementations only before +// RegisterSearchServiceService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type SearchServiceService struct { + Search func(context.Context, *SearchRequest) (*SearchResponse, error) + StreamingSearch func(SearchService_StreamingSearchServer) error } -// UnimplementedSearchServiceServer should be embedded to have forward compatible implementations. -type UnimplementedSearchServiceServer struct { -} - -func (*UnimplementedSearchServiceServer) Search(context.Context, *SearchRequest) (*SearchResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Search not implemented") -} -func (*UnimplementedSearchServiceServer) StreamingSearch(SearchService_StreamingSearchServer) error { - return status.Errorf(codes.Unimplemented, "method StreamingSearch not implemented") -} - -func RegisterSearchServiceServer(s *grpc.Server, srv SearchServiceServer) { - s.RegisterService(&_SearchService_serviceDesc, srv) -} - -func _SearchService_Search_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func (s *SearchServiceService) search(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.Search == nil { + return nil, status.Errorf(codes.Unimplemented, "method Search not implemented") + } in := new(SearchRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(SearchServiceServer).Search(ctx, in) + return s.Search(ctx, in) } info := &grpc.UnaryServerInfo{ - Server: srv, + Server: s, FullMethod: "/grpc.testing.SearchService/Search", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(SearchServiceServer).Search(ctx, req.(*SearchRequest)) + return s.Search(ctx, req.(*SearchRequest)) } return interceptor(ctx, in, info, handler) } - -func _SearchService_StreamingSearch_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(SearchServiceServer).StreamingSearch(&searchServiceStreamingSearchServer{stream}) +func (s *SearchServiceService) streamingSearch(_ interface{}, stream grpc.ServerStream) error { + if s.StreamingSearch == nil { + return status.Errorf(codes.Unimplemented, "method StreamingSearch not implemented") + } + return s.StreamingSearch(&searchServiceStreamingSearchServer{stream}) } type SearchService_StreamingSearchServer interface { @@ -136,22 +137,56 @@ func (x *searchServiceStreamingSearchServer) Recv() (*SearchRequest, error) { return m, nil } -var _SearchService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.testing.SearchService", - HandlerType: (*SearchServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Search", - Handler: _SearchService_Search_Handler, +// RegisterSearchServiceService registers a service implementation with a gRPC server. +func RegisterSearchServiceService(s grpc.ServiceRegistrar, srv *SearchServiceService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.testing.SearchService", + Methods: []grpc.MethodDesc{ + { + MethodName: "Search", + Handler: srv.search, + }, }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "StreamingSearch", - Handler: _SearchService_StreamingSearch_Handler, - ServerStreams: true, - ClientStreams: true, + Streams: []grpc.StreamDesc{ + { + StreamName: "StreamingSearch", + Handler: srv.streamingSearch, + ServerStreams: true, + ClientStreams: true, + }, }, - }, - Metadata: "reflection/grpc_testing/test.proto", + Metadata: "reflection/grpc_testing/test.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewSearchServiceService creates a new SearchServiceService containing the +// implemented methods of the SearchService service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewSearchServiceService(s interface{}) *SearchServiceService { + ns := &SearchServiceService{} + if h, ok := s.(interface { + Search(context.Context, *SearchRequest) (*SearchResponse, error) + }); ok { + ns.Search = h.Search + } + if h, ok := s.(interface { + StreamingSearch(SearchService_StreamingSearchServer) error + }); ok { + ns.StreamingSearch = h.StreamingSearch + } + return ns +} + +// UnstableSearchServiceService is the service API for SearchService service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableSearchServiceService interface { + Search(context.Context, *SearchRequest) (*SearchResponse, error) + StreamingSearch(SearchService_StreamingSearchServer) error } diff --git a/reflection/serverreflection_test.go b/reflection/serverreflection_test.go index 4cf6717f..db5fce2d 100644 --- a/reflection/serverreflection_test.go +++ b/reflection/serverreflection_test.go @@ -166,9 +166,9 @@ func (x) TestAllExtensionNumbersForType(t *testing.T) { // Do end2end tests. -type server struct { - pb.UnimplementedSearchServiceServer -} +type server struct{} + +var _ pb.UnstableSearchServiceService = (*server)(nil) func (s *server) Search(ctx context.Context, in *pb.SearchRequest) (*pb.SearchResponse, error) { return &pb.SearchResponse{}, nil @@ -195,7 +195,7 @@ func (x) TestReflectionEnd2end(t *testing.T) { t.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() - pb.RegisterSearchServiceServer(s, &server{}) + pb.RegisterSearchServiceService(s, pb.NewSearchServiceService(&server{})) pbv3.RegisterSearchServiceV3Server(s, &serverV3{}) // Register reflection service on s. Register(s) diff --git a/regenerate.sh b/regenerate.sh index 7e33b45e..750e3500 100755 --- a/regenerate.sh +++ b/regenerate.sh @@ -59,7 +59,8 @@ curl --silent https://raw.githubusercontent.com/istio/istio/master/security/prot mkdir -p ${WORKDIR}/out -SOURCES=( +# Generates legacy gRPC Server symbols in addition to the newer Service symbols +LEGACY_SOURCES=( ${WORKDIR}/googleapis/google/rpc/code.proto ${WORKDIR}/grpc-proto/grpc/binlog/v1/binarylog.proto ${WORKDIR}/grpc-proto/grpc/channelz/v1/channelz.proto @@ -73,16 +74,29 @@ SOURCES=( ${WORKDIR}/grpc-proto/grpc/service_config/service_config.proto ${WORKDIR}/grpc-proto/grpc/tls/provider/meshca/experimental/config.proto ${WORKDIR}/istio/istio/google/security/meshca/v1/meshca.proto - $(git ls-files --exclude-standard --cached --others "*.proto") + profiling/proto/service.proto + reflection/grpc_reflection_v1alpha/reflection.proto ) + +# Generates only the new gRPC Service symbols +SOURCES=( + $(git ls-files --exclude-standard --cached --others "*.proto" | grep -v '^\(profiling/proto/service.proto\|reflection/grpc_reflection_v1alpha/reflection.proto\)$') +) + # These options of the form 'Mfoo.proto=bar' instruct the codegen to use an # import path of 'bar' in the generated code when 'foo.proto' is imported in # one of the sources. OPTS=Mgrpc/service_config/service_config.proto=/internal/proto/grpc_service_config,\ Menvoy/config/core/v3/config_source.proto=github.com/envoyproxy/go-control-plane/envoy/config/core/v3 + for src in ${SOURCES[@]}; do echo "protoc ${src}" - protoc --go_out=${OPTS}:${WORKDIR}/out --go-grpc_out=${OPTS},requireUnimplementedServers=false:${WORKDIR}/out \ + protoc --go_out=${OPTS}:${WORKDIR}/out --go-grpc_out=${OPTS}:${WORKDIR}/out ${src} +done + +for src in ${LEGACY_SOURCES[@]}; do + echo "protoc ${src}" + protoc --go_out=${OPTS},plugins=grpc:${WORKDIR}/out --go-grpc_out=${OPTS},migration_mode=true:${WORKDIR}/out \ -I"." \ -I${WORKDIR}/grpc-proto \ -I${WORKDIR}/googleapis \ diff --git a/server.go b/server.go index ff71435f..33fc3240 100644 --- a/server.go +++ b/server.go @@ -554,12 +554,15 @@ type ServiceRegistrar interface { // RegisterService registers a service and its implementation to the gRPC // server. It is called from the IDL generated code. This must be called before -// invoking Serve. +// invoking Serve. If ss is non-nil (for legacy code), its type is checked to +// ensure it implements sd.HandlerType. func (s *Server) RegisterService(sd *ServiceDesc, ss interface{}) { - ht := reflect.TypeOf(sd.HandlerType).Elem() - st := reflect.TypeOf(ss) - if !st.Implements(ht) { - logger.Fatalf("grpc: Server.RegisterService found the handler of type %v that does not satisfy %v", st, ht) + if ss != nil { + ht := reflect.TypeOf(sd.HandlerType).Elem() + st := reflect.TypeOf(ss) + if !st.Implements(ht) { + logger.Fatalf("grpc: Server.RegisterService found the handler of type %v that does not satisfy %v", st, ht) + } } s.register(sd, ss) } diff --git a/stats/grpc_testing/test_grpc.pb.go b/stats/grpc_testing/test_grpc.pb.go index 98da3340..1fff30c6 100644 --- a/stats/grpc_testing/test_grpc.pb.go +++ b/stats/grpc_testing/test_grpc.pb.go @@ -11,7 +11,7 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 // TestServiceClient is the client API for TestService service. // @@ -38,6 +38,10 @@ func NewTestServiceClient(cc grpc.ClientConnInterface) TestServiceClient { return &testServiceClient{cc} } +var testServiceUnaryCallStreamDesc = &grpc.StreamDesc{ + StreamName: "UnaryCall", +} + func (c *testServiceClient) UnaryCall(ctx context.Context, in *SimpleRequest, opts ...grpc.CallOption) (*SimpleResponse, error) { out := new(SimpleResponse) err := c.cc.Invoke(ctx, "/grpc.testing.TestService/UnaryCall", in, out, opts...) @@ -47,8 +51,14 @@ func (c *testServiceClient) UnaryCall(ctx context.Context, in *SimpleRequest, op return out, nil } +var testServiceFullDuplexCallStreamDesc = &grpc.StreamDesc{ + StreamName: "FullDuplexCall", + ServerStreams: true, + ClientStreams: true, +} + func (c *testServiceClient) FullDuplexCall(ctx context.Context, opts ...grpc.CallOption) (TestService_FullDuplexCallClient, error) { - stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[0], "/grpc.testing.TestService/FullDuplexCall", opts...) + stream, err := c.cc.NewStream(ctx, testServiceFullDuplexCallStreamDesc, "/grpc.testing.TestService/FullDuplexCall", opts...) if err != nil { return nil, err } @@ -78,8 +88,13 @@ func (x *testServiceFullDuplexCallClient) Recv() (*SimpleResponse, error) { return m, nil } +var testServiceClientStreamCallStreamDesc = &grpc.StreamDesc{ + StreamName: "ClientStreamCall", + ClientStreams: true, +} + func (c *testServiceClient) ClientStreamCall(ctx context.Context, opts ...grpc.CallOption) (TestService_ClientStreamCallClient, error) { - stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[1], "/grpc.testing.TestService/ClientStreamCall", opts...) + stream, err := c.cc.NewStream(ctx, testServiceClientStreamCallStreamDesc, "/grpc.testing.TestService/ClientStreamCall", opts...) if err != nil { return nil, err } @@ -112,8 +127,13 @@ func (x *testServiceClientStreamCallClient) CloseAndRecv() (*SimpleResponse, err return m, nil } +var testServiceServerStreamCallStreamDesc = &grpc.StreamDesc{ + StreamName: "ServerStreamCall", + ServerStreams: true, +} + func (c *testServiceClient) ServerStreamCall(ctx context.Context, in *SimpleRequest, opts ...grpc.CallOption) (TestService_ServerStreamCallClient, error) { - stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[2], "/grpc.testing.TestService/ServerStreamCall", opts...) + stream, err := c.cc.NewStream(ctx, testServiceServerStreamCallStreamDesc, "/grpc.testing.TestService/ServerStreamCall", opts...) if err != nil { return nil, err } @@ -144,64 +164,65 @@ func (x *testServiceServerStreamCallClient) Recv() (*SimpleResponse, error) { return m, nil } -// TestServiceServer is the server API for TestService service. -// All implementations should embed UnimplementedTestServiceServer -// for forward compatibility -type TestServiceServer interface { +// TestServiceService is the service API for TestService service. +// Fields should be assigned to their respective handler implementations only before +// RegisterTestServiceService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type TestServiceService struct { // One request followed by one response. // The server returns the client id as-is. - UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) + UnaryCall func(context.Context, *SimpleRequest) (*SimpleResponse, error) // A sequence of requests with each request served by the server immediately. // As one request could lead to multiple responses, this interface // demonstrates the idea of full duplexing. - FullDuplexCall(TestService_FullDuplexCallServer) error + FullDuplexCall func(TestService_FullDuplexCallServer) error // Client stream - ClientStreamCall(TestService_ClientStreamCallServer) error + ClientStreamCall func(TestService_ClientStreamCallServer) error // Server stream - ServerStreamCall(*SimpleRequest, TestService_ServerStreamCallServer) error + ServerStreamCall func(*SimpleRequest, TestService_ServerStreamCallServer) error } -// UnimplementedTestServiceServer should be embedded to have forward compatible implementations. -type UnimplementedTestServiceServer struct { -} - -func (*UnimplementedTestServiceServer) UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UnaryCall not implemented") -} -func (*UnimplementedTestServiceServer) FullDuplexCall(TestService_FullDuplexCallServer) error { - return status.Errorf(codes.Unimplemented, "method FullDuplexCall not implemented") -} -func (*UnimplementedTestServiceServer) ClientStreamCall(TestService_ClientStreamCallServer) error { - return status.Errorf(codes.Unimplemented, "method ClientStreamCall not implemented") -} -func (*UnimplementedTestServiceServer) ServerStreamCall(*SimpleRequest, TestService_ServerStreamCallServer) error { - return status.Errorf(codes.Unimplemented, "method ServerStreamCall not implemented") -} - -func RegisterTestServiceServer(s *grpc.Server, srv TestServiceServer) { - s.RegisterService(&_TestService_serviceDesc, srv) -} - -func _TestService_UnaryCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func (s *TestServiceService) unaryCall(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.UnaryCall == nil { + return nil, status.Errorf(codes.Unimplemented, "method UnaryCall not implemented") + } in := new(SimpleRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(TestServiceServer).UnaryCall(ctx, in) + return s.UnaryCall(ctx, in) } info := &grpc.UnaryServerInfo{ - Server: srv, + Server: s, FullMethod: "/grpc.testing.TestService/UnaryCall", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).UnaryCall(ctx, req.(*SimpleRequest)) + return s.UnaryCall(ctx, req.(*SimpleRequest)) } return interceptor(ctx, in, info, handler) } - -func _TestService_FullDuplexCall_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(TestServiceServer).FullDuplexCall(&testServiceFullDuplexCallServer{stream}) +func (s *TestServiceService) fullDuplexCall(_ interface{}, stream grpc.ServerStream) error { + if s.FullDuplexCall == nil { + return status.Errorf(codes.Unimplemented, "method FullDuplexCall not implemented") + } + return s.FullDuplexCall(&testServiceFullDuplexCallServer{stream}) +} +func (s *TestServiceService) clientStreamCall(_ interface{}, stream grpc.ServerStream) error { + if s.ClientStreamCall == nil { + return status.Errorf(codes.Unimplemented, "method ClientStreamCall not implemented") + } + return s.ClientStreamCall(&testServiceClientStreamCallServer{stream}) +} +func (s *TestServiceService) serverStreamCall(_ interface{}, stream grpc.ServerStream) error { + if s.ServerStreamCall == nil { + return status.Errorf(codes.Unimplemented, "method ServerStreamCall not implemented") + } + m := new(SimpleRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return s.ServerStreamCall(m, &testServiceServerStreamCallServer{stream}) } type TestService_FullDuplexCallServer interface { @@ -226,10 +247,6 @@ func (x *testServiceFullDuplexCallServer) Recv() (*SimpleRequest, error) { return m, nil } -func _TestService_ClientStreamCall_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(TestServiceServer).ClientStreamCall(&testServiceClientStreamCallServer{stream}) -} - type TestService_ClientStreamCallServer interface { SendAndClose(*SimpleResponse) error Recv() (*SimpleRequest, error) @@ -252,14 +269,6 @@ func (x *testServiceClientStreamCallServer) Recv() (*SimpleRequest, error) { return m, nil } -func _TestService_ServerStreamCall_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(SimpleRequest) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(TestServiceServer).ServerStreamCall(m, &testServiceServerStreamCallServer{stream}) -} - type TestService_ServerStreamCallServer interface { Send(*SimpleResponse) error grpc.ServerStream @@ -273,32 +282,85 @@ func (x *testServiceServerStreamCallServer) Send(m *SimpleResponse) error { return x.ServerStream.SendMsg(m) } -var _TestService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.testing.TestService", - HandlerType: (*TestServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "UnaryCall", - Handler: _TestService_UnaryCall_Handler, +// RegisterTestServiceService registers a service implementation with a gRPC server. +func RegisterTestServiceService(s grpc.ServiceRegistrar, srv *TestServiceService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.testing.TestService", + Methods: []grpc.MethodDesc{ + { + MethodName: "UnaryCall", + Handler: srv.unaryCall, + }, }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "FullDuplexCall", - Handler: _TestService_FullDuplexCall_Handler, - ServerStreams: true, - ClientStreams: true, + Streams: []grpc.StreamDesc{ + { + StreamName: "FullDuplexCall", + Handler: srv.fullDuplexCall, + ServerStreams: true, + ClientStreams: true, + }, + { + StreamName: "ClientStreamCall", + Handler: srv.clientStreamCall, + ClientStreams: true, + }, + { + StreamName: "ServerStreamCall", + Handler: srv.serverStreamCall, + ServerStreams: true, + }, }, - { - StreamName: "ClientStreamCall", - Handler: _TestService_ClientStreamCall_Handler, - ClientStreams: true, - }, - { - StreamName: "ServerStreamCall", - Handler: _TestService_ServerStreamCall_Handler, - ServerStreams: true, - }, - }, - Metadata: "stats/grpc_testing/test.proto", + Metadata: "stats/grpc_testing/test.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewTestServiceService creates a new TestServiceService containing the +// implemented methods of the TestService service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewTestServiceService(s interface{}) *TestServiceService { + ns := &TestServiceService{} + if h, ok := s.(interface { + UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) + }); ok { + ns.UnaryCall = h.UnaryCall + } + if h, ok := s.(interface { + FullDuplexCall(TestService_FullDuplexCallServer) error + }); ok { + ns.FullDuplexCall = h.FullDuplexCall + } + if h, ok := s.(interface { + ClientStreamCall(TestService_ClientStreamCallServer) error + }); ok { + ns.ClientStreamCall = h.ClientStreamCall + } + if h, ok := s.(interface { + ServerStreamCall(*SimpleRequest, TestService_ServerStreamCallServer) error + }); ok { + ns.ServerStreamCall = h.ServerStreamCall + } + return ns +} + +// UnstableTestServiceService is the service API for TestService service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableTestServiceService interface { + // One request followed by one response. + // The server returns the client id as-is. + UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) + // A sequence of requests with each request served by the server immediately. + // As one request could lead to multiple responses, this interface + // demonstrates the idea of full duplexing. + FullDuplexCall(TestService_FullDuplexCallServer) error + // Client stream + ClientStreamCall(TestService_ClientStreamCallServer) error + // Server stream + ServerStreamCall(*SimpleRequest, TestService_ServerStreamCallServer) error } diff --git a/stats/stats_test.go b/stats/stats_test.go index d047d48b..628533ed 100644 --- a/stats/stats_test.go +++ b/stats/stats_test.go @@ -73,9 +73,9 @@ var ( errorID int32 = 32202 ) -type testServer struct { - testpb.UnimplementedTestServiceServer -} +type testServer struct{} + +var _ testpb.UnstableTestServiceService = (*testServer)(nil) func (s *testServer) UnaryCall(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { if err := grpc.SendHeader(ctx, testHeaderMetadata); err != nil { @@ -165,7 +165,7 @@ type test struct { clientStatsHandler stats.Handler serverStatsHandler stats.Handler - testServer testpb.TestServiceServer // nil means none + testService *testpb.TestServiceService // nil means none // srv and srvAddr are set once startServer is called. srv *grpc.Server srvAddr string @@ -200,8 +200,8 @@ func newTest(t *testing.T, tc *testConfig, ch stats.Handler, sh stats.Handler) * // startServer starts a gRPC server listening. Callers should defer a // call to te.tearDown to clean up. -func (te *test) startServer(ts testpb.TestServiceServer) { - te.testServer = ts +func (te *test) startServer(ts *testpb.TestServiceService) { + te.testService = ts lis, err := net.Listen("tcp", "localhost:0") if err != nil { te.t.Fatalf("Failed to listen: %v", err) @@ -218,8 +218,8 @@ func (te *test) startServer(ts testpb.TestServiceServer) { } s := grpc.NewServer(opts...) te.srv = s - if te.testServer != nil { - testpb.RegisterTestServiceServer(s, te.testServer) + if te.testService != nil { + testpb.RegisterTestServiceService(s, te.testService) } go s.Serve(lis) @@ -815,7 +815,7 @@ func checkServerStats(t *testing.T, got []*gotData, expect *expectedData, checkF func testServerStats(t *testing.T, tc *testConfig, cc *rpcConfig, checkFuncs []func(t *testing.T, d *gotData, e *expectedData)) { h := &statshandler{} te := newTest(t, tc, nil, h) - te.startServer(&testServer{}) + te.startServer(testpb.NewTestServiceService(&testServer{})) defer te.tearDown() var ( @@ -1106,7 +1106,7 @@ func checkClientStats(t *testing.T, got []*gotData, expect *expectedData, checkF func testClientStats(t *testing.T, tc *testConfig, cc *rpcConfig, checkFuncs map[int]*checkFuncWithCount) { h := &statshandler{} te := newTest(t, tc, h, nil) - te.startServer(&testServer{}) + te.startServer(testpb.NewTestServiceService(&testServer{})) defer te.tearDown() var ( diff --git a/stress/client/main.go b/stress/client/main.go index c5bfffa4..0353476d 100644 --- a/stress/client/main.go +++ b/stress/client/main.go @@ -146,12 +146,13 @@ func (g *gauge) get() int64 { // server implements metrics server functions. type server struct { - metricspb.UnimplementedMetricsServiceServer mutex sync.RWMutex // gauges is a map from /stress_test/server_/channel_/stub_/qps to its qps gauge. gauges map[string]*gauge } +var _ metricspb.UnstableMetricsServiceService = (*server)(nil) + // newMetricsServer returns a new metrics server. func newMetricsServer() *server { return &server{gauges: make(map[string]*gauge)} @@ -202,7 +203,7 @@ func startServer(server *server, port int) { } s := grpc.NewServer() - metricspb.RegisterMetricsServiceServer(s, server) + metricspb.RegisterMetricsServiceService(s, metricspb.NewMetricsServiceService(server)) s.Serve(lis) } diff --git a/stress/grpc_testing/metrics_grpc.pb.go b/stress/grpc_testing/metrics_grpc.pb.go index 3a232ff8..3f0a8358 100644 --- a/stress/grpc_testing/metrics_grpc.pb.go +++ b/stress/grpc_testing/metrics_grpc.pb.go @@ -11,7 +11,7 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 // MetricsServiceClient is the client API for MetricsService service. // @@ -32,8 +32,13 @@ func NewMetricsServiceClient(cc grpc.ClientConnInterface) MetricsServiceClient { return &metricsServiceClient{cc} } +var metricsServiceGetAllGaugesStreamDesc = &grpc.StreamDesc{ + StreamName: "GetAllGauges", + ServerStreams: true, +} + func (c *metricsServiceClient) GetAllGauges(ctx context.Context, in *EmptyMessage, opts ...grpc.CallOption) (MetricsService_GetAllGaugesClient, error) { - stream, err := c.cc.NewStream(ctx, &_MetricsService_serviceDesc.Streams[0], "/grpc.testing.MetricsService/GetAllGauges", opts...) + stream, err := c.cc.NewStream(ctx, metricsServiceGetAllGaugesStreamDesc, "/grpc.testing.MetricsService/GetAllGauges", opts...) if err != nil { return nil, err } @@ -64,6 +69,10 @@ func (x *metricsServiceGetAllGaugesClient) Recv() (*GaugeResponse, error) { return m, nil } +var metricsServiceGetGaugeStreamDesc = &grpc.StreamDesc{ + StreamName: "GetGauge", +} + func (c *metricsServiceClient) GetGauge(ctx context.Context, in *GaugeRequest, opts ...grpc.CallOption) (*GaugeResponse, error) { out := new(GaugeResponse) err := c.cc.Invoke(ctx, "/grpc.testing.MetricsService/GetGauge", in, out, opts...) @@ -73,38 +82,47 @@ func (c *metricsServiceClient) GetGauge(ctx context.Context, in *GaugeRequest, o return out, nil } -// MetricsServiceServer is the server API for MetricsService service. -// All implementations should embed UnimplementedMetricsServiceServer -// for forward compatibility -type MetricsServiceServer interface { +// MetricsServiceService is the service API for MetricsService service. +// Fields should be assigned to their respective handler implementations only before +// RegisterMetricsServiceService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type MetricsServiceService struct { // Returns the values of all the gauges that are currently being maintained by // the service - GetAllGauges(*EmptyMessage, MetricsService_GetAllGaugesServer) error + GetAllGauges func(*EmptyMessage, MetricsService_GetAllGaugesServer) error // Returns the value of one gauge - GetGauge(context.Context, *GaugeRequest) (*GaugeResponse, error) + GetGauge func(context.Context, *GaugeRequest) (*GaugeResponse, error) } -// UnimplementedMetricsServiceServer should be embedded to have forward compatible implementations. -type UnimplementedMetricsServiceServer struct { -} - -func (*UnimplementedMetricsServiceServer) GetAllGauges(*EmptyMessage, MetricsService_GetAllGaugesServer) error { - return status.Errorf(codes.Unimplemented, "method GetAllGauges not implemented") -} -func (*UnimplementedMetricsServiceServer) GetGauge(context.Context, *GaugeRequest) (*GaugeResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method GetGauge not implemented") -} - -func RegisterMetricsServiceServer(s *grpc.Server, srv MetricsServiceServer) { - s.RegisterService(&_MetricsService_serviceDesc, srv) -} - -func _MetricsService_GetAllGauges_Handler(srv interface{}, stream grpc.ServerStream) error { +func (s *MetricsServiceService) getAllGauges(_ interface{}, stream grpc.ServerStream) error { + if s.GetAllGauges == nil { + return status.Errorf(codes.Unimplemented, "method GetAllGauges not implemented") + } m := new(EmptyMessage) if err := stream.RecvMsg(m); err != nil { return err } - return srv.(MetricsServiceServer).GetAllGauges(m, &metricsServiceGetAllGaugesServer{stream}) + return s.GetAllGauges(m, &metricsServiceGetAllGaugesServer{stream}) +} +func (s *MetricsServiceService) getGauge(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.GetGauge == nil { + return nil, status.Errorf(codes.Unimplemented, "method GetGauge not implemented") + } + in := new(GaugeRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return s.GetGauge(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: s, + FullMethod: "/grpc.testing.MetricsService/GetGauge", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return s.GetGauge(ctx, req.(*GaugeRequest)) + } + return interceptor(ctx, in, info, handler) } type MetricsService_GetAllGaugesServer interface { @@ -120,39 +138,58 @@ func (x *metricsServiceGetAllGaugesServer) Send(m *GaugeResponse) error { return x.ServerStream.SendMsg(m) } -func _MetricsService_GetGauge_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GaugeRequest) - if err := dec(in); err != nil { - return nil, err +// RegisterMetricsServiceService registers a service implementation with a gRPC server. +func RegisterMetricsServiceService(s grpc.ServiceRegistrar, srv *MetricsServiceService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.testing.MetricsService", + Methods: []grpc.MethodDesc{ + { + MethodName: "GetGauge", + Handler: srv.getGauge, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "GetAllGauges", + Handler: srv.getAllGauges, + ServerStreams: true, + }, + }, + Metadata: "stress/grpc_testing/metrics.proto", } - if interceptor == nil { - return srv.(MetricsServiceServer).GetGauge(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpc.testing.MetricsService/GetGauge", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(MetricsServiceServer).GetGauge(ctx, req.(*GaugeRequest)) - } - return interceptor(ctx, in, info, handler) + + s.RegisterService(&sd, nil) } -var _MetricsService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.testing.MetricsService", - HandlerType: (*MetricsServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "GetGauge", - Handler: _MetricsService_GetGauge_Handler, - }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "GetAllGauges", - Handler: _MetricsService_GetAllGauges_Handler, - ServerStreams: true, - }, - }, - Metadata: "stress/grpc_testing/metrics.proto", +// NewMetricsServiceService creates a new MetricsServiceService containing the +// implemented methods of the MetricsService service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewMetricsServiceService(s interface{}) *MetricsServiceService { + ns := &MetricsServiceService{} + if h, ok := s.(interface { + GetAllGauges(*EmptyMessage, MetricsService_GetAllGaugesServer) error + }); ok { + ns.GetAllGauges = h.GetAllGauges + } + if h, ok := s.(interface { + GetGauge(context.Context, *GaugeRequest) (*GaugeResponse, error) + }); ok { + ns.GetGauge = h.GetGauge + } + return ns +} + +// UnstableMetricsServiceService is the service API for MetricsService service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableMetricsServiceService interface { + // Returns the values of all the gauges that are currently being maintained by + // the service + GetAllGauges(*EmptyMessage, MetricsService_GetAllGaugesServer) error + // Returns the value of one gauge + GetGauge(context.Context, *GaugeRequest) (*GaugeResponse, error) } diff --git a/test/balancer_test.go b/test/balancer_test.go index f0189cf2..c45a3801 100644 --- a/test/balancer_test.go +++ b/test/balancer_test.go @@ -498,7 +498,7 @@ func (s) TestAddressAttributesInNewSubConn(t *testing.T) { } s := grpc.NewServer() - testpb.RegisterTestServiceServer(s, &testServer{}) + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(&testServer{})) go s.Serve(lis) defer s.Stop() t.Logf("Started gRPC server at %s...", lis.Addr().String()) @@ -561,7 +561,7 @@ func (s) TestServersSwap(t *testing.T) { return &testpb.SimpleResponse{Username: username}, nil }, } - testpb.RegisterTestServiceServer(s, ts) + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(ts)) go s.Serve(lis) return lis.Addr().String(), s.Stop } @@ -621,7 +621,7 @@ func (s) TestEmptyAddrs(t *testing.T) { return &testpb.SimpleResponse{Username: one}, nil }, } - testpb.RegisterTestServiceServer(s, ts) + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(ts)) go s.Serve(lis) // Initialize pickfirst client @@ -710,7 +710,7 @@ func (s) TestWaitForReady(t *testing.T) { return &testpb.SimpleResponse{Username: one}, nil }, } - testpb.RegisterTestServiceServer(s, ts) + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(ts)) go s.Serve(lis) // Initialize client diff --git a/test/end2end_test.go b/test/end2end_test.go index 0842dcca..f26997ea 100644 --- a/test/end2end_test.go +++ b/test/end2end_test.go @@ -126,8 +126,6 @@ var ( var raceMode bool // set by race.go in race mode type testServer struct { - testpb.UnimplementedTestServiceServer - security string // indicate the authentication protocol used by this server. earlyFail bool // whether to error out the execution of a service handler prematurely. setAndSendHeader bool // whether to call setHeader and sendHeader. @@ -136,6 +134,8 @@ type testServer struct { unaryCallSleepTime time.Duration } +var _ testpb.UnstableTestServiceService = (*testServer)(nil) + func (s *testServer) EmptyCall(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { if md, ok := metadata.FromIncomingContext(ctx); ok { // For testing purpose, returns an error if user-agent is failAppUA. @@ -566,7 +566,7 @@ func newTest(t *testing.T, e env) *test { return te } -func (te *test) listenAndServe(ts testpb.TestServiceServer, listen func(network, address string) (net.Listener, error)) net.Listener { +func (te *test) listenAndServe(ts interface{}, listen func(network, address string) (net.Listener, error)) net.Listener { te.t.Helper() te.t.Logf("Running test in %s environment...", te.e.name) sopts := []grpc.ServerOption{grpc.MaxConcurrentStreams(te.maxStream)} @@ -626,7 +626,7 @@ func (te *test) listenAndServe(ts testpb.TestServiceServer, listen func(network, sopts = append(sopts, te.customServerOptions...) s := grpc.NewServer(sopts...) if ts != nil { - testpb.RegisterTestServiceServer(s, ts) + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(ts)) } // Create a new default health server if enableHealthServer is set, or use @@ -691,20 +691,20 @@ func (w wrapHS) Stop() { w.s.Close() } -func (te *test) startServerWithConnControl(ts testpb.TestServiceServer) *listenerWrapper { +func (te *test) startServerWithConnControl(ts interface{}) *listenerWrapper { l := te.listenAndServe(ts, listenWithConnControl) return l.(*listenerWrapper) } // startServer starts a gRPC server exposing the provided TestService // implementation. Callers should defer a call to te.tearDown to clean up -func (te *test) startServer(ts testpb.TestServiceServer) { +func (te *test) startServer(ts interface{}) { te.t.Helper() te.listenAndServe(ts, net.Listen) } // startServers starts 'num' gRPC servers exposing the provided TestService. -func (te *test) startServers(ts testpb.TestServiceServer, num int) { +func (te *test) startServers(ts interface{}, num int) { for i := 0; i < num; i++ { te.startServer(ts) te.srvs = append(te.srvs, te.srv.(*grpc.Server)) @@ -3892,15 +3892,13 @@ func equalError(x, y error) bool { return x == y || (x != nil && y != nil && x.Error() == y.Error()) } -// concurrentSendServer is a TestServiceServer whose +// concurrentSendServer is a TestServiceService whose // StreamingOutputCall makes ten serial Send calls, sending payloads // "0".."9", inclusive. TestServerStreamingConcurrent verifies they // were received in the correct order, and that there were no races. // -// All other TestServiceServer methods crash if called. -type concurrentSendServer struct { - testpb.TestServiceServer -} +// All other TestServiceService methods return unimplemented if called. +type concurrentSendServer struct{} func (s concurrentSendServer) StreamingOutputCall(args *testpb.StreamingOutputCallRequest, stream testpb.TestService_StreamingOutputCallServer) error { for i := 0; i < 10; i++ { @@ -4496,12 +4494,11 @@ func testStreamServerInterceptor(t *testing.T, e env) { } } -// funcServer implements methods of TestServiceServer using funcs, +// funcServer implements methods of TestServiceService using funcs, // similar to an http.HandlerFunc. -// Any unimplemented method will crash. Tests implement the method(s) +// Any unimplemented method will return unimplemented. Tests implement the method(s) // they need. type funcServer struct { - testpb.TestServiceServer unaryCall func(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) streamingInputCall func(stream testpb.TestService_StreamingInputCallServer) error fullDuplexCall func(stream testpb.TestService_FullDuplexCallServer) error @@ -4872,10 +4869,10 @@ func (s) TestFlowControlLogicalRace(t *testing.T) { defer lis.Close() s := grpc.NewServer() - testpb.RegisterTestServiceServer(s, &flowControlLogicalRaceServer{ + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(&flowControlLogicalRaceServer{ itemCount: itemCount, itemSize: itemSize, - }) + })) defer s.Stop() go s.Serve(lis) @@ -4929,8 +4926,6 @@ func (s) TestFlowControlLogicalRace(t *testing.T) { } type flowControlLogicalRaceServer struct { - testpb.TestServiceServer - itemSize int itemCount int } @@ -5077,9 +5072,6 @@ func (fw *filterWriter) Write(p []byte) (n int, err error) { // stubServer is a server that is easy to customize within individual test // cases. type stubServer struct { - // Guarantees we satisfy this interface; panics if unimplemented methods are called. - testpb.TestServiceServer - // Customizable implementations of server handlers. emptyCall func(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) unaryCall func(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) @@ -5133,7 +5125,7 @@ func (ss *stubServer) Start(sopts []grpc.ServerOption, dopts ...grpc.DialOption) ss.cleanups = append(ss.cleanups, func() { lis.Close() }) s := grpc.NewServer(sopts...) - testpb.RegisterTestServiceServer(s, ss) + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(ss)) go s.Serve(lis) ss.cleanups = append(ss.cleanups, s.Stop) ss.s = s @@ -6276,7 +6268,7 @@ func (s) TestServeExitsWhenListenerClosed(t *testing.T) { s := grpc.NewServer() defer s.Stop() - testpb.RegisterTestServiceServer(s, ss) + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(ss)) lis, err := net.Listen("tcp", "localhost:0") if err != nil { @@ -6495,7 +6487,7 @@ func (s) TestDisabledIOBuffers(t *testing.T) { } s := grpc.NewServer(grpc.WriteBufferSize(0), grpc.ReadBufferSize(0)) - testpb.RegisterTestServiceServer(s, ss) + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(ss)) lis, err := net.Listen("tcp", "localhost:0") if err != nil { @@ -6708,7 +6700,7 @@ func (s) TestNetPipeConn(t *testing.T) { ts := &funcServer{unaryCall: func(ctx context.Context, in *testpb.SimpleRequest) (*testpb.SimpleResponse, error) { return &testpb.SimpleResponse{}, nil }} - testpb.RegisterTestServiceServer(s, ts) + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(ts)) go s.Serve(pl) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -6791,7 +6783,7 @@ func (s) TestGoAwayThenClose(t *testing.T) { return err }, } - testpb.RegisterTestServiceServer(s1, ts) + testpb.RegisterTestServiceService(s1, testpb.NewTestServiceService(ts)) go s1.Serve(lis1) conn2Established := grpcsync.NewEvent() @@ -6801,7 +6793,7 @@ func (s) TestGoAwayThenClose(t *testing.T) { } s2 := grpc.NewServer() defer s2.Stop() - testpb.RegisterTestServiceServer(s2, ts) + testpb.RegisterTestServiceService(s2, testpb.NewTestServiceService(ts)) go s2.Serve(lis2) r := manual.NewBuilderWithScheme("whatever") diff --git a/test/goaway_test.go b/test/goaway_test.go index 55f79ebc..93d96480 100644 --- a/test/goaway_test.go +++ b/test/goaway_test.go @@ -48,7 +48,7 @@ func (s) TestGracefulClientOnGoAway(t *testing.T) { s := grpc.NewServer(grpc.KeepaliveParams(keepalive.ServerParameters{MaxConnectionAge: maxConnAge})) defer s.Stop() - testpb.RegisterTestServiceServer(s, ss) + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(ss)) lis, err := net.Listen("tcp", "localhost:0") if err != nil { diff --git a/test/gracefulstop_test.go b/test/gracefulstop_test.go index 3da75ea1..f7659524 100644 --- a/test/gracefulstop_test.go +++ b/test/gracefulstop_test.go @@ -117,7 +117,7 @@ func (s) TestGracefulStop(t *testing.T) { }, } s := grpc.NewServer() - testpb.RegisterTestServiceServer(s, ss) + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(ss)) // 1. Start Server wg := sync.WaitGroup{} diff --git a/test/grpc_testing/test_grpc.pb.go b/test/grpc_testing/test_grpc.pb.go index 2340ac05..2ab12ac9 100644 --- a/test/grpc_testing/test_grpc.pb.go +++ b/test/grpc_testing/test_grpc.pb.go @@ -11,7 +11,7 @@ import ( // 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.SupportPackageIsVersion6 +const _ = grpc.SupportPackageIsVersion7 // TestServiceClient is the client API for TestService service. // @@ -47,6 +47,10 @@ func NewTestServiceClient(cc grpc.ClientConnInterface) TestServiceClient { return &testServiceClient{cc} } +var testServiceEmptyCallStreamDesc = &grpc.StreamDesc{ + StreamName: "EmptyCall", +} + func (c *testServiceClient) EmptyCall(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) err := c.cc.Invoke(ctx, "/grpc.testing.TestService/EmptyCall", in, out, opts...) @@ -56,6 +60,10 @@ func (c *testServiceClient) EmptyCall(ctx context.Context, in *Empty, opts ...gr return out, nil } +var testServiceUnaryCallStreamDesc = &grpc.StreamDesc{ + StreamName: "UnaryCall", +} + func (c *testServiceClient) UnaryCall(ctx context.Context, in *SimpleRequest, opts ...grpc.CallOption) (*SimpleResponse, error) { out := new(SimpleResponse) err := c.cc.Invoke(ctx, "/grpc.testing.TestService/UnaryCall", in, out, opts...) @@ -65,8 +73,13 @@ func (c *testServiceClient) UnaryCall(ctx context.Context, in *SimpleRequest, op return out, nil } +var testServiceStreamingOutputCallStreamDesc = &grpc.StreamDesc{ + StreamName: "StreamingOutputCall", + ServerStreams: true, +} + func (c *testServiceClient) StreamingOutputCall(ctx context.Context, in *StreamingOutputCallRequest, opts ...grpc.CallOption) (TestService_StreamingOutputCallClient, error) { - stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[0], "/grpc.testing.TestService/StreamingOutputCall", opts...) + stream, err := c.cc.NewStream(ctx, testServiceStreamingOutputCallStreamDesc, "/grpc.testing.TestService/StreamingOutputCall", opts...) if err != nil { return nil, err } @@ -97,8 +110,13 @@ func (x *testServiceStreamingOutputCallClient) Recv() (*StreamingOutputCallRespo return m, nil } +var testServiceStreamingInputCallStreamDesc = &grpc.StreamDesc{ + StreamName: "StreamingInputCall", + ClientStreams: true, +} + func (c *testServiceClient) StreamingInputCall(ctx context.Context, opts ...grpc.CallOption) (TestService_StreamingInputCallClient, error) { - stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[1], "/grpc.testing.TestService/StreamingInputCall", opts...) + stream, err := c.cc.NewStream(ctx, testServiceStreamingInputCallStreamDesc, "/grpc.testing.TestService/StreamingInputCall", opts...) if err != nil { return nil, err } @@ -131,8 +149,14 @@ func (x *testServiceStreamingInputCallClient) CloseAndRecv() (*StreamingInputCal return m, nil } +var testServiceFullDuplexCallStreamDesc = &grpc.StreamDesc{ + StreamName: "FullDuplexCall", + ServerStreams: true, + ClientStreams: true, +} + func (c *testServiceClient) FullDuplexCall(ctx context.Context, opts ...grpc.CallOption) (TestService_FullDuplexCallClient, error) { - stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[2], "/grpc.testing.TestService/FullDuplexCall", opts...) + stream, err := c.cc.NewStream(ctx, testServiceFullDuplexCallStreamDesc, "/grpc.testing.TestService/FullDuplexCall", opts...) if err != nil { return nil, err } @@ -162,8 +186,14 @@ func (x *testServiceFullDuplexCallClient) Recv() (*StreamingOutputCallResponse, return m, nil } +var testServiceHalfDuplexCallStreamDesc = &grpc.StreamDesc{ + StreamName: "HalfDuplexCall", + ServerStreams: true, + ClientStreams: true, +} + func (c *testServiceClient) HalfDuplexCall(ctx context.Context, opts ...grpc.CallOption) (TestService_HalfDuplexCallClient, error) { - stream, err := c.cc.NewStream(ctx, &_TestService_serviceDesc.Streams[3], "/grpc.testing.TestService/HalfDuplexCall", opts...) + stream, err := c.cc.NewStream(ctx, testServiceHalfDuplexCallStreamDesc, "/grpc.testing.TestService/HalfDuplexCall", opts...) if err != nil { return nil, err } @@ -193,101 +223,100 @@ func (x *testServiceHalfDuplexCallClient) Recv() (*StreamingOutputCallResponse, return m, nil } -// TestServiceServer is the server API for TestService service. -// All implementations should embed UnimplementedTestServiceServer -// for forward compatibility -type TestServiceServer interface { +// TestServiceService is the service API for TestService service. +// Fields should be assigned to their respective handler implementations only before +// RegisterTestServiceService is called. Any unassigned fields will result in the +// handler for that method returning an Unimplemented error. +type TestServiceService struct { // One empty request followed by one empty response. - EmptyCall(context.Context, *Empty) (*Empty, error) + EmptyCall func(context.Context, *Empty) (*Empty, error) // One request followed by one response. // The server returns the client payload as-is. - UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) + UnaryCall func(context.Context, *SimpleRequest) (*SimpleResponse, error) // One request followed by a sequence of responses (streamed download). // The server returns the payload with client desired type and sizes. - StreamingOutputCall(*StreamingOutputCallRequest, TestService_StreamingOutputCallServer) error + StreamingOutputCall func(*StreamingOutputCallRequest, TestService_StreamingOutputCallServer) error // A sequence of requests followed by one response (streamed upload). // The server returns the aggregated size of client payload as the result. - StreamingInputCall(TestService_StreamingInputCallServer) error + StreamingInputCall func(TestService_StreamingInputCallServer) error // A sequence of requests with each request served by the server immediately. // As one request could lead to multiple responses, this interface // demonstrates the idea of full duplexing. - FullDuplexCall(TestService_FullDuplexCallServer) error + FullDuplexCall func(TestService_FullDuplexCallServer) error // A sequence of requests followed by a sequence of responses. // The server buffers all the client requests and then serves them in order. A // stream of responses are returned to the client when the server starts with // first request. - HalfDuplexCall(TestService_HalfDuplexCallServer) error + HalfDuplexCall func(TestService_HalfDuplexCallServer) error } -// UnimplementedTestServiceServer should be embedded to have forward compatible implementations. -type UnimplementedTestServiceServer struct { -} - -func (*UnimplementedTestServiceServer) EmptyCall(context.Context, *Empty) (*Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method EmptyCall not implemented") -} -func (*UnimplementedTestServiceServer) UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method UnaryCall not implemented") -} -func (*UnimplementedTestServiceServer) StreamingOutputCall(*StreamingOutputCallRequest, TestService_StreamingOutputCallServer) error { - return status.Errorf(codes.Unimplemented, "method StreamingOutputCall not implemented") -} -func (*UnimplementedTestServiceServer) StreamingInputCall(TestService_StreamingInputCallServer) error { - return status.Errorf(codes.Unimplemented, "method StreamingInputCall not implemented") -} -func (*UnimplementedTestServiceServer) FullDuplexCall(TestService_FullDuplexCallServer) error { - return status.Errorf(codes.Unimplemented, "method FullDuplexCall not implemented") -} -func (*UnimplementedTestServiceServer) HalfDuplexCall(TestService_HalfDuplexCallServer) error { - return status.Errorf(codes.Unimplemented, "method HalfDuplexCall not implemented") -} - -func RegisterTestServiceServer(s *grpc.Server, srv TestServiceServer) { - s.RegisterService(&_TestService_serviceDesc, srv) -} - -func _TestService_EmptyCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func (s *TestServiceService) emptyCall(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.EmptyCall == nil { + return nil, status.Errorf(codes.Unimplemented, "method EmptyCall not implemented") + } in := new(Empty) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(TestServiceServer).EmptyCall(ctx, in) + return s.EmptyCall(ctx, in) } info := &grpc.UnaryServerInfo{ - Server: srv, + Server: s, FullMethod: "/grpc.testing.TestService/EmptyCall", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).EmptyCall(ctx, req.(*Empty)) + return s.EmptyCall(ctx, req.(*Empty)) } return interceptor(ctx, in, info, handler) } - -func _TestService_UnaryCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func (s *TestServiceService) unaryCall(_ interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + if s.UnaryCall == nil { + return nil, status.Errorf(codes.Unimplemented, "method UnaryCall not implemented") + } in := new(SimpleRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(TestServiceServer).UnaryCall(ctx, in) + return s.UnaryCall(ctx, in) } info := &grpc.UnaryServerInfo{ - Server: srv, + Server: s, FullMethod: "/grpc.testing.TestService/UnaryCall", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServiceServer).UnaryCall(ctx, req.(*SimpleRequest)) + return s.UnaryCall(ctx, req.(*SimpleRequest)) } return interceptor(ctx, in, info, handler) } - -func _TestService_StreamingOutputCall_Handler(srv interface{}, stream grpc.ServerStream) error { +func (s *TestServiceService) streamingOutputCall(_ interface{}, stream grpc.ServerStream) error { + if s.StreamingOutputCall == nil { + return status.Errorf(codes.Unimplemented, "method StreamingOutputCall not implemented") + } m := new(StreamingOutputCallRequest) if err := stream.RecvMsg(m); err != nil { return err } - return srv.(TestServiceServer).StreamingOutputCall(m, &testServiceStreamingOutputCallServer{stream}) + return s.StreamingOutputCall(m, &testServiceStreamingOutputCallServer{stream}) +} +func (s *TestServiceService) streamingInputCall(_ interface{}, stream grpc.ServerStream) error { + if s.StreamingInputCall == nil { + return status.Errorf(codes.Unimplemented, "method StreamingInputCall not implemented") + } + return s.StreamingInputCall(&testServiceStreamingInputCallServer{stream}) +} +func (s *TestServiceService) fullDuplexCall(_ interface{}, stream grpc.ServerStream) error { + if s.FullDuplexCall == nil { + return status.Errorf(codes.Unimplemented, "method FullDuplexCall not implemented") + } + return s.FullDuplexCall(&testServiceFullDuplexCallServer{stream}) +} +func (s *TestServiceService) halfDuplexCall(_ interface{}, stream grpc.ServerStream) error { + if s.HalfDuplexCall == nil { + return status.Errorf(codes.Unimplemented, "method HalfDuplexCall not implemented") + } + return s.HalfDuplexCall(&testServiceHalfDuplexCallServer{stream}) } type TestService_StreamingOutputCallServer interface { @@ -303,10 +332,6 @@ func (x *testServiceStreamingOutputCallServer) Send(m *StreamingOutputCallRespon return x.ServerStream.SendMsg(m) } -func _TestService_StreamingInputCall_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(TestServiceServer).StreamingInputCall(&testServiceStreamingInputCallServer{stream}) -} - type TestService_StreamingInputCallServer interface { SendAndClose(*StreamingInputCallResponse) error Recv() (*StreamingInputCallRequest, error) @@ -329,10 +354,6 @@ func (x *testServiceStreamingInputCallServer) Recv() (*StreamingInputCallRequest return m, nil } -func _TestService_FullDuplexCall_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(TestServiceServer).FullDuplexCall(&testServiceFullDuplexCallServer{stream}) -} - type TestService_FullDuplexCallServer interface { Send(*StreamingOutputCallResponse) error Recv() (*StreamingOutputCallRequest, error) @@ -355,10 +376,6 @@ func (x *testServiceFullDuplexCallServer) Recv() (*StreamingOutputCallRequest, e return m, nil } -func _TestService_HalfDuplexCall_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(TestServiceServer).HalfDuplexCall(&testServiceHalfDuplexCallServer{stream}) -} - type TestService_HalfDuplexCallServer interface { Send(*StreamingOutputCallResponse) error Recv() (*StreamingOutputCallRequest, error) @@ -381,42 +398,114 @@ func (x *testServiceHalfDuplexCallServer) Recv() (*StreamingOutputCallRequest, e return m, nil } -var _TestService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "grpc.testing.TestService", - HandlerType: (*TestServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "EmptyCall", - Handler: _TestService_EmptyCall_Handler, +// RegisterTestServiceService registers a service implementation with a gRPC server. +func RegisterTestServiceService(s grpc.ServiceRegistrar, srv *TestServiceService) { + sd := grpc.ServiceDesc{ + ServiceName: "grpc.testing.TestService", + Methods: []grpc.MethodDesc{ + { + MethodName: "EmptyCall", + Handler: srv.emptyCall, + }, + { + MethodName: "UnaryCall", + Handler: srv.unaryCall, + }, }, - { - MethodName: "UnaryCall", - Handler: _TestService_UnaryCall_Handler, + Streams: []grpc.StreamDesc{ + { + StreamName: "StreamingOutputCall", + Handler: srv.streamingOutputCall, + ServerStreams: true, + }, + { + StreamName: "StreamingInputCall", + Handler: srv.streamingInputCall, + ClientStreams: true, + }, + { + StreamName: "FullDuplexCall", + Handler: srv.fullDuplexCall, + ServerStreams: true, + ClientStreams: true, + }, + { + StreamName: "HalfDuplexCall", + Handler: srv.halfDuplexCall, + ServerStreams: true, + ClientStreams: true, + }, }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "StreamingOutputCall", - Handler: _TestService_StreamingOutputCall_Handler, - ServerStreams: true, - }, - { - StreamName: "StreamingInputCall", - Handler: _TestService_StreamingInputCall_Handler, - ClientStreams: true, - }, - { - StreamName: "FullDuplexCall", - Handler: _TestService_FullDuplexCall_Handler, - ServerStreams: true, - ClientStreams: true, - }, - { - StreamName: "HalfDuplexCall", - Handler: _TestService_HalfDuplexCall_Handler, - ServerStreams: true, - ClientStreams: true, - }, - }, - Metadata: "test/grpc_testing/test.proto", + Metadata: "test/grpc_testing/test.proto", + } + + s.RegisterService(&sd, nil) +} + +// NewTestServiceService creates a new TestServiceService containing the +// implemented methods of the TestService service in s. Any unimplemented +// methods will result in the gRPC server returning an UNIMPLEMENTED status to the client. +// This includes situations where the method handler is misspelled or has the wrong +// signature. For this reason, this function should be used with great care and +// is not recommended to be used by most users. +func NewTestServiceService(s interface{}) *TestServiceService { + ns := &TestServiceService{} + if h, ok := s.(interface { + EmptyCall(context.Context, *Empty) (*Empty, error) + }); ok { + ns.EmptyCall = h.EmptyCall + } + if h, ok := s.(interface { + UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) + }); ok { + ns.UnaryCall = h.UnaryCall + } + if h, ok := s.(interface { + StreamingOutputCall(*StreamingOutputCallRequest, TestService_StreamingOutputCallServer) error + }); ok { + ns.StreamingOutputCall = h.StreamingOutputCall + } + if h, ok := s.(interface { + StreamingInputCall(TestService_StreamingInputCallServer) error + }); ok { + ns.StreamingInputCall = h.StreamingInputCall + } + if h, ok := s.(interface { + FullDuplexCall(TestService_FullDuplexCallServer) error + }); ok { + ns.FullDuplexCall = h.FullDuplexCall + } + if h, ok := s.(interface { + HalfDuplexCall(TestService_HalfDuplexCallServer) error + }); ok { + ns.HalfDuplexCall = h.HalfDuplexCall + } + return ns +} + +// UnstableTestServiceService is the service API for TestService service. +// New methods may be added to this interface if they are added to the service +// definition, which is not a backward-compatible change. For this reason, +// use of this type is not recommended. +type UnstableTestServiceService interface { + // One empty request followed by one empty response. + EmptyCall(context.Context, *Empty) (*Empty, error) + // One request followed by one response. + // The server returns the client payload as-is. + UnaryCall(context.Context, *SimpleRequest) (*SimpleResponse, error) + // One request followed by a sequence of responses (streamed download). + // The server returns the payload with client desired type and sizes. + StreamingOutputCall(*StreamingOutputCallRequest, TestService_StreamingOutputCallServer) error + // A sequence of requests followed by one response (streamed upload). + // The server returns the aggregated size of client payload as the result. + StreamingInputCall(TestService_StreamingInputCallServer) error + // A sequence of requests with each request served by the server immediately. + // As one request could lead to multiple responses, this interface + // demonstrates the idea of full duplexing. + FullDuplexCall(TestService_FullDuplexCallServer) error + // A sequence of requests followed by a sequence of responses. + // The server buffers all the client requests and then serves them in order. A + // stream of responses are returned to the client when the server starts with + // first request. + HalfDuplexCall(TestService_HalfDuplexCallServer) error } diff --git a/test/healthcheck_test.go b/test/healthcheck_test.go index 0a60f8c9..0137494e 100644 --- a/test/healthcheck_test.go +++ b/test/healthcheck_test.go @@ -140,7 +140,7 @@ func setupServer(sc *svrConfig) (s *grpc.Server, lis net.Listener, ts *testHealt ts = newTestHealthServer() } healthgrpc.RegisterHealthServer(s, ts) - testpb.RegisterTestServiceServer(s, &testServer{}) + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(&testServer{})) go s.Serve(lis) return s, lis, ts, s.Stop, nil } diff --git a/test/local_creds_test.go b/test/local_creds_test.go index b55b73bd..12af20b2 100644 --- a/test/local_creds_test.go +++ b/test/local_creds_test.go @@ -64,7 +64,7 @@ func testLocalCredsE2ESucceed(network, address string) error { s := grpc.NewServer(sopts...) defer s.Stop() - testpb.RegisterTestServiceServer(s, ss) + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(ss)) lis, err := net.Listen(network, address) if err != nil { @@ -162,7 +162,7 @@ func testLocalCredsE2EFail(dopts []grpc.DialOption) error { s := grpc.NewServer(sopts...) defer s.Stop() - testpb.RegisterTestServiceServer(s, ss) + testpb.RegisterTestServiceService(s, testpb.NewTestServiceService(ss)) lis, err := net.Listen("tcp", "localhost:0") if err != nil {