1package zk
2
3import (
4	"errors"
5	"fmt"
6)
7
8const (
9	protocolVersion = 0
10
11	DefaultPort = 2181
12)
13
14const (
15	opNotify          = 0
16	opCreate          = 1
17	opDelete          = 2
18	opExists          = 3
19	opGetData         = 4
20	opSetData         = 5
21	opGetAcl          = 6
22	opSetAcl          = 7
23	opGetChildren     = 8
24	opSync            = 9
25	opPing            = 11
26	opGetChildren2    = 12
27	opCheck           = 13
28	opMulti           = 14
29	opReconfig        = 16
30	opCreateContainer = 19
31	opCreateTTL       = 21
32	opClose           = -11
33	opSetAuth         = 100
34	opSetWatches      = 101
35	opError           = -1
36	// Not in protocol, used internally
37	opWatcherEvent = -2
38)
39
40const (
41	EventNodeCreated         EventType = 1
42	EventNodeDeleted         EventType = 2
43	EventNodeDataChanged     EventType = 3
44	EventNodeChildrenChanged EventType = 4
45
46	EventSession     EventType = -1
47	EventNotWatching EventType = -2
48)
49
50var (
51	eventNames = map[EventType]string{
52		EventNodeCreated:         "EventNodeCreated",
53		EventNodeDeleted:         "EventNodeDeleted",
54		EventNodeDataChanged:     "EventNodeDataChanged",
55		EventNodeChildrenChanged: "EventNodeChildrenChanged",
56		EventSession:             "EventSession",
57		EventNotWatching:         "EventNotWatching",
58	}
59)
60
61const (
62	StateUnknown           State = -1
63	StateDisconnected      State = 0
64	StateConnecting        State = 1
65	StateAuthFailed        State = 4
66	StateConnectedReadOnly State = 5
67	StateSaslAuthenticated State = 6
68	StateExpired           State = -112
69
70	StateConnected  = State(100)
71	StateHasSession = State(101)
72)
73
74const (
75	FlagEphemeral = 1
76	FlagSequence  = 2
77	FlagTTL       = 4
78)
79
80var (
81	stateNames = map[State]string{
82		StateUnknown:           "StateUnknown",
83		StateDisconnected:      "StateDisconnected",
84		StateConnectedReadOnly: "StateConnectedReadOnly",
85		StateSaslAuthenticated: "StateSaslAuthenticated",
86		StateExpired:           "StateExpired",
87		StateAuthFailed:        "StateAuthFailed",
88		StateConnecting:        "StateConnecting",
89		StateConnected:         "StateConnected",
90		StateHasSession:        "StateHasSession",
91	}
92)
93
94type State int32
95
96func (s State) String() string {
97	if name := stateNames[s]; name != "" {
98		return name
99	}
100	return "Unknown"
101}
102
103type ErrCode int32
104
105var (
106	ErrConnectionClosed        = errors.New("zk: connection closed")
107	ErrUnknown                 = errors.New("zk: unknown error")
108	ErrAPIError                = errors.New("zk: api error")
109	ErrNoNode                  = errors.New("zk: node does not exist")
110	ErrNoAuth                  = errors.New("zk: not authenticated")
111	ErrBadVersion              = errors.New("zk: version conflict")
112	ErrNoChildrenForEphemerals = errors.New("zk: ephemeral nodes may not have children")
113	ErrNodeExists              = errors.New("zk: node already exists")
114	ErrNotEmpty                = errors.New("zk: node has children")
115	ErrSessionExpired          = errors.New("zk: session has been expired by the server")
116	ErrInvalidACL              = errors.New("zk: invalid ACL specified")
117	ErrInvalidFlags            = errors.New("zk: invalid flags specified")
118	ErrAuthFailed              = errors.New("zk: client authentication failed")
119	ErrClosing                 = errors.New("zk: zookeeper is closing")
120	ErrNothing                 = errors.New("zk: no server responsees to process")
121	ErrSessionMoved            = errors.New("zk: session moved to another server, so operation is ignored")
122	ErrReconfigDisabled        = errors.New("attempts to perform a reconfiguration operation when reconfiguration feature is disabled")
123	ErrBadArguments            = errors.New("invalid arguments")
124	// ErrInvalidCallback         = errors.New("zk: invalid callback specified")
125
126	errCodeToError = map[ErrCode]error{
127		0:                          nil,
128		errAPIError:                ErrAPIError,
129		errNoNode:                  ErrNoNode,
130		errNoAuth:                  ErrNoAuth,
131		errBadVersion:              ErrBadVersion,
132		errNoChildrenForEphemerals: ErrNoChildrenForEphemerals,
133		errNodeExists:              ErrNodeExists,
134		errNotEmpty:                ErrNotEmpty,
135		errSessionExpired:          ErrSessionExpired,
136		// errInvalidCallback:         ErrInvalidCallback,
137		errInvalidAcl:        ErrInvalidACL,
138		errAuthFailed:        ErrAuthFailed,
139		errClosing:           ErrClosing,
140		errNothing:           ErrNothing,
141		errSessionMoved:      ErrSessionMoved,
142		errZReconfigDisabled: ErrReconfigDisabled,
143		errBadArguments:      ErrBadArguments,
144	}
145)
146
147func (e ErrCode) toError() error {
148	if err, ok := errCodeToError[e]; ok {
149		return err
150	}
151	return fmt.Errorf("unknown error: %v", e)
152}
153
154const (
155	errOk = 0
156	// System and server-side errors
157	errSystemError          = -1
158	errRuntimeInconsistency = -2
159	errDataInconsistency    = -3
160	errConnectionLoss       = -4
161	errMarshallingError     = -5
162	errUnimplemented        = -6
163	errOperationTimeout     = -7
164	errBadArguments         = -8
165	errInvalidState         = -9
166	// API errors
167	errAPIError                ErrCode = -100
168	errNoNode                  ErrCode = -101 // *
169	errNoAuth                  ErrCode = -102
170	errBadVersion              ErrCode = -103 // *
171	errNoChildrenForEphemerals ErrCode = -108
172	errNodeExists              ErrCode = -110 // *
173	errNotEmpty                ErrCode = -111
174	errSessionExpired          ErrCode = -112
175	errInvalidCallback         ErrCode = -113
176	errInvalidAcl              ErrCode = -114
177	errAuthFailed              ErrCode = -115
178	errClosing                 ErrCode = -116
179	errNothing                 ErrCode = -117
180	errSessionMoved            ErrCode = -118
181	// Attempts to perform a reconfiguration operation when reconfiguration feature is disabled
182	errZReconfigDisabled ErrCode = -123
183)
184
185// Constants for ACL permissions
186const (
187	PermRead = 1 << iota
188	PermWrite
189	PermCreate
190	PermDelete
191	PermAdmin
192	PermAll = 0x1f
193)
194
195var (
196	emptyPassword = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
197	opNames       = map[int32]string{
198		opNotify:          "notify",
199		opCreate:          "create",
200		opCreateContainer: "createContainer",
201		opCreateTTL:       "createTTL",
202		opDelete:          "delete",
203		opExists:          "exists",
204		opGetData:         "getData",
205		opSetData:         "setData",
206		opGetAcl:          "getACL",
207		opSetAcl:          "setACL",
208		opGetChildren:     "getChildren",
209		opSync:            "sync",
210		opPing:            "ping",
211		opGetChildren2:    "getChildren2",
212		opCheck:           "check",
213		opMulti:           "multi",
214		opReconfig:        "reconfig",
215		opClose:           "close",
216		opSetAuth:         "setAuth",
217		opSetWatches:      "setWatches",
218
219		opWatcherEvent: "watcherEvent",
220	}
221)
222
223type EventType int32
224
225func (t EventType) String() string {
226	if name := eventNames[t]; name != "" {
227		return name
228	}
229	return "Unknown"
230}
231
232// Mode is used to build custom server modes (leader|follower|standalone).
233type Mode uint8
234
235func (m Mode) String() string {
236	if name := modeNames[m]; name != "" {
237		return name
238	}
239	return "unknown"
240}
241
242const (
243	ModeUnknown    Mode = iota
244	ModeLeader     Mode = iota
245	ModeFollower   Mode = iota
246	ModeStandalone Mode = iota
247)
248
249var (
250	modeNames = map[Mode]string{
251		ModeLeader:     "leader",
252		ModeFollower:   "follower",
253		ModeStandalone: "standalone",
254	}
255)
256