From 1263806a39d91de8eeda11c32012b198837c2c4d Mon Sep 17 00:00:00 2001 From: ben-toogood Date: Tue, 11 Aug 2020 08:38:30 +0100 Subject: [PATCH 1/2] util/kubernetes: add readiness check to deployments (#1923) --- util/kubernetes/client/client.go | 7 +++++++ util/kubernetes/client/templates.go | 16 +++++++++++++++- util/kubernetes/client/types.go | 26 ++++++++++++++++++++------ 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/util/kubernetes/client/client.go b/util/kubernetes/client/client.go index 910ec64d..7b14e08c 100644 --- a/util/kubernetes/client/client.go +++ b/util/kubernetes/client/client.go @@ -321,6 +321,13 @@ func NewDeployment(name, version, typ, namespace string) *Deployment { Name: "service-port", ContainerPort: 8080, }}, + ReadinessProbe: &Probe{ + TCPSocket: TCPSocketAction{ + Port: 8080, + }, + PeriodSeconds: 10, + InitialDelaySeconds: 10, + }, }}, }, }, diff --git a/util/kubernetes/client/templates.go b/util/kubernetes/client/templates.go index 829d6415..61231119 100644 --- a/util/kubernetes/client/templates.go +++ b/util/kubernetes/client/templates.go @@ -92,8 +92,22 @@ spec: name: {{ .Name }} {{- end}} {{- end}} + {{- if .ReadinessProbe }} + {{- with .ReadinessProbe }} + readinessProbe: + {{- with .TCPSocket }} + tcpSocket: + {{- if .Host }} + host: {{ .Host }} + {{- end }} + port: {{ .Port }} + {{- end }} + initialDelaySeconds: {{ .InitialDelaySeconds }} + periodSeconds: {{ .PeriodSeconds }} + {{- end }} + {{- end }} + {{- end }} {{- end }} - {{- end}} ` var serviceTmpl = ` diff --git a/util/kubernetes/client/types.go b/util/kubernetes/client/types.go index cfc40235..41392733 100644 --- a/util/kubernetes/client/types.go +++ b/util/kubernetes/client/types.go @@ -35,12 +35,13 @@ type Condition struct { // Container defined container runtime values type Container struct { - Name string `json:"name"` - Image string `json:"image"` - Env []EnvVar `json:"env,omitempty"` - Command []string `json:"command,omitempty"` - Args []string `json:"args,omitempty"` - Ports []ContainerPort `json:"ports,omitempty"` + Name string `json:"name"` + Image string `json:"image"` + Env []EnvVar `json:"env,omitempty"` + Command []string `json:"command,omitempty"` + Args []string `json:"args,omitempty"` + Ports []ContainerPort `json:"ports,omitempty"` + ReadinessProbe *Probe `json:"readinessProbe,omitempty"` } // DeploymentSpec defines micro deployment spec @@ -220,3 +221,16 @@ type ServiceAccount struct { Metadata *Metadata `json:"metadata,omitempty"` ImagePullSecrets []ImagePullSecret `json:"imagePullSecrets,omitempty"` } + +// Probe describes a health check to be performed against a container to determine whether it is alive or ready to receive traffic. +type Probe struct { + TCPSocket TCPSocketAction `json:"tcpSocket,omitempty"` + PeriodSeconds int `json:"periodSeconds"` + InitialDelaySeconds int `json:"initialDelaySeconds"` +} + +// TCPSocketAction describes an action based on opening a socket +type TCPSocketAction struct { + Host string `json:"host,omitempty"` + Port int `json:"port,omitempty"` +} From d072eb6ff2301e3dd0c18f6968cdde34d2474fba Mon Sep 17 00:00:00 2001 From: Asim Aslam Date: Tue, 11 Aug 2020 10:03:47 +0100 Subject: [PATCH 2/2] Deprecate service (#1924) --- proxy/http/http_test.go | 37 ++--- service/grpc/grpc.go | 129 --------------- service/grpc/grpc_test.go | 155 ------------------ service/grpc/options.go | 21 --- service/grpc/proto/test.pb.go | 203 ------------------------ service/grpc/proto/test.pb.micro.go | 93 ----------- service/grpc/proto/test.proto | 13 -- service/mucp/mucp.go | 122 -------------- service/options.go | 236 ---------------------------- service/service.go | 28 ---- 10 files changed, 15 insertions(+), 1022 deletions(-) delete mode 100644 service/grpc/grpc.go delete mode 100644 service/grpc/grpc_test.go delete mode 100644 service/grpc/options.go delete mode 100644 service/grpc/proto/test.pb.go delete mode 100644 service/grpc/proto/test.pb.micro.go delete mode 100644 service/grpc/proto/test.proto delete mode 100644 service/mucp/mucp.go delete mode 100644 service/options.go delete mode 100644 service/service.go diff --git a/proxy/http/http_test.go b/proxy/http/http_test.go index ace10acf..de2efbd3 100644 --- a/proxy/http/http_test.go +++ b/proxy/http/http_test.go @@ -5,14 +5,13 @@ import ( "fmt" "net" "net/http" - "sync" "testing" "github.com/micro/go-micro/v3/client" + cmucp "github.com/micro/go-micro/v3/client/mucp" "github.com/micro/go-micro/v3/registry/memory" "github.com/micro/go-micro/v3/server" - "github.com/micro/go-micro/v3/service" - "github.com/micro/go-micro/v3/service/mucp" + "github.com/micro/go-micro/v3/server/mucp" ) type testHandler struct{} @@ -53,37 +52,31 @@ func TestHTTPProxy(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - var wg sync.WaitGroup - wg.Add(1) + reg := memory.NewRegistry() // new micro service - service := mucp.NewService( - service.Context(ctx), - service.Name("foobar"), - service.Registry(memory.NewRegistry()), - service.AfterStart(func() error { - wg.Done() - return nil - }), - ) - - // set router - service.Server().Init( + service := mucp.NewServer( + server.Context(ctx), + server.Name("foobar"), + server.Registry(reg), server.WithRouter(p), ) + service.Start() + defer service.Stop() + // run service // server go http.Serve(c, nil) - go service.Run() - // wait till service is started - wg.Wait() + cl := cmucp.NewClient( + client.Registry(reg), + ) for _, test := range testCases { - req := service.Client().NewRequest("foobar", test.rpcEp, map[string]string{"foo": "bar"}, client.WithContentType("application/json")) + req := cl.NewRequest("foobar", test.rpcEp, map[string]string{"foo": "bar"}, client.WithContentType("application/json")) var rsp map[string]string - err := service.Client().Call(ctx, req, &rsp) + err := cl.Call(ctx, req, &rsp) if err != nil && test.err == false { t.Fatal(err) } diff --git a/service/grpc/grpc.go b/service/grpc/grpc.go deleted file mode 100644 index 243e5ae2..00000000 --- a/service/grpc/grpc.go +++ /dev/null @@ -1,129 +0,0 @@ -package grpc - -import ( - "github.com/micro/go-micro/v3/client" - gclient "github.com/micro/go-micro/v3/client/grpc" - "github.com/micro/go-micro/v3/model" - "github.com/micro/go-micro/v3/server" - gserver "github.com/micro/go-micro/v3/server/grpc" - "github.com/micro/go-micro/v3/service" -) - -type grpcService struct { - opts service.Options -} - -func newService(opts ...service.Option) service.Service { - options := service.NewOptions(opts...) - - return &grpcService{ - opts: options, - } -} - -func (s *grpcService) Name() string { - return s.opts.Server.Options().Name -} - -// Init initialises options. Additionally it calls cmd.Init -// which parses command line flags. cmd.Init is only called -// on first Init. -func (s *grpcService) Init(opts ...service.Option) { - // process options - for _, o := range opts { - o(&s.opts) - } -} - -func (s *grpcService) Options() service.Options { - return s.opts -} - -func (s *grpcService) Client() client.Client { - return s.opts.Client -} - -func (s *grpcService) Server() server.Server { - return s.opts.Server -} - -func (s *grpcService) Model() model.Model { - return s.opts.Model -} - -func (s *grpcService) String() string { - return "grpc" -} - -func (s *grpcService) Start() error { - for _, fn := range s.opts.BeforeStart { - if err := fn(); err != nil { - return err - } - } - - if err := s.opts.Server.Start(); err != nil { - return err - } - - for _, fn := range s.opts.AfterStart { - if err := fn(); err != nil { - return err - } - } - - return nil -} - -func (s *grpcService) Stop() error { - var gerr error - - for _, fn := range s.opts.BeforeStop { - if err := fn(); err != nil { - gerr = err - } - } - - if err := s.opts.Server.Stop(); err != nil { - return err - } - - for _, fn := range s.opts.AfterStop { - if err := fn(); err != nil { - gerr = err - } - } - - return gerr -} - -func (s *grpcService) Run() error { - if err := s.Start(); err != nil { - return err - } - - // wait on context cancel - <-s.opts.Context.Done() - - return s.Stop() -} - -// NewService returns a grpc service compatible with go-micro.Service -func NewService(opts ...service.Option) service.Service { - // our grpc client - c := gclient.NewClient() - // our grpc server - s := gserver.NewServer() - - // create options with priority for our opts - options := []service.Option{ - service.Client(c), - service.Server(s), - } - - // append passed in opts - options = append(options, opts...) - - // generate and return a service - return newService(options...) -} diff --git a/service/grpc/grpc_test.go b/service/grpc/grpc_test.go deleted file mode 100644 index faf15336..00000000 --- a/service/grpc/grpc_test.go +++ /dev/null @@ -1,155 +0,0 @@ -package grpc - -import ( - "context" - "crypto/tls" - "sync" - "testing" - "time" - - "github.com/micro/go-micro/v3/registry/memory" - "github.com/micro/go-micro/v3/service" - hello "github.com/micro/go-micro/v3/service/grpc/proto" - mls "github.com/micro/go-micro/v3/util/tls" -) - -type testHandler struct{} - -func (t *testHandler) Call(ctx context.Context, req *hello.Request, rsp *hello.Response) error { - rsp.Msg = "Hello " + req.Name - return nil -} - -func TestGRPCService(t *testing.T) { - var wg sync.WaitGroup - wg.Add(1) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - // create memory registry - r := memory.NewRegistry() - - // create GRPC service - service := NewService( - service.Name("test.service"), - service.Registry(r), - service.AfterStart(func() error { - wg.Done() - return nil - }), - service.Context(ctx), - ) - - // register test handler - hello.RegisterTestHandler(service.Server(), &testHandler{}) - - // run service - errCh := make(chan error, 1) - go func() { - defer close(errCh) - errCh <- service.Run() - }() - - // wait for start - wg.Wait() - - // create client - test := hello.NewTestService("test.service", service.Client()) - - // call service - ctx2, cancel2 := context.WithTimeout(context.Background(), time.Duration(time.Second)) - defer cancel2() - rsp, err := test.Call(ctx2, &hello.Request{ - Name: "John", - }) - if err != nil { - t.Fatal(err) - } - - // check server - select { - case err := <-errCh: - t.Fatal(err) - case <-time.After(time.Second): - break - } - - // check message - if rsp.Msg != "Hello John" { - t.Fatalf("unexpected response %s", rsp.Msg) - } -} - -func TestGRPCTLSService(t *testing.T) { - var wg sync.WaitGroup - wg.Add(1) - - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - - // create memory registry - r := memory.NewRegistry() - - // create cert - cert, err := mls.Certificate("test.service") - if err != nil { - t.Fatal(err) - } - config := &tls.Config{ - Certificates: []tls.Certificate{cert}, - InsecureSkipVerify: true, - } - - // create GRPC service - service := NewService( - service.Name("test.service"), - service.Registry(r), - service.AfterStart(func() error { - wg.Done() - return nil - }), - service.Context(ctx), - // set TLS config - WithTLS(config), - ) - - // register test handler - hello.RegisterTestHandler(service.Server(), &testHandler{}) - - // run service - errCh := make(chan error, 1) - go func() { - defer close(errCh) - errCh <- service.Run() - }() - - // wait for start - wg.Wait() - - // create client - test := hello.NewTestService("test.service", service.Client()) - - // call service - ctx2, cancel2 := context.WithTimeout(context.Background(), time.Duration(time.Second)) - defer cancel2() - rsp, err := test.Call(ctx2, &hello.Request{ - Name: "John", - }) - if err != nil { - t.Fatal(err) - } - - // check server - select { - case err := <-errCh: - t.Fatal(err) - case <-time.After(time.Second): - break - } - - // check message - if rsp.Msg != "Hello John" { - t.Fatalf("unexpected response %s", rsp.Msg) - } -} diff --git a/service/grpc/options.go b/service/grpc/options.go deleted file mode 100644 index 4aa088b2..00000000 --- a/service/grpc/options.go +++ /dev/null @@ -1,21 +0,0 @@ -package grpc - -import ( - "crypto/tls" - - gc "github.com/micro/go-micro/v3/client/grpc" - gs "github.com/micro/go-micro/v3/server/grpc" - "github.com/micro/go-micro/v3/service" -) - -// WithTLS sets the TLS config for the service -func WithTLS(t *tls.Config) service.Option { - return func(o *service.Options) { - o.Client.Init( - gc.AuthTLS(t), - ) - o.Server.Init( - gs.AuthTLS(t), - ) - } -} diff --git a/service/grpc/proto/test.pb.go b/service/grpc/proto/test.pb.go deleted file mode 100644 index 7ce3f3c4..00000000 --- a/service/grpc/proto/test.pb.go +++ /dev/null @@ -1,203 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: service/grpc/proto/test.proto - -package test - -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" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -type Request struct { - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Request) Reset() { *m = Request{} } -func (m *Request) String() string { return proto.CompactTextString(m) } -func (*Request) ProtoMessage() {} -func (*Request) Descriptor() ([]byte, []int) { - return fileDescriptor_06b01994cb662112, []int{0} -} - -func (m *Request) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Request.Unmarshal(m, b) -} -func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Request.Marshal(b, m, deterministic) -} -func (m *Request) XXX_Merge(src proto.Message) { - xxx_messageInfo_Request.Merge(m, src) -} -func (m *Request) XXX_Size() int { - return xxx_messageInfo_Request.Size(m) -} -func (m *Request) XXX_DiscardUnknown() { - xxx_messageInfo_Request.DiscardUnknown(m) -} - -var xxx_messageInfo_Request proto.InternalMessageInfo - -func (m *Request) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -type Response struct { - Msg string `protobuf:"bytes,1,opt,name=msg,proto3" json:"msg,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Response) Reset() { *m = Response{} } -func (m *Response) String() string { return proto.CompactTextString(m) } -func (*Response) ProtoMessage() {} -func (*Response) Descriptor() ([]byte, []int) { - return fileDescriptor_06b01994cb662112, []int{1} -} - -func (m *Response) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Response.Unmarshal(m, b) -} -func (m *Response) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Response.Marshal(b, m, deterministic) -} -func (m *Response) XXX_Merge(src proto.Message) { - xxx_messageInfo_Response.Merge(m, src) -} -func (m *Response) XXX_Size() int { - return xxx_messageInfo_Response.Size(m) -} -func (m *Response) XXX_DiscardUnknown() { - xxx_messageInfo_Response.DiscardUnknown(m) -} - -var xxx_messageInfo_Response proto.InternalMessageInfo - -func (m *Response) GetMsg() string { - if m != nil { - return m.Msg - } - return "" -} - -func init() { - proto.RegisterType((*Request)(nil), "Request") - proto.RegisterType((*Response)(nil), "Response") -} - -func init() { proto.RegisterFile("service/grpc/proto/test.proto", fileDescriptor_06b01994cb662112) } - -var fileDescriptor_06b01994cb662112 = []byte{ - // 133 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x2d, 0x4e, 0x2d, 0x2a, - 0xcb, 0x4c, 0x4e, 0xd5, 0x4f, 0x2f, 0x2a, 0x48, 0xd6, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0xd7, 0x2f, - 0x49, 0x2d, 0x2e, 0xd1, 0x03, 0x33, 0x95, 0x64, 0xb9, 0xd8, 0x83, 0x52, 0x0b, 0x4b, 0x53, 0x8b, - 0x4b, 0x84, 0x84, 0xb8, 0x58, 0xf2, 0x12, 0x73, 0x53, 0x25, 0x18, 0x15, 0x18, 0x35, 0x38, 0x83, - 0xc0, 0x6c, 0x25, 0x19, 0x2e, 0x8e, 0xa0, 0xd4, 0xe2, 0x82, 0xfc, 0xbc, 0xe2, 0x54, 0x21, 0x01, - 0x2e, 0xe6, 0xdc, 0xe2, 0x74, 0xa8, 0x34, 0x88, 0x69, 0xa4, 0xca, 0xc5, 0x12, 0x02, 0xd2, 0x29, - 0xcb, 0xc5, 0xe2, 0x9c, 0x98, 0x93, 0x23, 0xc4, 0xa1, 0x07, 0x35, 0x4b, 0x8a, 0x53, 0x0f, 0xa6, - 0x4d, 0x89, 0x21, 0x89, 0x0d, 0x6c, 0x95, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0xe6, 0x7f, 0x80, - 0xd4, 0x8b, 0x00, 0x00, 0x00, -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// TestClient is the client API for Test service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. -type TestClient interface { - Call(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) -} - -type testClient struct { - cc *grpc.ClientConn -} - -func NewTestClient(cc *grpc.ClientConn) TestClient { - return &testClient{cc} -} - -func (c *testClient) Call(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) { - out := new(Response) - err := c.cc.Invoke(ctx, "/Test/Call", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// TestServer is the server API for Test service. -type TestServer interface { - Call(context.Context, *Request) (*Response, error) -} - -// UnimplementedTestServer can be embedded to have forward compatible implementations. -type UnimplementedTestServer struct { -} - -func (*UnimplementedTestServer) Call(ctx context.Context, req *Request) (*Response, error) { - return nil, status.Errorf(codes.Unimplemented, "method Call not implemented") -} - -func RegisterTestServer(s *grpc.Server, srv TestServer) { - s.RegisterService(&_Test_serviceDesc, srv) -} - -func _Test_Call_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Request) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TestServer).Call(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/Test/Call", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TestServer).Call(ctx, req.(*Request)) - } - return interceptor(ctx, in, info, handler) -} - -var _Test_serviceDesc = grpc.ServiceDesc{ - ServiceName: "Test", - HandlerType: (*TestServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Call", - Handler: _Test_Call_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "service/grpc/proto/test.proto", -} diff --git a/service/grpc/proto/test.pb.micro.go b/service/grpc/proto/test.pb.micro.go deleted file mode 100644 index e35dbeff..00000000 --- a/service/grpc/proto/test.pb.micro.go +++ /dev/null @@ -1,93 +0,0 @@ -// Code generated by protoc-gen-micro. DO NOT EDIT. -// source: service/grpc/proto/test.proto - -package test - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" -) - -import ( - context "context" - api "github.com/micro/go-micro/v3/api" - client "github.com/micro/go-micro/v3/client" - server "github.com/micro/go-micro/v3/server" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// Reference imports to suppress errors if they are not otherwise used. -var _ api.Endpoint -var _ context.Context -var _ client.Option -var _ server.Option - -// Api Endpoints for Test service - -func NewTestEndpoints() []*api.Endpoint { - return []*api.Endpoint{} -} - -// Client API for Test service - -type TestService interface { - Call(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) -} - -type testService struct { - c client.Client - name string -} - -func NewTestService(name string, c client.Client) TestService { - return &testService{ - c: c, - name: name, - } -} - -func (c *testService) Call(ctx context.Context, in *Request, opts ...client.CallOption) (*Response, error) { - req := c.c.NewRequest(c.name, "Test.Call", in) - out := new(Response) - err := c.c.Call(ctx, req, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Test service - -type TestHandler interface { - Call(context.Context, *Request, *Response) error -} - -func RegisterTestHandler(s server.Server, hdlr TestHandler, opts ...server.HandlerOption) error { - type test interface { - Call(ctx context.Context, in *Request, out *Response) error - } - type Test struct { - test - } - h := &testHandler{hdlr} - return s.Handle(s.NewHandler(&Test{h}, opts...)) -} - -type testHandler struct { - TestHandler -} - -func (h *testHandler) Call(ctx context.Context, in *Request, out *Response) error { - return h.TestHandler.Call(ctx, in, out) -} diff --git a/service/grpc/proto/test.proto b/service/grpc/proto/test.proto deleted file mode 100644 index 0dbbea9b..00000000 --- a/service/grpc/proto/test.proto +++ /dev/null @@ -1,13 +0,0 @@ -syntax = "proto3"; - -service Test { - rpc Call(Request) returns (Response) {} -} - -message Request { - string name = 1; -} - -message Response { - string msg = 1; -} diff --git a/service/mucp/mucp.go b/service/mucp/mucp.go deleted file mode 100644 index 38093069..00000000 --- a/service/mucp/mucp.go +++ /dev/null @@ -1,122 +0,0 @@ -// Package mucp initialises a mucp service -package mucp - -import ( - "github.com/micro/go-micro/v3/client" - cmucp "github.com/micro/go-micro/v3/client/mucp" - "github.com/micro/go-micro/v3/model" - "github.com/micro/go-micro/v3/server" - smucp "github.com/micro/go-micro/v3/server/mucp" - "github.com/micro/go-micro/v3/service" -) - -type mucpService struct { - opts service.Options -} - -func newService(opts ...service.Option) service.Service { - options := service.NewOptions(opts...) - - return &mucpService{ - opts: options, - } -} - -func (s *mucpService) Name() string { - return s.opts.Server.Options().Name -} - -// Init initialises options. Additionally it calls cmd.Init -// which parses command line flags. cmd.Init is only called -// on first Init. -func (s *mucpService) Init(opts ...service.Option) { - // process options - for _, o := range opts { - o(&s.opts) - } -} - -func (s *mucpService) Options() service.Options { - return s.opts -} - -func (s *mucpService) Client() client.Client { - return s.opts.Client -} - -func (s *mucpService) Server() server.Server { - return s.opts.Server -} - -func (s *mucpService) Model() model.Model { - return s.opts.Model -} - -func (s *mucpService) String() string { - return "mucp" -} - -func (s *mucpService) Start() error { - for _, fn := range s.opts.BeforeStart { - if err := fn(); err != nil { - return err - } - } - - if err := s.opts.Server.Start(); err != nil { - return err - } - - for _, fn := range s.opts.AfterStart { - if err := fn(); err != nil { - return err - } - } - - return nil -} - -func (s *mucpService) Stop() error { - var gerr error - - for _, fn := range s.opts.BeforeStop { - if err := fn(); err != nil { - gerr = err - } - } - - if err := s.opts.Server.Stop(); err != nil { - return err - } - - for _, fn := range s.opts.AfterStop { - if err := fn(); err != nil { - gerr = err - } - } - - return gerr -} - -func (s *mucpService) Run() error { - if err := s.Start(); err != nil { - return err - } - - // wait on context cancel - <-s.opts.Context.Done() - - return s.Stop() -} - -// NewService returns a new mucp service -func NewService(opts ...service.Option) service.Service { - options := []service.Option{ - service.Client(cmucp.NewClient()), - service.Server(smucp.NewServer()), - } - - options = append(options, opts...) - - return newService(options...) -} diff --git a/service/options.go b/service/options.go deleted file mode 100644 index 0829e27b..00000000 --- a/service/options.go +++ /dev/null @@ -1,236 +0,0 @@ -package service - -import ( - "context" - "time" - - "github.com/micro/go-micro/v3/broker" - "github.com/micro/go-micro/v3/broker/http" - "github.com/micro/go-micro/v3/client" - mucpClient "github.com/micro/go-micro/v3/client/mucp" - "github.com/micro/go-micro/v3/model" - "github.com/micro/go-micro/v3/registry" - "github.com/micro/go-micro/v3/registry/mdns" - "github.com/micro/go-micro/v3/server" - mucpServer "github.com/micro/go-micro/v3/server/mucp" - "github.com/micro/go-micro/v3/transport" - thttp "github.com/micro/go-micro/v3/transport/http" -) - -type Options struct { - Broker broker.Broker - Client client.Client - Server server.Server - Model model.Model - Registry registry.Registry - Transport transport.Transport - - // Before and After funcs - BeforeStart []func() error - BeforeStop []func() error - AfterStart []func() error - AfterStop []func() error - - // Other options for implementations of the interface - // can be stored in a context - Context context.Context -} - -type Option func(*Options) - -func NewOptions(opts ...Option) Options { - opt := Options{ - Broker: http.NewBroker(), - Client: mucpClient.NewClient(), - Server: mucpServer.NewServer(), - Registry: mdns.NewRegistry(), - Transport: thttp.NewTransport(), - Context: context.Background(), - } - - for _, o := range opts { - o(&opt) - } - - return opt -} - -func Broker(b broker.Broker) Option { - return func(o *Options) { - o.Broker = b - // Update Client and Server - o.Client.Init(client.Broker(b)) - o.Server.Init(server.Broker(b)) - } -} - -func Client(c client.Client) Option { - return func(o *Options) { - o.Client = c - } -} - -// Context specifies a context for the service. -// Can be used to signal shutdown of the service. -// Can be used for extra option values. -func Context(ctx context.Context) Option { - return func(o *Options) { - o.Context = ctx - } -} - -// Server sets the server for handling requests -func Server(s server.Server) Option { - return func(o *Options) { - o.Server = s - } -} - -// Model sets the model for data access -func Model(m model.Model) Option { - return func(o *Options) { - o.Model = m - } -} - -// Registry sets the registry for the service -// and the underlying components -func Registry(r registry.Registry) Option { - return func(o *Options) { - o.Registry = r - // Update server - o.Server.Init(server.Registry(r)) - // Update Broker - o.Broker.Init(broker.Registry(r)) - // Update router - o.Client.Init(client.Registry(r)) - } -} - -// Transport sets the transport for the service -// and the underlying components -func Transport(t transport.Transport) Option { - return func(o *Options) { - o.Transport = t - // Update Client and Server - o.Client.Init(client.Transport(t)) - o.Server.Init(server.Transport(t)) - } -} - -// Convenience options - -// Address sets the address of the server -func Address(addr string) Option { - return func(o *Options) { - o.Server.Init(server.Address(addr)) - } -} - -// Name of the service -func Name(n string) Option { - return func(o *Options) { - o.Server.Init(server.Name(n)) - } -} - -// Version of the service -func Version(v string) Option { - return func(o *Options) { - o.Server.Init(server.Version(v)) - } -} - -// Metadata associated with the service -func Metadata(md map[string]string) Option { - return func(o *Options) { - o.Server.Init(server.Metadata(md)) - } -} - -// RegisterTTL specifies the TTL to use when registering the service -func RegisterTTL(t time.Duration) Option { - return func(o *Options) { - o.Server.Init(server.RegisterTTL(t)) - } -} - -// RegisterInterval specifies the interval on which to re-register -func RegisterInterval(t time.Duration) Option { - return func(o *Options) { - o.Server.Init(server.RegisterInterval(t)) - } -} - -// WrapClient is a convenience method for wrapping a Client with -// some middleware component. A list of wrappers can be provided. -// Wrappers are applied in reverse order so the last is executed first. -func WrapClient(w ...client.Wrapper) Option { - return func(o *Options) { - // apply in reverse - for i := len(w); i > 0; i-- { - o.Client = w[i-1](o.Client) - } - } -} - -// WrapCall is a convenience method for wrapping a Client CallFunc -func WrapCall(w ...client.CallWrapper) Option { - return func(o *Options) { - o.Client.Init(client.WrapCall(w...)) - } -} - -// WrapHandler adds a handler Wrapper to a list of options passed into the server -func WrapHandler(w ...server.HandlerWrapper) Option { - return func(o *Options) { - var wrappers []server.Option - - for _, wrap := range w { - wrappers = append(wrappers, server.WrapHandler(wrap)) - } - - // Init once - o.Server.Init(wrappers...) - } -} - -// WrapSubscriber adds a subscriber Wrapper to a list of options passed into the server -func WrapSubscriber(w ...server.SubscriberWrapper) Option { - return func(o *Options) { - var wrappers []server.Option - - for _, wrap := range w { - wrappers = append(wrappers, server.WrapSubscriber(wrap)) - } - - // Init once - o.Server.Init(wrappers...) - } -} - -// Before and Afters - -func BeforeStart(fn func() error) Option { - return func(o *Options) { - o.BeforeStart = append(o.BeforeStart, fn) - } -} - -func BeforeStop(fn func() error) Option { - return func(o *Options) { - o.BeforeStop = append(o.BeforeStop, fn) - } -} - -func AfterStart(fn func() error) Option { - return func(o *Options) { - o.AfterStart = append(o.AfterStart, fn) - } -} - -func AfterStop(fn func() error) Option { - return func(o *Options) { - o.AfterStop = append(o.AfterStop, fn) - } -} diff --git a/service/service.go b/service/service.go deleted file mode 100644 index c9ad69f5..00000000 --- a/service/service.go +++ /dev/null @@ -1,28 +0,0 @@ -// Package service encapsulates the client, server and other interfaces to provide a complete micro service. -package service - -import ( - "github.com/micro/go-micro/v3/client" - "github.com/micro/go-micro/v3/model" - "github.com/micro/go-micro/v3/server" -) - -// Service is an interface for a micro service -type Service interface { - // The service name - Name() string - // Init initialises options - Init(...Option) - // Options returns the current options - Options() Options - // Client is used to call services - Client() client.Client - // Server is for handling requests and events - Server() server.Server - // Model is used to access data - Model() model.Model - // Run the service - Run() error - // The service implementation - String() string -}