1 | #include <string.h> |
2 | |
3 | #include <Common/ProfileEvents.h> |
4 | #include <Common/ZooKeeper/IKeeper.h> |
5 | |
6 | |
7 | namespace DB |
8 | { |
9 | namespace ErrorCodes |
10 | { |
11 | extern const int KEEPER_EXCEPTION; |
12 | } |
13 | } |
14 | |
15 | namespace ProfileEvents |
16 | { |
17 | extern const Event ZooKeeperUserExceptions; |
18 | extern const Event ZooKeeperHardwareExceptions; |
19 | extern const Event ZooKeeperOtherExceptions; |
20 | } |
21 | |
22 | |
23 | namespace Coordination |
24 | { |
25 | |
26 | Exception::Exception(const std::string & msg, const int32_t code_, int) |
27 | : DB::Exception(msg, DB::ErrorCodes::KEEPER_EXCEPTION), code(code_) |
28 | { |
29 | if (Coordination::isUserError(code)) |
30 | ProfileEvents::increment(ProfileEvents::ZooKeeperUserExceptions); |
31 | else if (Coordination::isHardwareError(code)) |
32 | ProfileEvents::increment(ProfileEvents::ZooKeeperHardwareExceptions); |
33 | else |
34 | ProfileEvents::increment(ProfileEvents::ZooKeeperOtherExceptions); |
35 | } |
36 | |
37 | Exception::Exception(const std::string & msg, const int32_t code_) |
38 | : Exception(msg + " (" + errorMessage(code_) + ")" , code_, 0) |
39 | { |
40 | } |
41 | |
42 | Exception::Exception(const int32_t code_) |
43 | : Exception(errorMessage(code_), code_, 0) |
44 | { |
45 | } |
46 | |
47 | Exception::Exception(const int32_t code_, const std::string & path) |
48 | : Exception(std::string{errorMessage(code_)} + ", path: " + path, code_, 0) |
49 | { |
50 | } |
51 | |
52 | Exception::Exception(const Exception & exc) |
53 | : DB::Exception(exc), code(exc.code) |
54 | { |
55 | } |
56 | |
57 | |
58 | using namespace DB; |
59 | |
60 | |
61 | static void addRootPath(String & path, const String & root_path) |
62 | { |
63 | if (path.empty()) |
64 | throw Exception("Path cannot be empty" , ZBADARGUMENTS); |
65 | |
66 | if (path[0] != '/') |
67 | throw Exception("Path must begin with /" , ZBADARGUMENTS); |
68 | |
69 | if (root_path.empty()) |
70 | return; |
71 | |
72 | if (path.size() == 1) /// "/" |
73 | path = root_path; |
74 | else |
75 | path = root_path + path; |
76 | } |
77 | |
78 | static void removeRootPath(String & path, const String & root_path) |
79 | { |
80 | if (root_path.empty()) |
81 | return; |
82 | |
83 | if (path.size() <= root_path.size()) |
84 | throw Exception("Received path is not longer than root_path" , ZDATAINCONSISTENCY); |
85 | |
86 | path = path.substr(root_path.size()); |
87 | } |
88 | |
89 | |
90 | const char * errorMessage(int32_t code) |
91 | { |
92 | switch (code) |
93 | { |
94 | case ZOK: return "Ok" ; |
95 | case ZSYSTEMERROR: return "System error" ; |
96 | case ZRUNTIMEINCONSISTENCY: return "Run time inconsistency" ; |
97 | case ZDATAINCONSISTENCY: return "Data inconsistency" ; |
98 | case ZCONNECTIONLOSS: return "Connection loss" ; |
99 | case ZMARSHALLINGERROR: return "Marshalling error" ; |
100 | case ZUNIMPLEMENTED: return "Unimplemented" ; |
101 | case ZOPERATIONTIMEOUT: return "Operation timeout" ; |
102 | case ZBADARGUMENTS: return "Bad arguments" ; |
103 | case ZINVALIDSTATE: return "Invalid zhandle state" ; |
104 | case ZAPIERROR: return "API error" ; |
105 | case ZNONODE: return "No node" ; |
106 | case ZNOAUTH: return "Not authenticated" ; |
107 | case ZBADVERSION: return "Bad version" ; |
108 | case ZNOCHILDRENFOREPHEMERALS: return "No children for ephemerals" ; |
109 | case ZNODEEXISTS: return "Node exists" ; |
110 | case ZNOTEMPTY: return "Not empty" ; |
111 | case ZSESSIONEXPIRED: return "Session expired" ; |
112 | case ZINVALIDCALLBACK: return "Invalid callback" ; |
113 | case ZINVALIDACL: return "Invalid ACL" ; |
114 | case ZAUTHFAILED: return "Authentication failed" ; |
115 | case ZCLOSING: return "ZooKeeper is closing" ; |
116 | case ZNOTHING: return "(not error) no server responses to process" ; |
117 | case ZSESSIONMOVED: return "Session moved to another server, so operation is ignored" ; |
118 | } |
119 | if (code > 0) |
120 | return strerror(code); |
121 | |
122 | return "unknown error" ; |
123 | } |
124 | |
125 | bool isHardwareError(int32_t zk_return_code) |
126 | { |
127 | return zk_return_code == ZINVALIDSTATE |
128 | || zk_return_code == ZSESSIONEXPIRED |
129 | || zk_return_code == ZSESSIONMOVED |
130 | || zk_return_code == ZCONNECTIONLOSS |
131 | || zk_return_code == ZMARSHALLINGERROR |
132 | || zk_return_code == ZOPERATIONTIMEOUT; |
133 | } |
134 | |
135 | bool isUserError(int32_t zk_return_code) |
136 | { |
137 | return zk_return_code == ZNONODE |
138 | || zk_return_code == ZBADVERSION |
139 | || zk_return_code == ZNOCHILDRENFOREPHEMERALS |
140 | || zk_return_code == ZNODEEXISTS |
141 | || zk_return_code == ZNOTEMPTY; |
142 | } |
143 | |
144 | |
145 | void CreateRequest::addRootPath(const String & root_path) { Coordination::addRootPath(path, root_path); } |
146 | void RemoveRequest::addRootPath(const String & root_path) { Coordination::addRootPath(path, root_path); } |
147 | void ExistsRequest::addRootPath(const String & root_path) { Coordination::addRootPath(path, root_path); } |
148 | void GetRequest::addRootPath(const String & root_path) { Coordination::addRootPath(path, root_path); } |
149 | void SetRequest::addRootPath(const String & root_path) { Coordination::addRootPath(path, root_path); } |
150 | void ListRequest::addRootPath(const String & root_path) { Coordination::addRootPath(path, root_path); } |
151 | void CheckRequest::addRootPath(const String & root_path) { Coordination::addRootPath(path, root_path); } |
152 | |
153 | void MultiRequest::addRootPath(const String & root_path) |
154 | { |
155 | for (auto & request : requests) |
156 | request->addRootPath(root_path); |
157 | } |
158 | |
159 | void CreateResponse::removeRootPath(const String & root_path) { Coordination::removeRootPath(path_created, root_path); } |
160 | void WatchResponse::removeRootPath(const String & root_path) { Coordination::removeRootPath(path, root_path); } |
161 | |
162 | void MultiResponse::removeRootPath(const String & root_path) |
163 | { |
164 | for (auto & response : responses) |
165 | response->removeRootPath(root_path); |
166 | } |
167 | |
168 | } |
169 | |
170 | |