Unverified Commit fd94fb87 authored by Xin.Zh's avatar Xin.Zh Committed by GitHub

Merge pull request #46 from wenxuwan/master

move zk client to gost
parents 0383403a b7e262ea
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package gxzookeeper
import (
"path"
"strings"
"sync"
"sync/atomic"
"time"
)
import (
"github.com/dubbogo/go-zookeeper/zk"
perrors "github.com/pkg/errors"
)
var (
// ErrNilZkClientConn no conn error
ErrNilZkClientConn = perrors.New("zookeeper Client{conn} is nil")
// ErrNilChildren no children error
ErrNilChildren = perrors.Errorf("has none children")
// ErrNilNode no node error
ErrNilNode = perrors.Errorf("node does not exist")
)
var (
zkClientPool zookeeperClientPool
clientPoolOnce sync.Once
)
// ZookeeperClient represents zookeeper Client Configuration
type ZookeeperClient struct {
name string
ZkAddrs []string
sync.RWMutex // for conn
Conn *zk.Conn
activeNumber uint32
Timeout time.Duration
Wait sync.WaitGroup
valid uint32
share bool
reconnectCh chan struct{}
eventRegistry map[string][]*chan struct{}
eventRegistryLock sync.RWMutex
zkEventHandler ZkEventHandler
Session <-chan zk.Event
}
type zookeeperClientPool struct {
sync.Mutex
zkClient map[string]*ZookeeperClient
}
// ZkEventHandler interface
type ZkEventHandler interface {
HandleZkEvent(z *ZookeeperClient)
}
// DefaultHandler is default handler for zk event
type DefaultHandler struct {
}
// StateToString will transfer zk state to string
func StateToString(state zk.State) string {
switch state {
case zk.StateDisconnected:
return "zookeeper disconnected"
case zk.StateConnecting:
return "zookeeper connecting"
case zk.StateAuthFailed:
return "zookeeper auth failed"
case zk.StateConnectedReadOnly:
return "zookeeper connect readonly"
case zk.StateSaslAuthenticated:
return "zookeeper sasl authenticated"
case zk.StateExpired:
return "zookeeper connection expired"
case zk.StateConnected:
return "zookeeper connected"
case zk.StateHasSession:
return "zookeeper has Session"
case zk.StateUnknown:
return "zookeeper unknown state"
case zk.State(zk.EventNodeDeleted):
return "zookeeper node deleted"
case zk.State(zk.EventNodeDataChanged):
return "zookeeper node data changed"
default:
return state.String()
}
}
func initZookeeperClientPool() {
zkClientPool.zkClient = make(map[string]*ZookeeperClient)
}
//NewZookeeperClient will create a ZookeeperClient
func NewZookeeperClient(name string, zkAddrs []string, share bool, opts ...zkClientOption) (*ZookeeperClient, error) {
if share {
clientPoolOnce.Do(initZookeeperClientPool)
zkClientPool.Lock()
defer zkClientPool.Unlock()
if zkClient, ok := zkClientPool.zkClient[name]; ok {
zkClient.activeNumber++
return zkClient, nil
}
}
newZkClient := &ZookeeperClient{
name: name,
ZkAddrs: zkAddrs,
activeNumber: 0,
share: share,
reconnectCh: make(chan struct{}),
eventRegistry: make(map[string][]*chan struct{}),
Session: make(<-chan zk.Event),
zkEventHandler: &DefaultHandler{},
}
for _, opt := range opts {
opt(newZkClient)
}
err := newZkClient.createZookeeperConn()
if err != nil {
return nil, err
}
newZkClient.activeNumber++
if share {
zkClientPool.zkClient[name] = newZkClient
}
return newZkClient, nil
}
// nolint
func (z *ZookeeperClient) createZookeeperConn() error {
var err error
// connect to zookeeper
z.Conn, z.Session, err = zk.Connect(z.ZkAddrs, z.Timeout)
if err != nil {
return err
}
atomic.StoreUint32(&z.valid, 1)
go z.zkEventHandler.HandleZkEvent(z)
return nil
}
// WithTestCluster sets test cluster for zk Client
func WithTestCluster(ts *zk.TestCluster) Option {
return func(opt *options) {
opt.Ts = ts
}
}
// NewMockZookeeperClient returns a mock Client instance
func NewMockZookeeperClient(name string, timeout time.Duration, opts ...Option) (*zk.TestCluster, *ZookeeperClient, <-chan zk.Event, error) {
var (
err error
z *ZookeeperClient
ts *zk.TestCluster
)
z = &ZookeeperClient{
name: name,
ZkAddrs: []string{},
Timeout: timeout,
share: false,
reconnectCh: make(chan struct{}),
eventRegistry: make(map[string][]*chan struct{}),
Session: make(<-chan zk.Event),
zkEventHandler: &DefaultHandler{},
}
option := &options{}
for _, opt := range opts {
opt(option)
}
// connect to zookeeper
if option.Ts != nil {
ts = option.Ts
} else {
ts, err = zk.StartTestCluster(1, nil, nil, zk.WithRetryTimes(40))
if err != nil {
return nil, nil, nil, perrors.WithMessagef(err, "zk.StartTestCluster fail")
}
}
z.Conn, z.Session, err = ts.ConnectWithOptions(timeout)
if err != nil {
return nil, nil, nil, perrors.WithMessagef(err, "zk.Connect fail")
}
atomic.StoreUint32(&z.valid, 1)
z.activeNumber++
return ts, z, z.Session, nil
}
// HandleZkEvent handles zookeeper events
func (d *DefaultHandler) HandleZkEvent(z *ZookeeperClient) {
var (
state int
event zk.Event
)
for {
select {
case event = <-z.Session:
switch (int)(event.State) {
case (int)(zk.StateDisconnected):
atomic.StoreUint32(&z.valid, 0)
case (int)(zk.EventNodeDataChanged), (int)(zk.EventNodeChildrenChanged):
z.eventRegistryLock.RLock()
for p, a := range z.eventRegistry {
if strings.HasPrefix(p, event.Path) {
for _, e := range a {
*e <- struct{}{}
}
}
}
z.eventRegistryLock.RUnlock()
case (int)(zk.StateConnecting), (int)(zk.StateConnected), (int)(zk.StateHasSession):
if state == (int)(zk.StateHasSession) {
continue
}
if event.State == zk.StateHasSession {
atomic.StoreUint32(&z.valid, 1)
close(z.reconnectCh)
z.reconnectCh = make(chan struct{})
}
z.eventRegistryLock.RLock()
if a, ok := z.eventRegistry[event.Path]; ok && 0 < len(a) {
for _, e := range a {
*e <- struct{}{}
}
}
z.eventRegistryLock.RUnlock()
}
state = (int)(event.State)
}
}
}
// RegisterEvent registers zookeeper events
func (z *ZookeeperClient) RegisterEvent(zkPath string, event *chan struct{}) {
if zkPath == "" || event == nil {
return
}
z.eventRegistryLock.Lock()
defer z.eventRegistryLock.Unlock()
a := z.eventRegistry[zkPath]
a = append(a, event)
z.eventRegistry[zkPath] = a
}
// UnregisterEvent unregisters zookeeper events
func (z *ZookeeperClient) UnregisterEvent(zkPath string, event *chan struct{}) {
if zkPath == "" {
return
}
z.eventRegistryLock.Lock()
defer z.eventRegistryLock.Unlock()
infoList, ok := z.eventRegistry[zkPath]
if !ok {
return
}
for i, e := range infoList {
if e == event {
infoList = append(infoList[:i], infoList[i+1:]...)
}
}
if len(infoList) == 0 {
delete(z.eventRegistry, zkPath)
} else {
z.eventRegistry[zkPath] = infoList
}
}
// ZkConnValid validates zookeeper connection
func (z *ZookeeperClient) ZkConnValid() bool {
if atomic.LoadUint32(&z.valid) == 1 {
return true
}
return false
}
// Create will create the node recursively, which means that if the parent node is absent,
// it will create parent node first.
// And the value for the basePath is ""
func (z *ZookeeperClient) Create(basePath string) error {
return z.CreateWithValue(basePath, []byte(""))
}
// CreateWithValue will create the node recursively, which means that if the parent node is absent,
// it will create parent node first.
func (z *ZookeeperClient) CreateWithValue(basePath string, value []byte) error {
var (
err error
tmpPath string
)
conn := z.getConn()
err = ErrNilZkClientConn
if conn == nil {
return perrors.WithMessagef(err, "zk.Create(path:%s)", basePath)
}
for _, str := range strings.Split(basePath, "/")[1:] {
tmpPath = path.Join(tmpPath, "/", str)
_, err = conn.Create(tmpPath, value, 0, zk.WorldACL(zk.PermAll))
if err != nil {
if err != zk.ErrNodeExists {
return perrors.WithMessagef(err, "zk.Create(path:%s)", basePath)
}
}
}
return nil
}
// CreateTempWithValue will create the node recursively, which means that if the parent node is absent,
// it will create parent node first,and set value in last child path
// If the path exist, it will update data
func (z *ZookeeperClient) CreateTempWithValue(basePath string, value []byte) error {
var (
err error
tmpPath string
)
conn := z.getConn()
err = ErrNilZkClientConn
if conn == nil {
return perrors.WithMessagef(err, "zk.Create(path:%s)", basePath)
}
pathSlice := strings.Split(basePath, "/")[1:]
length := len(pathSlice)
for i, str := range pathSlice {
tmpPath = path.Join(tmpPath, "/", str)
// last child need be ephemeral
if i == length-1 {
_, err = conn.Create(tmpPath, value, zk.FlagEphemeral, zk.WorldACL(zk.PermAll))
if err == zk.ErrNodeExists {
return err
}
} else {
_, err = conn.Create(tmpPath, []byte{}, 0, zk.WorldACL(zk.PermAll))
}
if err != nil {
if err != zk.ErrNodeExists {
return perrors.WithMessagef(err, "zk.Create(path:%s)", basePath)
}
}
}
return nil
}
//Delete will delete basePath
func (z *ZookeeperClient) Delete(basePath string) error {
err := ErrNilZkClientConn
conn := z.getConn()
if conn != nil {
err = conn.Delete(basePath, -1)
}
return perrors.WithMessagef(err, "Delete(basePath:%s)", basePath)
}
// RegisterTemp registers temporary node by @basePath and @node
func (z *ZookeeperClient) RegisterTemp(basePath string, node string) (string, error) {
var (
err error
zkPath string
tmpPath string
)
err = ErrNilZkClientConn
zkPath = path.Join(basePath) + "/" + node
conn := z.getConn()
if conn != nil {
tmpPath, err = conn.Create(zkPath, []byte(""), zk.FlagEphemeral, zk.WorldACL(zk.PermAll))
}
if err != nil {
return zkPath, perrors.WithStack(err)
}
return tmpPath, nil
}
// RegisterTempSeq register temporary sequence node by @basePath and @data
func (z *ZookeeperClient) RegisterTempSeq(basePath string, data []byte) (string, error) {
var (
err error
tmpPath string
)
err = ErrNilZkClientConn
conn := z.getConn()
if conn != nil {
tmpPath, err = conn.Create(
path.Join(basePath)+"/",
data,
zk.FlagEphemeral|zk.FlagSequence,
zk.WorldACL(zk.PermAll),
)
}
if err != nil && err != zk.ErrNodeExists {
return "", perrors.WithStack(err)
}
return tmpPath, nil
}
// GetChildrenW gets children watch by @path
func (z *ZookeeperClient) GetChildrenW(path string) ([]string, <-chan zk.Event, error) {
var (
err error
children []string
stat *zk.Stat
watcher *zk.Watcher
)
err = ErrNilZkClientConn
conn := z.getConn()
if conn != nil {
children, stat, watcher, err = conn.ChildrenW(path)
}
if err != nil {
if err == zk.ErrNoChildrenForEphemerals {
return nil, nil, ErrNilChildren
}
if err == zk.ErrNoNode {
return nil, nil, ErrNilNode
}
return nil, nil, perrors.WithMessagef(err, "zk.ChildrenW(path:%s)", path)
}
if stat == nil {
return nil, nil, perrors.Errorf("path{%s} get stat is nil", path)
}
if len(children) == 0 {
return nil, nil, ErrNilChildren
}
return children, watcher.EvtCh, nil
}
// GetChildren gets children by @path
func (z *ZookeeperClient) GetChildren(path string) ([]string, error) {
var (
err error
children []string
stat *zk.Stat
)
err = ErrNilZkClientConn
conn := z.getConn()
if conn != nil {
children, stat, err = conn.Children(path)
}
if err != nil {
if err == zk.ErrNoNode {
return nil, perrors.Errorf("path{%s} has none children", path)
}
return nil, perrors.WithMessagef(err, "zk.Children(path:%s)", path)
}
if stat == nil {
return nil, perrors.Errorf("path{%s} has none children", path)
}
if len(children) == 0 {
return nil, ErrNilChildren
}
return children, nil
}
// ExistW to judge watch whether it exists or not by @zkPath
func (z *ZookeeperClient) ExistW(zkPath string) (<-chan zk.Event, error) {
var (
exist bool
err error
watcher *zk.Watcher
)
err = ErrNilZkClientConn
conn := z.getConn()
if conn != nil {
exist, _, watcher, err = conn.ExistsW(zkPath)
}
if err != nil {
return nil, perrors.WithMessagef(err, "zk.ExistsW(path:%s)", zkPath)
}
if !exist {
return nil, perrors.Errorf("zkClient{%s} App zk path{%s} does not exist.", z.name, zkPath)
}
return watcher.EvtCh, nil
}
// GetContent gets content by @zkPath
func (z *ZookeeperClient) GetContent(zkPath string) ([]byte, *zk.Stat, error) {
return z.Conn.Get(zkPath)
}
//SetContent set content of zkPath
func (z *ZookeeperClient) SetContent(zkPath string, content []byte, version int32) (*zk.Stat, error) {
return z.Conn.Set(zkPath, content, version)
}
// getConn gets zookeeper connection safely
func (z *ZookeeperClient) getConn() *zk.Conn {
if z == nil {
return nil
}
z.RLock()
defer z.RUnlock()
return z.Conn
}
// Reconnect gets zookeeper reconnect event
func (z *ZookeeperClient) Reconnect() <-chan struct{} {
return z.reconnectCh
}
// GetEventHandler gets zookeeper event handler
func (z *ZookeeperClient) GetEventHandler() ZkEventHandler {
return z.zkEventHandler
}
func (z *ZookeeperClient) Close() {
if z.share {
zkClientPool.Lock()
defer zkClientPool.Unlock()
z.activeNumber--
if z.activeNumber == 0 {
z.Conn.Close()
delete(zkClientPool.zkClient, z.name)
}
} else {
z.Lock()
conn := z.Conn
z.activeNumber--
z.Conn = nil
z.Unlock()
if conn != nil {
conn.Close()
}
}
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package gxzookeeper
import (
"strconv"
"testing"
"time"
)
import (
"github.com/dubbogo/go-zookeeper/zk"
"github.com/stretchr/testify/assert"
)
func verifyEventStateOrder(t *testing.T, c <-chan zk.Event, expectedStates []zk.State, source string) {
for _, state := range expectedStates {
for {
event, ok := <-c
if !ok {
t.Fatalf("unexpected channel close for %s", source)
}
if event.Type != zk.EventSession {
continue
}
if event.State != state {
t.Fatalf("mismatched state order from %s, expected %v, received %v", source, state, event.State)
}
break
}
}
}
func Test_getZookeeperClient(t *testing.T) {
var err error
var tc *zk.TestCluster
var address []string
tc, err = zk.StartTestCluster(1, nil, nil, zk.WithRetryTimes(40))
assert.NoError(t, err)
assert.NotNil(t, tc.Servers[0])
address = append(address, "127.0.0.1:"+strconv.Itoa(tc.Servers[0].Port))
client1, err := NewZookeeperClient("test1", address, true, WithZkTimeOut(3*time.Second))
assert.Nil(t, err)
client2, err := NewZookeeperClient("test1", address, true, WithZkTimeOut(3*time.Second))
assert.Nil(t, err)
client3, err := NewZookeeperClient("test2", address, true, WithZkTimeOut(3*time.Second))
assert.Nil(t, err)
client4, err := NewZookeeperClient("test2", address, false, WithZkTimeOut(3*time.Second))
assert.Nil(t, err)
if client1 != client2 {
t.Fatalf("NewZookeeperClient failed")
}
if client1 == client3 {
t.Fatalf("NewZookeeperClient failed")
}
if client3 == client4 {
t.Fatalf("NewZookeeperClient failed")
}
client1.Close()
client2.Close()
client3.Close()
client4.Close()
tc.Stop()
}
func Test_Close(t *testing.T) {
var err error
var tc *zk.TestCluster
var address []string
tc, err = zk.StartTestCluster(1, nil, nil, zk.WithRetryTimes(40))
assert.NoError(t, err)
assert.NotNil(t, tc.Servers[0])
address = append(address, "127.0.0.1:"+strconv.Itoa(tc.Servers[0].Port))
client1, err := NewZookeeperClient("test1", address, true, WithZkTimeOut(3*time.Second))
assert.Nil(t, err)
client2, err := NewZookeeperClient("test1", address, true, WithZkTimeOut(3*time.Second))
assert.Nil(t, err)
if client1 != client2 {
t.Fatalf("NewZookeeperClient failed")
}
client1.Close()
client3, err := NewZookeeperClient("test1", address, true, WithZkTimeOut(3*time.Second))
assert.Nil(t, err)
if client2 != client3 {
t.Fatalf("NewZookeeperClient failed")
}
client2.Close()
assert.Equal(t, client1.activeNumber, uint32(1))
client1.Close()
assert.Equal(t, client1.activeNumber, uint32(0))
client4, err := NewZookeeperClient("test1", address, true, WithZkTimeOut(3*time.Second))
assert.Nil(t, err)
assert.Equal(t, client4.activeNumber, uint32(1))
if client4 == client3 {
t.Fatalf("NewZookeeperClient failed")
}
client5, err := NewZookeeperClient("test1", address, false, WithZkTimeOut(3*time.Second))
assert.Nil(t, err)
client6, err := NewZookeeperClient("test1", address, false, WithZkTimeOut(3*time.Second))
assert.Nil(t, err)
if client5 == client6 {
t.Fatalf("NewZookeeperClient failed")
}
client5.Close()
assert.Equal(t, client5.activeNumber, uint32(0))
assert.Equal(t, client5.Conn, (*zk.Conn)(nil))
assert.NotEqual(t, client6.Conn, nil)
client6.Close()
assert.Equal(t, client6.activeNumber, uint32(0))
assert.Equal(t, client6.Conn, (*zk.Conn)(nil))
tc.Stop()
}
func Test_newMockZookeeperClient(t *testing.T) {
ts, _, event, err := NewMockZookeeperClient("test", 15*time.Second)
assert.NoError(t, err)
defer func() {
err := ts.Stop()
assert.Nil(t, err)
}()
states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession}
verifyEventStateOrder(t, event, states, "event channel")
}
func TestCreate(t *testing.T) {
ts, z, event, err := NewMockZookeeperClient("test", 15*time.Second)
assert.NoError(t, err)
defer func() {
_ = ts.Stop()
assert.Nil(t, err)
}()
err = z.Create("test1/test2/test3/test4")
assert.NoError(t, err)
states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession}
verifyEventStateOrder(t, event, states, "event channel")
}
func TestCreateDelete(t *testing.T) {
ts, z, event, err := NewMockZookeeperClient("test", 15*time.Second)
assert.NoError(t, err)
defer func() {
_ = ts.Stop()
assert.Nil(t, err)
}()
states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession}
verifyEventStateOrder(t, event, states, "event channel")
err = z.Create("/test1/test2/test3/test4")
assert.NoError(t, err)
err = z.Delete("/test1/test2/test3/test4")
assert.NoError(t, err)
// verifyEventOrder(t, event, []zk.EventType{zk.EventNodeCreated}, "event channel")
}
func TestRegisterTemp(t *testing.T) {
ts, z, event, err := NewMockZookeeperClient("test", 15*time.Second)
assert.NoError(t, err)
defer func() {
_ = ts.Stop()
assert.Nil(t, err)
}()
err = z.Create("/test1/test2/test3")
assert.NoError(t, err)
tmpath, err := z.RegisterTemp("/test1/test2/test3", "test4")
assert.NoError(t, err)
assert.Equal(t, "/test1/test2/test3/test4", tmpath)
states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession}
verifyEventStateOrder(t, event, states, "event channel")
}
func TestRegisterTempSeq(t *testing.T) {
ts, z, event, err := NewMockZookeeperClient("test", 15*time.Second)
assert.NoError(t, err)
defer func() {
_ = ts.Stop()
assert.Nil(t, err)
}()
err = z.Create("/test1/test2/test3")
assert.NoError(t, err)
tmpath, err := z.RegisterTempSeq("/test1/test2/test3", []byte("test"))
assert.NoError(t, err)
assert.Equal(t, "/test1/test2/test3/0000000000", tmpath)
states := []zk.State{zk.StateConnecting, zk.StateConnected, zk.StateHasSession}
verifyEventStateOrder(t, event, states, "event channel")
}
func Test_UnregisterEvent(t *testing.T) {
client := &ZookeeperClient{}
client.eventRegistry = make(map[string][]*chan struct{})
array := []*chan struct{}{}
array = append(array, new(chan struct{}))
client.eventRegistry["test"] = array
client.UnregisterEvent("test", new(chan struct{}))
}
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package gxzookeeper
import (
"time"
)
import (
"github.com/dubbogo/go-zookeeper/zk"
)
// nolint
type options struct {
ZkName string
Client *ZookeeperClient
Ts *zk.TestCluster
}
// Option will define a function of handling Options
type Option func(*options)
// WithZkName sets zk Client name
func WithZkName(name string) Option {
return func(opt *options) {
opt.ZkName = name
}
}
type zkClientOption func(*ZookeeperClient)
// WithZkEventHandler sets zk Client event
func WithZkEventHandler(handler ZkEventHandler) zkClientOption {
return func(opt *ZookeeperClient) {
opt.zkEventHandler = handler
}
}
// WithZkTimeOut sets zk Client timeout
func WithZkTimeOut(t time.Duration) zkClientOption {
return func(opt *ZookeeperClient) {
opt.Timeout = t
}
}
......@@ -2,39 +2,48 @@ module github.com/dubbogo/gost
require (
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
github.com/coreos/bbolt v0.0.0-00010101000000-000000000000 // indirect
github.com/coreos/bbolt v1.3.3 // indirect
github.com/coreos/etcd v3.3.25+incompatible
github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f // indirect
github.com/davecgh/go-spew v1.1.1
github.com/dubbogo/go-zookeeper v1.0.3
github.com/dubbogo/jsonparser v1.0.1
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/google/uuid v1.2.0 // indirect
github.com/gorilla/websocket v1.4.2 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
github.com/jonboulle/clockwork v0.2.2 // indirect
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88 // indirect
github.com/k0kubun/pp v3.0.1+incompatible
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.7 // indirect
github.com/mattn/go-isatty v0.0.12
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.9.0 // indirect
github.com/shirou/gopsutil v3.20.11-0.20201116082039-2fb5da2f2449+incompatible
github.com/stretchr/testify v1.6.1
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
go.etcd.io/bbolt v1.3.4 // indirect
go.uber.org/atomic v1.7.0
go.uber.org/zap v1.16.0 // indirect
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect
google.golang.org/grpc v1.33.1
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
sigs.k8s.io/yaml v1.2.0 // indirect
)
replace (
github.com/coreos/bbolt => go.etcd.io/bbolt v1.3.4
go.etcd.io/bbolt v1.3.4 => github.com/coreos/bbolt v1.3.4
google.golang.org/grpc v1.33.1 => google.golang.org/grpc v1.26.0
)
......
......@@ -41,6 +41,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/coreos/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
github.com/coreos/etcd v3.3.25+incompatible h1:0GQEw6h3YnuOVdtwygkIfJ+Omx0tZ8/QkVyXI4LkbeY=
github.com/coreos/etcd v3.3.25+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
......@@ -54,12 +55,17 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f h1:lBNOc5arjvs8E5mO2tbp
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dubbogo/go-zookeeper v1.0.2 h1:xmEnPL8SlCe3/+J5ZR9e8qE35LmFVYe8VVpDakjNM4A=
github.com/dubbogo/go-zookeeper v1.0.2/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c=
github.com/dubbogo/go-zookeeper v1.0.3 h1:UkuY+rBsxdT7Bs63QAzp9z7XqQ53W1j8E5rwl83me8g=
github.com/dubbogo/go-zookeeper v1.0.3/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c=
github.com/dubbogo/jsonparser v1.0.1 h1:sAIr8gk+gkahkIm6CnUxh9wTCkbgwLEQ8dTXTnAXyzo=
github.com/dubbogo/jsonparser v1.0.1/go.mod h1:tYAtpctvSP/tWw4MeelsowSPgXQRVHHWbqL6ynps8jU=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
......@@ -137,6 +143,8 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c h1:Lh2aW+HnU2Nbe1gqD9SOJLJxW1jBMmQOktN2acDyJk8=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 h1:FlFbCRLd5Jr4iYXZufAvgWN6Ao0JrI5chLINnUXDDr0=
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
......@@ -198,6 +206,8 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
......@@ -234,6 +244,8 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE
github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
......@@ -329,6 +341,8 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/wenxuwan/go-zookeeper v1.0.3-0.20210303051024-8a4fef629f1a h1:EG3JeqQNnLM6PUbnmfUl1ou4JDfF3H08CKifYHrcwlQ=
github.com/wenxuwan/go-zookeeper v1.0.3-0.20210303051024-8a4fef629f1a/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
......@@ -377,6 +391,8 @@ golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTk
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
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.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
......@@ -470,6 +486,7 @@ golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/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-20200103221440-774c71fcf114/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-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ=
......@@ -518,6 +535,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
......@@ -534,6 +553,8 @@ gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment