micro-register-service/service.go

179 lines
4.3 KiB
Go
Raw Normal View History

// Package service uses the registry service
package service
import (
"context"
"fmt"
"time"
pb "github.com/unistack-org/micro-registry-service/v3/proto"
"github.com/unistack-org/micro/v3/client"
"github.com/unistack-org/micro/v3/errors"
"github.com/unistack-org/micro/v3/registry"
)
type serviceRegistry struct {
opts registry.Options
// name of the registry
service string
// address
address []string
// client to call registry
client pb.RegistryService
}
func (s *serviceRegistry) callOpts() []client.CallOption {
var opts []client.CallOption
// set registry address
if len(s.address) > 0 {
opts = append(opts, client.WithAddress(s.address...))
}
// set timeout
if s.opts.Timeout > time.Duration(0) {
opts = append(opts, client.WithRequestTimeout(s.opts.Timeout))
}
return opts
}
func (s *serviceRegistry) Init(opts ...registry.Option) error {
for _, o := range opts {
o(&s.opts)
}
if len(s.opts.Addrs) > 0 {
s.address = s.opts.Addrs
}
var cli client.Client
if s.opts.Context != nil {
if v, ok := s.opts.Context.Value(clientKey{}).(string); ok && v != "" {
s.service = v
}
if v, ok := s.opts.Context.Value(clientKey{}).(client.Client); ok && v != nil {
cli = v
}
}
if cli == nil {
return fmt.Errorf("missing Client option")
}
if s.service == "" {
return fmt.Errorf("missing Service option")
}
s.client = pb.NewRegistryService(s.service, cli)
return nil
}
func (s *serviceRegistry) Options() registry.Options {
return s.opts
}
func (s *serviceRegistry) Connect(ctx context.Context) error {
return nil
}
func (s *serviceRegistry) Disconnect(ctx context.Context) error {
return nil
}
func (s *serviceRegistry) Register(ctx context.Context, srv *registry.Service, opts ...registry.RegisterOption) error {
options := registry.NewRegisterOptions(opts...)
// encode srv into protobuf and pack TTL and domain into it
pbSrv := ToProto(srv)
pbSrv.Options.Ttl = int64(options.TTL.Seconds())
pbSrv.Options.Domain = options.Domain
// register the service
_, err := s.client.Register(ctx, pbSrv, s.callOpts()...)
return err
}
func (s *serviceRegistry) Deregister(ctx context.Context, srv *registry.Service, opts ...registry.DeregisterOption) error {
options := registry.NewDeregisterOptions(opts...)
// encode srv into protobuf and pack domain into it
pbSrv := ToProto(srv)
pbSrv.Options.Domain = options.Domain
// deregister the service
_, err := s.client.Deregister(ctx, pbSrv, s.callOpts()...)
return err
}
func (s *serviceRegistry) GetService(ctx context.Context, name string, opts ...registry.GetOption) ([]*registry.Service, error) {
options := registry.NewGetOptions(opts...)
rsp, err := s.client.GetService(ctx, &pb.GetRequest{
Service: name, Options: &pb.Options{Domain: options.Domain},
}, s.callOpts()...)
if verr, ok := err.(*errors.Error); ok && verr.Code == 404 {
return nil, registry.ErrNotFound
} else if err != nil {
return nil, err
}
services := make([]*registry.Service, 0, len(rsp.Services))
for _, service := range rsp.Services {
services = append(services, ToService(service))
}
return services, nil
}
func (s *serviceRegistry) ListServices(ctx context.Context, opts ...registry.ListOption) ([]*registry.Service, error) {
options := registry.NewListOptions(opts...)
req := &pb.ListRequest{Options: &pb.Options{Domain: options.Domain}}
rsp, err := s.client.ListServices(ctx, req, s.callOpts()...)
if err != nil {
return nil, err
}
services := make([]*registry.Service, 0, len(rsp.Services))
for _, service := range rsp.Services {
services = append(services, ToService(service))
}
return services, nil
}
func (s *serviceRegistry) Watch(ctx context.Context, opts ...registry.WatchOption) (registry.Watcher, error) {
options := registry.NewWatchOptions(opts...)
stream, err := s.client.Watch(ctx, &pb.WatchRequest{
Service: options.Service, Options: &pb.Options{Domain: options.Domain},
}, s.callOpts()...)
if err != nil {
return nil, err
}
return newWatcher(stream), nil
}
func (s *serviceRegistry) String() string {
return "service"
}
// NewRegistry returns a new registry service client
func NewRegistry(opts ...registry.Option) registry.Registry {
options := registry.NewOptions(opts...)
addrs := options.Addrs
if len(addrs) == 0 {
addrs = []string{"127.0.0.1:8000"}
}
return &serviceRegistry{
opts: options,
address: addrs,
}
}