gitee.com/h79/goutils@v1.22.10/discovery/etcd/client.go (about)

     1  package etcd
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"gitee.com/h79/goutils/common/logger"
     7  	"gitee.com/h79/goutils/common/server"
     8  	"gitee.com/h79/goutils/discovery/config"
     9  	"gitee.com/h79/goutils/discovery/resolver"
    10  	"gitee.com/h79/goutils/discovery/resolver/builder"
    11  	"gitee.com/h79/goutils/discovery/service"
    12  	"gitee.com/h79/goutils/discovery/watch"
    13  	clientv3 "go.etcd.io/etcd/client/v3"
    14  )
    15  
    16  var _ service.Client = (*edClient)(nil)
    17  var _ builder.Builder = (*edClient)(nil)
    18  
    19  type edClient struct {
    20  	Base
    21  	node config.Node
    22  }
    23  
    24  func NewClient(conf config.Config, eps config.EndPoints, resol resolver.Resolver) (service.Client, error) {
    25  
    26  	cli, err := NewClient3(&eps, 30)
    27  	if err != nil {
    28  		logger.Error("etcd.client: create client failure,err= %v", err)
    29  		return nil, err
    30  	}
    31  	logger.Info("etcd.client: create client")
    32  
    33  	return NewClientWith(cli, &conf)
    34  }
    35  
    36  func NewClientWith(cli *clientv3.Client, conf *config.Config) (service.Client, error) {
    37  
    38  	b := &edClient{
    39  		Base: Base{
    40  			client:  cli,
    41  			watcher: nil,
    42  		},
    43  		node: conf.Node,
    44  	}
    45  	resolver.Register(b)
    46  	return b, nil
    47  }
    48  
    49  func (cli *edClient) Start() error {
    50  	return nil
    51  }
    52  
    53  func (cli *edClient) Stop() {
    54  }
    55  
    56  // Resolve service.Client and resolver.Builder interface
    57  //
    58  //	https://github.com/grpc/grpc/blob/master/doc/service_config.md
    59  func (cli *edClient) Resolve(target builder.Target) []builder.Address {
    60  
    61  	resp, err := cli.client.Get(context.Background(), target.NameWith(""), clientv3.WithPrefix())
    62  	if err != nil {
    63  		return nil
    64  	}
    65  	addrs := cli.extractAdders(resp)
    66  
    67  	var adders []builder.Address
    68  	for _, data := range addrs {
    69  		s := server.Address{}
    70  		err = json.Unmarshal([]byte(data), &s)
    71  		if err != nil {
    72  			return nil
    73  		}
    74  		s.Adjust()
    75  		address := builder.Address{Addr: s.To(), ServerName: target.SchemeWith("")}
    76  		adders = append(adders, address)
    77  	}
    78  	return adders
    79  }
    80  
    81  func (cli *edClient) extractAdders(resp *clientv3.GetResponse) []string {
    82  	adders := make([]string, 0)
    83  	if resp == nil || resp.Kvs == nil {
    84  		return adders
    85  	}
    86  	for i := range resp.Kvs {
    87  		kvs := resp.Kvs[i]
    88  		if v := kvs.Value; v != nil {
    89  			if cli.watcher != nil {
    90  				data := service.Data{Key: service.NewKey(string(kvs.Key)), Value: string(kvs.Value)}
    91  				cli.watcher.Changed(watch.NewChanged(data, watch.Put))
    92  			}
    93  			adders = append(adders, string(v))
    94  		}
    95  	}
    96  	return adders
    97  }
    98  
    99  // Build
   100  // builder.Builder interface
   101  func (cli *edClient) Build(target builder.Target, cc builder.Connector) (builder.Resolver, error) {
   102  
   103  	logger.Info("def.Client: Build target: %+v", target)
   104  
   105  	cr := resolver.NewResolver(target, cc, cli)
   106  
   107  	return cr, nil
   108  }
   109  
   110  // Scheme
   111  // builder.Builder interface
   112  func (cli *edClient) Scheme() string {
   113  	return cli.node.Scheme
   114  }
   115  
   116  // Type
   117  // builder.Builder interface
   118  func (cli *edClient) Type() string {
   119  	return cli.node.Type
   120  }