-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.go
103 lines (86 loc) · 2.32 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package client
import (
"errors"
"strings"
"github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/mvcc/mvccpb"
"golang.org/x/net/context"
)
const (
DEFAULT_DIR_VALUE = "etcdv3_dir_$2H#%gRe3*t"
)
var (
ErrorInvalidRootKey = errors.New("root key should not be empty or end with /")
ErrorInvalidKey = errors.New("key should start with /")
ErrorPutKey = errors.New("key is not under a directory or key is a directory or key is not empty")
ErrorKeyNotFound = errors.New("key has not been set")
ErrorListKey = errors.New("can only list a directory")
)
// etcd v3 client with Hierarchy
type EtcdHRCHYClient struct {
client *clientv3.Client
ctx context.Context
// root key as root directory
rootKey string
// special value for directory
dirValue string
}
func New(clt *clientv3.Client, rootKey string, dirValue ...string) (*EtcdHRCHYClient, error) {
if !checkRootKey(rootKey) {
return nil, ErrorInvalidRootKey
}
d := DEFAULT_DIR_VALUE
if len(dirValue) > 0 && dirValue[0] != "" {
d = dirValue[0]
}
return &EtcdHRCHYClient{
client: clt,
rootKey: rootKey,
dirValue: d,
ctx: context.TODO(),
}, nil
}
func (clt *EtcdHRCHYClient) EtcdClient() *clientv3.Client {
return clt.client
}
func (clt *EtcdHRCHYClient) RootKey() string {
return clt.rootKey
}
func (clt *EtcdHRCHYClient) DirValue() string {
return clt.dirValue
}
// clone client with new etcdClt, for changing some config of etcdClt
func (clt *EtcdHRCHYClient) Clone(etcdClt *clientv3.Client) *EtcdHRCHYClient {
return &EtcdHRCHYClient{
client: etcdClt,
rootKey: clt.rootKey,
dirValue: clt.dirValue,
ctx: context.TODO(),
}
}
// make sure the rootKey is a directory
func (clt *EtcdHRCHYClient) FormatRootKey() error {
if clt.rootKey != "" {
_, err := clt.client.Put(clt.ctx, clt.rootKey, clt.dirValue)
return err
}
return nil
}
type Node struct {
*mvccpb.KeyValue
IsDir bool `json:"is_dir"`
}
func (clt *EtcdHRCHYClient) isDir(value []byte) bool {
return string(value) == clt.dirValue
}
func (clt *EtcdHRCHYClient) trimRootKey(key string) string {
return strings.TrimPrefix(key, clt.rootKey)
}
func (clt *EtcdHRCHYClient) createNode(kv *mvccpb.KeyValue) *Node {
// remove rootKey prefix
//kv.Key = []byte(clt.trimRootKey(string(kv.Key)))
return &Node{
KeyValue: kv,
IsDir: clt.isDir(kv.Value),
}
}