github.com/isyscore/isc-gobase@v1.5.3-0.20231218061332-cbc7451899e9/extend/etcd/etcd.go (about)

     1  package etcd
     2  
     3  import (
     4  	"context"
     5  	"github.com/golang/glog"
     6  	"github.com/isyscore/isc-gobase/bean"
     7  	"github.com/isyscore/isc-gobase/config"
     8  	"github.com/isyscore/isc-gobase/constants"
     9  	"github.com/isyscore/isc-gobase/goid"
    10  	"github.com/isyscore/isc-gobase/isc"
    11  	"github.com/isyscore/isc-gobase/logger"
    12  	//"github.com/isyscore/isc-gobase/tracing"
    13  	etcdClientV3 "go.etcd.io/etcd/client/v3"
    14  	"go.uber.org/zap"
    15  	"google.golang.org/grpc"
    16  	"io"
    17  	"time"
    18  )
    19  
    20  var EtcdHooks []GobaseEtcdHook
    21  
    22  func init() {
    23  	config.LoadConfig()
    24  
    25  	if config.ExistConfigFile() && config.GetValueBoolDefault("base.etcd.enable", false) {
    26  		err := config.GetValueObject("base.etcd", &config.EtcdCfg)
    27  		if err != nil {
    28  			logger.Warn("读取etcd配置异常")
    29  			return
    30  		}
    31  	}
    32  
    33  	EtcdHooks = []GobaseEtcdHook{}
    34  	//grpclog.SetLoggerV2(&EtcdLogger{})
    35  }
    36  
    37  func NewEtcdClient() (*EtcdClientWrap, error) {
    38  	if !config.GetValueBoolDefault("base.etcd.enable", false) {
    39  		logger.Error("etcd没有配置,请先配置")
    40  		return nil, nil
    41  	}
    42  
    43  	// 客户端配置
    44  	etcdCfg := etcdClientV3.Config{
    45  		Endpoints:           config.EtcdCfg.Endpoints,
    46  		Username:            config.EtcdCfg.Username,
    47  		Password:            config.EtcdCfg.Password,
    48  		MaxCallSendMsgSize:  config.EtcdCfg.MaxCallSendMsgSize,
    49  		MaxCallRecvMsgSize:  config.EtcdCfg.MaxCallRecvMsgSize,
    50  		RejectOldCluster:    config.EtcdCfg.RejectOldCluster,
    51  		PermitWithoutStream: config.EtcdCfg.PermitWithoutStream,
    52  	}
    53  
    54  	if config.EtcdCfg.AutoSyncInterval != "" {
    55  		t, err := time.ParseDuration(config.EtcdCfg.AutoSyncInterval)
    56  		if err != nil {
    57  			logger.Warn("读取配置【base.etcd.auto-sync-interval】异常", err)
    58  		} else {
    59  			etcdCfg.AutoSyncInterval = t
    60  		}
    61  	}
    62  
    63  	if config.EtcdCfg.DialTimeout != "" {
    64  		t, err := time.ParseDuration(config.EtcdCfg.DialTimeout)
    65  		if err != nil {
    66  			logger.Warn("读取配置【base.etcd.dial-timeout】异常", err)
    67  		} else {
    68  			etcdCfg.DialTimeout = t
    69  		}
    70  	}
    71  
    72  	if config.EtcdCfg.DialKeepAliveTime != "" {
    73  		t, err := time.ParseDuration(config.EtcdCfg.DialKeepAliveTime)
    74  		if err != nil {
    75  			logger.Warn("读取配置【base.etcd.dial-keep-alive-time】异常", err)
    76  		} else {
    77  			etcdCfg.DialKeepAliveTime = t
    78  		}
    79  	}
    80  
    81  	if config.EtcdCfg.DialKeepAliveTimeout != "" {
    82  		t, err := time.ParseDuration(config.EtcdCfg.DialKeepAliveTimeout)
    83  		if err != nil {
    84  			logger.Warn("读取配置【base.etcd.dial-keep-alive-timeout】异常", err)
    85  		} else {
    86  			etcdCfg.DialKeepAliveTimeout = t
    87  		}
    88  	}
    89  
    90  	var etcdClient *etcdClientV3.Client
    91  	if config.EtcdCfg.DialRetry == "" {
    92  		_etcdClient, err := etcdClientV3.New(etcdCfg)
    93  		if err != nil {
    94  			logger.Error("生成etcd-client失败:%v", err.Error())
    95  			return nil, err
    96  		}
    97  		etcdClient = _etcdClient
    98  	} else if config.EtcdCfg.DialRetry == "always" {
    99  		for {
   100  			_etcdClient, err := etcdClientV3.New(etcdCfg)
   101  			if err != nil {
   102  				logger.Error("尝试连接etcd 失败:%v", err.Error())
   103  				continue
   104  			}
   105  			etcdClient = _etcdClient
   106  			break
   107  		}
   108  	} else {
   109  		retryTimes := isc.ToInt(config.EtcdCfg.DialRetry)
   110  		for i := 0; i < retryTimes; i++ {
   111  			_etcdClient, err := etcdClientV3.New(etcdCfg)
   112  			if err != nil {
   113  				logger.Error("尝试连接etcd 第[%v]次失败:%v", i+1, err.Error())
   114  				continue
   115  			}
   116  			etcdClient = _etcdClient
   117  			break
   118  		}
   119  	}
   120  
   121  	var etcdClientWrap EtcdClientWrap
   122  	etcdClientWrap = EtcdClientWrap{Client: etcdClient, etcdHooks: EtcdHooks}
   123  	bean.AddBean(constants.BeanNameEtcdPre, &etcdClientWrap)
   124  	return &etcdClientWrap, nil
   125  }
   126  
   127  func NewEtcdClientWithCfg(etcdCfg etcdClientV3.Config) (*EtcdClientWrap, error) {
   128  	if !config.GetValueBoolDefault("base.etcd.enable", false) {
   129  		logger.Error("etcd没有配置,请先配置")
   130  		return nil, nil
   131  	}
   132  
   133  	etcdClient, err := etcdClientV3.New(etcdCfg)
   134  	if err != nil {
   135  		logger.Error("生成etcd-client失败:%v", err.Error())
   136  		return nil, err
   137  	}
   138  
   139  	var etcdClientWrap EtcdClientWrap
   140  	etcdClientWrap = EtcdClientWrap{Client: etcdClient, etcdHooks: EtcdHooks}
   141  	bean.AddBean(constants.BeanNameEtcdPre, &etcdClientWrap)
   142  	return &etcdClientWrap, nil
   143  }
   144  
   145  func AddEtcdHook(hook GobaseEtcdHook) {
   146  	EtcdHooks = append(EtcdHooks, hook)
   147  	client := bean.GetBean(constants.BeanNameEtcdPre)
   148  	if client == nil {
   149  		return
   150  	}
   151  	etcdClient := client.(*EtcdClientWrap)
   152  	etcdClient.AddHook(hook)
   153  }
   154  
   155  type EtcdClientWrap struct {
   156  	*etcdClientV3.Client
   157  	etcdHooks []GobaseEtcdHook
   158  }
   159  
   160  type GobaseEtcdHook interface {
   161  	Before(ctx context.Context, op etcdClientV3.Op) context.Context
   162  	After(ctx context.Context, op etcdClientV3.Op, pRsp any, err error)
   163  }
   164  
   165  func (etcdWrap *EtcdClientWrap) AddHook(etcdHook GobaseEtcdHook) {
   166  	etcdWrap.etcdHooks = append(etcdWrap.etcdHooks, etcdHook)
   167  }
   168  
   169  func (etcdWrap *EtcdClientWrap) Put(ctx context.Context, key, val string, opts ...etcdClientV3.OpOption) (*etcdClientV3.PutResponse, error) {
   170  	op := etcdClientV3.OpPut(key, val, opts...)
   171  	for _, hook := range etcdWrap.etcdHooks {
   172  		ctx = hook.Before(ctx, op)
   173  	}
   174  
   175  	rsp, err := etcdWrap.Client.Put(ctx, key, val, opts...)
   176  	for _, hook := range etcdWrap.etcdHooks {
   177  		hook.After(ctx, op, rsp, err)
   178  	}
   179  	return rsp, err
   180  }
   181  
   182  func (etcdWrap *EtcdClientWrap) Get(ctx context.Context, key string, opts ...etcdClientV3.OpOption) (*etcdClientV3.GetResponse, error) {
   183  	op := etcdClientV3.OpGet(key, opts...)
   184  	for _, hook := range etcdWrap.etcdHooks {
   185  		ctx = hook.Before(ctx, op)
   186  	}
   187  	rsp, err := etcdWrap.Client.Get(ctx, key, opts...)
   188  	for _, hook := range etcdWrap.etcdHooks {
   189  		hook.After(ctx, op, rsp, err)
   190  	}
   191  	return rsp, err
   192  }
   193  
   194  func (etcdWrap *EtcdClientWrap) Delete(ctx context.Context, key string, opts ...etcdClientV3.OpOption) (*etcdClientV3.DeleteResponse, error) {
   195  	op := etcdClientV3.OpDelete(key, opts...)
   196  	for _, hook := range etcdWrap.etcdHooks {
   197  		ctx = hook.Before(ctx, op)
   198  	}
   199  
   200  	rsp, err := etcdWrap.Client.Delete(ctx, key, opts...)
   201  	for _, hook := range etcdWrap.etcdHooks {
   202  		hook.After(ctx, op, rsp, err)
   203  	}
   204  	return rsp, err
   205  }
   206  
   207  func (etcdWrap *EtcdClientWrap) Compact(ctx context.Context, rev int64, opts ...etcdClientV3.CompactOption) (*etcdClientV3.CompactResponse, error) {
   208  	return etcdWrap.Client.Compact(ctx, rev, opts...)
   209  }
   210  
   211  func (etcdWrap *EtcdClientWrap) Do(ctx context.Context, op etcdClientV3.Op) (etcdClientV3.OpResponse, error) {
   212  	for _, hook := range etcdWrap.etcdHooks {
   213  		ctx = hook.Before(ctx, op)
   214  	}
   215  	rsp, err := etcdWrap.Client.Do(ctx, op)
   216  	for _, hook := range etcdWrap.etcdHooks {
   217  		goid.Go(func() {
   218  			hook.After(ctx, op, rsp, err)
   219  		})
   220  	}
   221  	return rsp, err
   222  }
   223  
   224  func (etcdWrap *EtcdClientWrap) Txn(ctx context.Context) etcdClientV3.Txn {
   225  	return etcdWrap.Client.Txn(ctx)
   226  }
   227  
   228  func (etcdWrap *EtcdClientWrap) MemberList(ctx context.Context) (*etcdClientV3.MemberListResponse, error) {
   229  	return etcdWrap.Client.MemberList(ctx)
   230  }
   231  
   232  func (etcdWrap *EtcdClientWrap) MemberAdd(ctx context.Context, peerAddrs []string) (*etcdClientV3.MemberAddResponse, error) {
   233  	return etcdWrap.Client.MemberAdd(ctx, peerAddrs)
   234  }
   235  
   236  func (etcdWrap *EtcdClientWrap) MemberAddAsLearner(ctx context.Context, peerAddrs []string) (*etcdClientV3.MemberAddResponse, error) {
   237  	return etcdWrap.Client.MemberAddAsLearner(ctx, peerAddrs)
   238  }
   239  
   240  func (etcdWrap *EtcdClientWrap) MemberRemove(ctx context.Context, id uint64) (*etcdClientV3.MemberRemoveResponse, error) {
   241  	return etcdWrap.Client.MemberRemove(ctx, id)
   242  }
   243  
   244  func (etcdWrap *EtcdClientWrap) MemberPromote(ctx context.Context, id uint64) (*etcdClientV3.MemberPromoteResponse, error) {
   245  	return etcdWrap.Client.MemberPromote(ctx, id)
   246  }
   247  
   248  func (etcdWrap *EtcdClientWrap) Grant(ctx context.Context, ttl int64) (*etcdClientV3.LeaseGrantResponse, error) {
   249  	return etcdWrap.Client.Grant(ctx, ttl)
   250  }
   251  
   252  func (etcdWrap *EtcdClientWrap) Revoke(ctx context.Context, id etcdClientV3.LeaseID) (*etcdClientV3.LeaseRevokeResponse, error) {
   253  	return etcdWrap.Client.Revoke(ctx, id)
   254  }
   255  
   256  func (etcdWrap *EtcdClientWrap) TimeToLive(ctx context.Context, id etcdClientV3.LeaseID, opts ...etcdClientV3.LeaseOption) (*etcdClientV3.LeaseTimeToLiveResponse, error) {
   257  	return etcdWrap.Client.TimeToLive(ctx, id, opts...)
   258  }
   259  
   260  func (etcdWrap *EtcdClientWrap) Leases(ctx context.Context) (*etcdClientV3.LeaseLeasesResponse, error) {
   261  	return etcdWrap.Client.Leases(ctx)
   262  }
   263  
   264  func (etcdWrap *EtcdClientWrap) KeepAlive(ctx context.Context, id etcdClientV3.LeaseID) (<-chan *etcdClientV3.LeaseKeepAliveResponse, error) {
   265  	return etcdWrap.Client.KeepAlive(ctx, id)
   266  }
   267  
   268  func (etcdWrap *EtcdClientWrap) KeepAliveOnce(ctx context.Context, id etcdClientV3.LeaseID) (*etcdClientV3.LeaseKeepAliveResponse, error) {
   269  	return etcdWrap.Client.KeepAliveOnce(ctx, id)
   270  }
   271  
   272  func (etcdWrap *EtcdClientWrap) Close() error {
   273  	return etcdWrap.Client.Close()
   274  }
   275  
   276  func (etcdWrap *EtcdClientWrap) Watch(ctx context.Context, key string, opts ...etcdClientV3.OpOption) etcdClientV3.WatchChan {
   277  	return etcdWrap.Client.Watch(ctx, key, opts...)
   278  }
   279  
   280  func (etcdWrap *EtcdClientWrap) RequestProgress(ctx context.Context) error {
   281  	return etcdWrap.Client.RequestProgress(ctx)
   282  }
   283  
   284  func (etcdWrap *EtcdClientWrap)Authenticate(ctx context.Context, name string, password string) (*etcdClientV3.AuthenticateResponse, error) {
   285  	return etcdWrap.Client.Authenticate(ctx, name, password)
   286  }
   287  
   288  func (etcdWrap *EtcdClientWrap) AuthEnable(ctx context.Context) (*etcdClientV3.AuthEnableResponse, error) {
   289  	return etcdWrap.Client.AuthEnable(ctx)
   290  }
   291  
   292  func (etcdWrap *EtcdClientWrap) AuthDisable(ctx context.Context) (*etcdClientV3.AuthDisableResponse, error) {
   293  	return etcdWrap.Client.AuthDisable(ctx)
   294  }
   295  
   296  func (etcdWrap *EtcdClientWrap) AuthStatus(ctx context.Context) (*etcdClientV3.AuthStatusResponse, error) {
   297  	return etcdWrap.Client.AuthStatus(ctx)
   298  }
   299  
   300  func (etcdWrap *EtcdClientWrap) UserAdd(ctx context.Context, name string, password string) (*etcdClientV3.AuthUserAddResponse, error) {
   301  	return etcdWrap.Client.UserAdd(ctx, name, password)
   302  }
   303  
   304  func (etcdWrap *EtcdClientWrap) UserAddWithOptions(ctx context.Context, name string, password string, opt *etcdClientV3.UserAddOptions) (*etcdClientV3.AuthUserAddResponse, error) {
   305  	return etcdWrap.Client.UserAddWithOptions(ctx, name, password, opt)
   306  }
   307  
   308  func (etcdWrap *EtcdClientWrap) UserDelete(ctx context.Context, name string) (*etcdClientV3.AuthUserDeleteResponse, error) {
   309  	return etcdWrap.Client.UserDelete(ctx, name)
   310  }
   311  
   312  func (etcdWrap *EtcdClientWrap) UserChangePassword(ctx context.Context, name string, password string) (*etcdClientV3.AuthUserChangePasswordResponse, error) {
   313  	return etcdWrap.Client.UserChangePassword(ctx, name, password)
   314  }
   315  
   316  func (etcdWrap *EtcdClientWrap) UserGrantRole(ctx context.Context, user string, role string) (*etcdClientV3.AuthUserGrantRoleResponse, error) {
   317  	return etcdWrap.Client.UserGrantRole(ctx, user, role)
   318  }
   319  
   320  func (etcdWrap *EtcdClientWrap) UserGet(ctx context.Context, name string) (*etcdClientV3.AuthUserGetResponse, error) {
   321  	return etcdWrap.Client.UserGet(ctx, name)
   322  }
   323  
   324  func (etcdWrap *EtcdClientWrap) UserList(ctx context.Context) (*etcdClientV3.AuthUserListResponse, error) {
   325  	return etcdWrap.Client.UserList(ctx)
   326  }
   327  
   328  func (etcdWrap *EtcdClientWrap) UserRevokeRole(ctx context.Context, name string, role string) (*etcdClientV3.AuthUserRevokeRoleResponse, error) {
   329  	return etcdWrap.Client.UserRevokeRole(ctx, name, role)
   330  }
   331  
   332  func (etcdWrap *EtcdClientWrap) RoleAdd(ctx context.Context, name string) (*etcdClientV3.AuthRoleAddResponse, error) {
   333  	return etcdWrap.Client.RoleAdd(ctx, name)
   334  }
   335  
   336  func (etcdWrap *EtcdClientWrap) RoleGrantPermission(ctx context.Context, name string, key, rangeEnd string, permType etcdClientV3.PermissionType) (*etcdClientV3.AuthRoleGrantPermissionResponse, error) {
   337  	return etcdWrap.Client.RoleGrantPermission(ctx, name, key, rangeEnd, permType)
   338  }
   339  
   340  func (etcdWrap *EtcdClientWrap) RoleGet(ctx context.Context, role string) (*etcdClientV3.AuthRoleGetResponse, error) {
   341  	return etcdWrap.Client.RoleGet(ctx, role)
   342  }
   343  
   344  func (etcdWrap *EtcdClientWrap) RoleList(ctx context.Context) (*etcdClientV3.AuthRoleListResponse, error) {
   345  	return etcdWrap.Client.RoleList(ctx)
   346  }
   347  
   348  func (etcdWrap *EtcdClientWrap) RoleRevokePermission(ctx context.Context, role string, key, rangeEnd string) (*etcdClientV3.AuthRoleRevokePermissionResponse, error) {
   349  	return etcdWrap.Client.RoleRevokePermission(ctx, role,key, rangeEnd)
   350  }
   351  
   352  func (etcdWrap *EtcdClientWrap) RoleDelete(ctx context.Context, role string) (*etcdClientV3.AuthRoleDeleteResponse, error) {
   353  	return etcdWrap.Client.RoleDelete(ctx, role)
   354  }
   355  
   356  func (etcdWrap *EtcdClientWrap) AlarmList(ctx context.Context) (*etcdClientV3.AlarmResponse, error) {
   357  	return etcdWrap.Client.AlarmList(ctx)
   358  }
   359  
   360  func (etcdWrap *EtcdClientWrap) AlarmDisarm(ctx context.Context, m *etcdClientV3.AlarmMember) (*etcdClientV3.AlarmResponse, error) {
   361  	return etcdWrap.Client.AlarmDisarm(ctx, m)
   362  }
   363  
   364  func (etcdWrap *EtcdClientWrap) Defragment(ctx context.Context, endpoint string) (*etcdClientV3.DefragmentResponse, error) {
   365  	return etcdWrap.Client.Defragment(ctx, endpoint)
   366  }
   367  
   368  func (etcdWrap *EtcdClientWrap) Status(ctx context.Context, endpoint string) (*etcdClientV3.StatusResponse, error) {
   369  	return etcdWrap.Client.Status(ctx, endpoint)
   370  }
   371  
   372  func (etcdWrap *EtcdClientWrap) HashKV(ctx context.Context, endpoint string, rev int64) (*etcdClientV3.HashKVResponse, error) {
   373  	return etcdWrap.Client.HashKV(ctx, endpoint, rev)
   374  }
   375  
   376  func (etcdWrap *EtcdClientWrap) Snapshot(ctx context.Context) (io.ReadCloser, error) {
   377  	return etcdWrap.Client.Snapshot(ctx)
   378  }
   379  
   380  func (etcdWrap *EtcdClientWrap) MoveLeader(ctx context.Context, transfereeID uint64) (*etcdClientV3.MoveLeaderResponse, error) {
   381  	return etcdWrap.Client.MoveLeader(ctx, transfereeID)
   382  }
   383  
   384  func (etcdWrap *EtcdClientWrap) WithLogger(lg *zap.Logger) *etcdClientV3.Client {
   385  	return etcdWrap.Client.WithLogger(lg)
   386  }
   387  
   388  func (etcdWrap *EtcdClientWrap) GetLogger() *zap.Logger {
   389  	return etcdWrap.Client.GetLogger()
   390  }
   391  
   392  func (etcdWrap *EtcdClientWrap) Ctx() context.Context {
   393  	return etcdWrap.Client.Ctx()
   394  }
   395  
   396  func (etcdWrap *EtcdClientWrap) Endpoints() []string {
   397  	return etcdWrap.Client.Endpoints()
   398  }
   399  
   400  func (etcdWrap *EtcdClientWrap) SetEndpoints(eps ...string) {
   401  	etcdWrap.Client.SetEndpoints(eps...)
   402  }
   403  
   404  func (etcdWrap *EtcdClientWrap) Sync(ctx context.Context) error {
   405  	return etcdWrap.Client.Sync(ctx)
   406  }
   407  
   408  func (etcdWrap *EtcdClientWrap) Dial(ep string) (*grpc.ClientConn, error) {
   409  	return etcdWrap.Client.Dial(ep)
   410  }
   411  
   412  func (etcdWrap *EtcdClientWrap) ActiveConnection() *grpc.ClientConn {
   413  	return etcdWrap.Client.ActiveConnection()
   414  }
   415  
   416  type EtcdLogger struct{}
   417  
   418  func (g *EtcdLogger) Info(args ...interface{}) {
   419  	logger.Info("", args...)
   420  }
   421  
   422  func (g *EtcdLogger) Infoln(args ...interface{}) {
   423  	logger.Info("", args...)
   424  }
   425  
   426  func (g *EtcdLogger) Infof(format string, args ...interface{}) {
   427  	logger.Info(format, args)
   428  }
   429  
   430  func (g *EtcdLogger) InfoDepth(depth int, args ...interface{}) {
   431  	logger.Info("", args...)
   432  }
   433  
   434  func (g *EtcdLogger) Warning(args ...interface{}) {
   435  	logger.Warn("", args...)
   436  }
   437  
   438  func (g *EtcdLogger) Warningln(args ...interface{}) {
   439  	logger.Warn("", args...)
   440  }
   441  
   442  func (g *EtcdLogger) Warningf(format string, args ...interface{}) {
   443  	logger.Warn(format, args...)
   444  }
   445  
   446  func (g *EtcdLogger) WarningDepth(depth int, args ...interface{}) {
   447  	logger.Warn("", args...)
   448  }
   449  
   450  func (g *EtcdLogger) Error(args ...interface{}) {
   451  	logger.Error("", args...)
   452  }
   453  
   454  func (g *EtcdLogger) Errorln(args ...interface{}) {
   455  	logger.Error("", args...)
   456  }
   457  
   458  func (g *EtcdLogger) Errorf(format string, args ...interface{}) {
   459  	logger.Error(format, args...)
   460  }
   461  
   462  func (g *EtcdLogger) ErrorDepth(depth int, args ...interface{}) {
   463  	logger.Error("", args...)
   464  }
   465  
   466  func (g *EtcdLogger) Fatal(args ...interface{}) {
   467  	logger.Fatal("", args...)
   468  }
   469  
   470  func (g *EtcdLogger) Fatalln(args ...interface{}) {
   471  	logger.Fatal("", args...)
   472  }
   473  
   474  func (g *EtcdLogger) Fatalf(format string, args ...interface{}) {
   475  	logger.Fatal(format, args...)
   476  }
   477  
   478  func (g *EtcdLogger) FatalDepth(depth int, args ...interface{}) {
   479  	logger.Fatal("", args...)
   480  }
   481  
   482  func (g *EtcdLogger) V(l int) bool {
   483  	return bool(glog.V(glog.Level(l)))
   484  }
   485  
   486  //func EtcdTracingIsOpen() bool {
   487  //	return config.GetValueBoolDefault("base.tracing.enable", false) && config.GetValueBoolDefault("base.tracing.etcd.enable", false)
   488  //}