1#include <Common/ZooKeeper/ZooKeeper.h>
2#include <Common/ZooKeeper/KeeperException.h>
3#include <iostream>
4#include <sstream>
5#include <Poco/ConsoleChannel.h>
6#include <common/logger_useful.h>
7#include <common/readline_use.h>
8#include <IO/ReadHelpers.h>
9#include <IO/ReadBufferFromString.h>
10
11
12void printStat(const Coordination::Stat & s)
13{
14 std::cout << "Stat:\n";
15 std::cout << " czxid: " << s.czxid << '\n';
16 std::cout << " mzxid: " << s.mzxid << '\n';
17 std::cout << " ctime: " << s.ctime << '\n';
18 std::cout << " mtime: " << s.mtime << '\n';
19 std::cout << " version: " << s.version << '\n';
20 std::cout << " cversion: " << s.cversion << '\n';
21 std::cout << " aversion: " << s.aversion << '\n';
22 std::cout << " ephemeralOwner: " << s.ephemeralOwner << '\n';
23 std::cout << " dataLength: " << s.dataLength << '\n';
24 std::cout << " numChildren: " << s.numChildren << '\n';
25 std::cout << " pzxid: " << s.pzxid << std::endl;
26}
27
28void waitForWatch(const zkutil::EventPtr & event)
29{
30 std::cout << "waiting for watch" << std::endl;
31 event->wait();
32 std::cout << "watch event was signalled" << std::endl;
33}
34
35
36void readUntilSpace(std::string & s, DB::ReadBuffer & buf)
37{
38 s = "";
39 while (!buf.eof())
40 {
41 if (isspace(*buf.position()))
42 return;
43 s.push_back(*buf.position());
44 ++buf.position();
45 }
46}
47
48void readMaybeQuoted(std::string & s, DB::ReadBuffer & buf)
49{
50 if (!buf.eof() && *buf.position() == '\'')
51 DB::readQuotedString(s, buf);
52 else
53 readUntilSpace(s, buf);
54}
55
56
57int main(int argc, char ** argv)
58{
59 try
60 {
61 if (argc != 2)
62 {
63 std::cerr << "usage: " << argv[0] << " hosts" << std::endl;
64 return 2;
65 }
66
67 Poco::AutoPtr<Poco::ConsoleChannel> channel = new Poco::ConsoleChannel(std::cerr);
68 Logger::root().setChannel(channel);
69 Logger::root().setLevel("trace");
70
71 zkutil::ZooKeeper zk(argv[1]);
72
73 while (char * line_ = readline(":3 "))
74 {
75 add_history(line_);
76 std::string line(line_);
77 free(line_);
78
79 try
80 {
81 std::stringstream ss(line);
82
83 std::string cmd;
84 ss >> cmd;
85
86 if (cmd == "q" || cmd == "quit" || cmd == "exit" || cmd == ":q")
87 break;
88
89 std::string path;
90 ss >> path;
91 if (cmd == "ls")
92 {
93 std::string w;
94 ss >> w;
95 bool watch = w == "w";
96 zkutil::EventPtr event = watch ? std::make_shared<Poco::Event>() : nullptr;
97 std::vector<std::string> v = zk.getChildren(path, nullptr, event);
98 for (size_t i = 0; i < v.size(); ++i)
99 {
100 std::cout << v[i] << std::endl;
101 }
102 if (watch)
103 waitForWatch(event);
104 }
105 else if (cmd == "create")
106 {
107 DB::ReadBufferFromString in(line);
108
109 std::string path;
110 std::string data;
111 std::string mode;
112
113 DB::assertString("create", in);
114 DB::skipWhitespaceIfAny(in);
115 readMaybeQuoted(path, in);
116 DB::skipWhitespaceIfAny(in);
117 readMaybeQuoted(data, in);
118 DB::skipWhitespaceIfAny(in);
119 readUntilSpace(mode, in);
120
121 int32_t m;
122 if (mode == "p")
123 m = zkutil::CreateMode::Persistent;
124 else if (mode == "ps")
125 m = zkutil::CreateMode::PersistentSequential;
126 else if (mode == "e")
127 m = zkutil::CreateMode::Ephemeral;
128 else if (mode == "es")
129 m = zkutil::CreateMode::EphemeralSequential;
130 else
131 {
132 std::cout << "Bad create mode" << std::endl;
133 continue;
134 }
135 std::cout << zk.create(path, data, m) << std::endl;
136 }
137 else if (cmd == "remove")
138 {
139 zk.remove(path);
140 }
141 else if (cmd == "rmr")
142 {
143 zk.removeRecursive(path);
144 }
145 else if (cmd == "exists")
146 {
147 std::string w;
148 ss >> w;
149 bool watch = w == "w";
150 zkutil::EventPtr event = watch ? std::make_shared<Poco::Event>() : nullptr;
151 Coordination::Stat stat;
152 bool e = zk.exists(path, &stat, event);
153 if (e)
154 printStat(stat);
155 else
156 std::cout << path << " does not exist" << std::endl;
157 if (watch)
158 waitForWatch(event);
159 }
160 else if (cmd == "get")
161 {
162 std::string w;
163 ss >> w;
164 bool watch = w == "w";
165 zkutil::EventPtr event = watch ? std::make_shared<Poco::Event>() : nullptr;
166 Coordination::Stat stat;
167 std::string data = zk.get(path, &stat, event);
168 std::cout << "Data: " << data << std::endl;
169 printStat(stat);
170 if (watch)
171 waitForWatch(event);
172 }
173 else if (cmd == "set")
174 {
175 DB::ReadBufferFromString in(line);
176
177 std::string data;
178 int version = -1;
179
180 DB::assertString("set", in);
181 DB::skipWhitespaceIfAny(in);
182 DB::assertString(path, in);
183 DB::skipWhitespaceIfAny(in);
184 readMaybeQuoted(data, in);
185 DB::skipWhitespaceIfAny(in);
186
187 if (!in.eof())
188 DB::readText(version, in);
189
190 Coordination::Stat stat;
191 zk.set(path, data, version, &stat);
192 printStat(stat);
193 }
194 else if (cmd != "")
195 {
196 std::cout << "commands:\n";
197 std::cout << " q\n";
198 std::cout << " ls path [w]\n";
199 std::cout << " create path data (p|ps|e|es)\n";
200 std::cout << " remove path\n";
201 std::cout << " rmr path\n";
202 std::cout << " exists path [w]\n";
203 std::cout << " get path [w]\n";
204 std::cout << " set path data [version]" << std::endl;
205 continue;
206 }
207
208 }
209 catch (const Coordination::Exception & e)
210 {
211 std::cerr << "KeeperException: " << e.displayText() << std::endl;
212 }
213 }
214 }
215 catch (const Coordination::Exception & e)
216 {
217 std::cerr << "KeeperException: " << e.displayText() << std::endl;
218 return 1;
219 }
220
221 return 0;
222}
223