libcouchbase 0.3.3 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/libcouchbase/CMakeLists.txt +6 -8
- data/ext/libcouchbase/README.markdown +2 -2
- data/ext/libcouchbase/RELEASE_NOTES.markdown +229 -2
- data/ext/libcouchbase/cmake/Modules/ConfigureDtrace.cmake +11 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +18 -0
- data/ext/libcouchbase/cmake/Modules/GetLibcouchbaseFlags.cmake +3 -2
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/config-cmake.h.in +4 -0
- data/ext/libcouchbase/cmake/defs.mk.in +0 -2
- data/ext/libcouchbase/cmake/source_files.cmake +21 -5
- data/ext/libcouchbase/contrib/cJSON/cJSON.c +1 -1
- data/ext/libcouchbase/contrib/cbsasl/src/client.c +2 -0
- data/ext/libcouchbase/example/users/README +48 -0
- data/ext/libcouchbase/example/users/users.c +147 -0
- data/ext/libcouchbase/include/libcouchbase/auth.h +175 -31
- data/ext/libcouchbase/include/libcouchbase/cntl.h +82 -1
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +45 -3
- data/ext/libcouchbase/include/libcouchbase/error.h +19 -1
- data/ext/libcouchbase/include/libcouchbase/iops.h +3 -0
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +31 -1
- data/ext/libcouchbase/include/libcouchbase/plugins/io/bsdio-inl.c +4 -1
- data/ext/libcouchbase/include/libcouchbase/subdoc.h +36 -2
- data/ext/libcouchbase/include/libcouchbase/views.h +7 -1
- data/ext/libcouchbase/include/libcouchbase/visibility.h +1 -0
- data/ext/libcouchbase/include/memcached/protocol_binary.h +24 -1146
- data/ext/libcouchbase/packaging/parse-git-describe.pl +1 -1
- data/ext/libcouchbase/plugins/io/libev/libev_io_opts.h +3 -2
- data/ext/libcouchbase/src/README.md +0 -2
- data/ext/libcouchbase/src/auth-priv.h +23 -4
- data/ext/libcouchbase/src/auth.cc +51 -43
- data/ext/libcouchbase/src/bootstrap.cc +244 -0
- data/ext/libcouchbase/src/bootstrap.h +58 -38
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +120 -158
- data/ext/libcouchbase/src/bucketconfig/bc_file.cc +281 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +526 -0
- data/ext/libcouchbase/src/bucketconfig/bc_http.h +50 -25
- data/ext/libcouchbase/src/bucketconfig/bc_static.cc +150 -0
- data/ext/libcouchbase/src/bucketconfig/clconfig.h +410 -386
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +393 -0
- data/ext/libcouchbase/src/cbft.cc +22 -27
- data/ext/libcouchbase/src/cntl.cc +56 -22
- data/ext/libcouchbase/src/connspec.cc +47 -6
- data/ext/libcouchbase/src/connspec.h +27 -0
- data/ext/libcouchbase/src/dns-srv.cc +147 -0
- data/ext/libcouchbase/src/dump.cc +3 -3
- data/ext/libcouchbase/src/errmap.cc +173 -0
- data/ext/libcouchbase/src/errmap.h +198 -0
- data/ext/libcouchbase/src/getconfig.cc +7 -33
- data/ext/libcouchbase/src/handler.cc +118 -7
- data/ext/libcouchbase/src/hostlist.cc +0 -36
- data/ext/libcouchbase/src/hostlist.h +44 -62
- data/ext/libcouchbase/src/http/http-priv.h +125 -112
- data/ext/libcouchbase/src/http/http.cc +27 -35
- data/ext/libcouchbase/src/http/http.h +1 -34
- data/ext/libcouchbase/src/http/http_io.cc +28 -36
- data/ext/libcouchbase/src/instance.cc +131 -34
- data/ext/libcouchbase/src/internal.h +58 -26
- data/ext/libcouchbase/src/jsparse/parser.cc +136 -210
- data/ext/libcouchbase/src/jsparse/parser.h +84 -98
- data/ext/libcouchbase/src/lcbht/lcbht.cc +177 -0
- data/ext/libcouchbase/src/lcbht/lcbht.h +174 -163
- data/ext/libcouchbase/src/lcbio/connect.cc +569 -0
- data/ext/libcouchbase/src/lcbio/connect.h +16 -7
- data/ext/libcouchbase/src/lcbio/ctx.c +1 -1
- data/ext/libcouchbase/src/lcbio/iotable.h +101 -16
- data/ext/libcouchbase/src/lcbio/{ioutils.c → ioutils.cc} +30 -51
- data/ext/libcouchbase/src/lcbio/ioutils.h +29 -90
- data/ext/libcouchbase/src/lcbio/manager.cc +543 -0
- data/ext/libcouchbase/src/lcbio/manager.h +133 -96
- data/ext/libcouchbase/src/lcbio/protoctx.c +2 -2
- data/ext/libcouchbase/src/lcbio/timer-cxx.h +87 -0
- data/ext/libcouchbase/src/mc/mcreq.c +11 -2
- data/ext/libcouchbase/src/mc/mcreq.h +9 -2
- data/ext/libcouchbase/src/mcserver/mcserver.cc +175 -43
- data/ext/libcouchbase/src/mcserver/mcserver.h +9 -13
- data/ext/libcouchbase/src/mcserver/negotiate.cc +181 -62
- data/ext/libcouchbase/src/mcserver/negotiate.h +1 -3
- data/ext/libcouchbase/src/mctx-helper.h +51 -0
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +1 -2
- data/ext/libcouchbase/src/n1ql/n1ql.cc +74 -42
- data/ext/libcouchbase/src/netbuf/netbuf.c +4 -4
- data/ext/libcouchbase/src/newconfig.cc +6 -6
- data/ext/libcouchbase/src/nodeinfo.cc +2 -2
- data/ext/libcouchbase/src/operations/{cbflush.c → cbflush.cc} +7 -15
- data/ext/libcouchbase/src/operations/{counter.c → counter.cc} +0 -0
- data/ext/libcouchbase/src/operations/durability.cc +6 -26
- data/ext/libcouchbase/src/operations/durability_internal.h +6 -3
- data/ext/libcouchbase/src/operations/{get.c → get.cc} +24 -26
- data/ext/libcouchbase/src/operations/{observe.c → observe.cc} +68 -93
- data/ext/libcouchbase/src/operations/{pktfwd.c → pktfwd.cc} +0 -0
- data/ext/libcouchbase/src/operations/{remove.c → remove.cc} +0 -0
- data/ext/libcouchbase/src/operations/stats.cc +3 -8
- data/ext/libcouchbase/src/operations/{store.c → store.cc} +27 -32
- data/ext/libcouchbase/src/operations/subdoc.cc +129 -42
- data/ext/libcouchbase/src/operations/{touch.c → touch.cc} +0 -0
- data/ext/libcouchbase/src/packetutils.h +30 -2
- data/ext/libcouchbase/src/probes.d +1 -1
- data/ext/libcouchbase/src/rdb/rope.c +1 -1
- data/ext/libcouchbase/src/{retrychk.c → retrychk.cc} +2 -3
- data/ext/libcouchbase/src/retryq.cc +52 -14
- data/ext/libcouchbase/src/retryq.h +3 -3
- data/ext/libcouchbase/src/settings.c +5 -0
- data/ext/libcouchbase/src/settings.h +11 -0
- data/ext/libcouchbase/src/ssl/ssl_c.c +1 -0
- data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +0 -1
- data/ext/libcouchbase/src/strcodecs/strcodecs.h +1 -1
- data/ext/libcouchbase/src/trace.h +4 -4
- data/ext/libcouchbase/src/vbucket/vbucket.c +6 -10
- data/ext/libcouchbase/src/views/{docreq.c → docreq.cc} +48 -54
- data/ext/libcouchbase/src/views/docreq.h +24 -30
- data/ext/libcouchbase/src/views/viewreq.cc +318 -0
- data/ext/libcouchbase/src/views/viewreq.h +43 -13
- data/ext/libcouchbase/tests/basic/t_connstr.cc +88 -50
- data/ext/libcouchbase/tests/basic/t_creds.cc +47 -5
- data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
- data/ext/libcouchbase/tests/basic/t_jsparse.cc +27 -82
- data/ext/libcouchbase/tests/basic/t_misc.cc +1 -1
- data/ext/libcouchbase/tests/basic/t_n1qlstrings.cc +0 -1
- data/ext/libcouchbase/tests/htparse/t_basic.cc +58 -78
- data/ext/libcouchbase/tests/ioserver/connection.cc +1 -1
- data/ext/libcouchbase/tests/ioserver/ioserver.cc +19 -6
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +28 -2
- data/ext/libcouchbase/tests/iotests/mock-environment.h +51 -1
- data/ext/libcouchbase/tests/iotests/t_behavior.cc +1 -7
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +97 -115
- data/ext/libcouchbase/tests/iotests/t_durability.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_eerrs.cc +119 -0
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +178 -0
- data/ext/libcouchbase/tests/iotests/t_misc.cc +3 -3
- data/ext/libcouchbase/tests/iotests/t_netfail.cc +1 -1
- data/ext/libcouchbase/tests/iotests/t_obseqno.cc +0 -1
- data/ext/libcouchbase/tests/iotests/t_subdoc.cc +18 -11
- data/ext/libcouchbase/tests/mc/t_alloc.cc +9 -9
- data/ext/libcouchbase/tests/socktests/socktest.cc +7 -10
- data/ext/libcouchbase/tests/socktests/socktest.h +2 -3
- data/ext/libcouchbase/tests/socktests/t_basic.cc +6 -6
- data/ext/libcouchbase/tests/socktests/t_manager.cc +5 -6
- data/ext/libcouchbase/tests/socktests/t_ssl.cc +1 -1
- data/ext/libcouchbase/tests/vbucket/confdata/ketama_expected.json +2562 -0
- data/ext/libcouchbase/tests/vbucket/confdata/memd_ketama_config.json +31 -0
- data/ext/libcouchbase/tests/vbucket/t_config.cc +35 -5
- data/ext/libcouchbase/tools/CMakeLists.txt +2 -2
- data/ext/libcouchbase/tools/cbc-handlers.h +128 -0
- data/ext/libcouchbase/tools/cbc-n1qlback.cc +64 -10
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +2 -2
- data/ext/libcouchbase/tools/cbc.cc +143 -10
- data/ext/libcouchbase/tools/docgen/loc.h +1 -1
- data/lib/libcouchbase/connection.rb +4 -3
- data/lib/libcouchbase/version.rb +1 -1
- metadata +37 -28
- data/ext/libcouchbase/include/memcached/vbucket.h +0 -42
- data/ext/libcouchbase/src/bootstrap.c +0 -269
- data/ext/libcouchbase/src/bucketconfig/bc_file.c +0 -347
- data/ext/libcouchbase/src/bucketconfig/bc_http.c +0 -630
- data/ext/libcouchbase/src/bucketconfig/bc_mcraw.c +0 -150
- data/ext/libcouchbase/src/bucketconfig/confmon.c +0 -474
- data/ext/libcouchbase/src/lcbht/lcbht.c +0 -282
- data/ext/libcouchbase/src/lcbio/connect.c +0 -557
- data/ext/libcouchbase/src/lcbio/manager.c +0 -584
- data/ext/libcouchbase/src/packetutils.c +0 -37
- data/ext/libcouchbase/src/simplestring.c +0 -211
- data/ext/libcouchbase/src/simplestring.h +0 -228
- data/ext/libcouchbase/src/ssobuf.h +0 -82
- data/ext/libcouchbase/src/views/viewreq.c +0 -358
- data/ext/libcouchbase/tests/basic/t_string.cc +0 -112
@@ -0,0 +1,31 @@
|
|
1
|
+
{
|
2
|
+
"bucketCapabilitiesVer" : "",
|
3
|
+
"name" : "memd",
|
4
|
+
"nodeLocator" : "ketama",
|
5
|
+
"nodes" : [
|
6
|
+
{
|
7
|
+
"ports" : {
|
8
|
+
"direct" : 11210
|
9
|
+
},
|
10
|
+
"hostname" : "192.168.1.103:8091"
|
11
|
+
},
|
12
|
+
{
|
13
|
+
"hostname" : "192.168.1.101:8091",
|
14
|
+
"ports" : {
|
15
|
+
"direct" : 11210
|
16
|
+
}
|
17
|
+
},
|
18
|
+
{
|
19
|
+
"hostname" : "192.168.1.102:8091",
|
20
|
+
"ports" : {
|
21
|
+
"direct" : 11210
|
22
|
+
}
|
23
|
+
},
|
24
|
+
{
|
25
|
+
"hostname" : "$HOST:8091",
|
26
|
+
"ports" : {
|
27
|
+
"direct" : 11210
|
28
|
+
}
|
29
|
+
}
|
30
|
+
]
|
31
|
+
}
|
@@ -55,10 +55,10 @@ ConfigTest::testConfig(const char *fname, bool checkNew)
|
|
55
55
|
ASSERT_TRUE(vbc != NULL);
|
56
56
|
int rv = lcbvb_load_json(vbc, testData.c_str());
|
57
57
|
ASSERT_EQ(0, rv);
|
58
|
-
ASSERT_GT(vbc->nsrv, 0);
|
58
|
+
ASSERT_GT(vbc->nsrv, (unsigned int)0);
|
59
59
|
|
60
60
|
if (vbc->dtype == LCBVB_DIST_VBUCKET) {
|
61
|
-
ASSERT_GT(vbc->nvb, 0);
|
61
|
+
ASSERT_GT(vbc->nvb, (unsigned int)0);
|
62
62
|
|
63
63
|
for (unsigned ii = 0; ii < vbc->nvb; ii++) {
|
64
64
|
lcbvb_vbmaster(vbc, ii);
|
@@ -284,7 +284,7 @@ TEST_F(ConfigTest, testNondataNodes)
|
|
284
284
|
|
285
285
|
lcbvb_map_key(cfg_old, s.c_str(), s.size(), &vbid, &ix_exp);
|
286
286
|
lcbvb_map_key(cfg_ex, s.c_str(), s.size(), &vbid, &ix_cur);
|
287
|
-
ASSERT_TRUE(ix_exp > -1 && ix_exp <
|
287
|
+
ASSERT_TRUE(ix_exp > -1 && ix_exp < (int)cfg_ex->ndatasrv);
|
288
288
|
ASSERT_EQ(ix_exp, ix_cur);
|
289
289
|
}
|
290
290
|
|
@@ -298,7 +298,7 @@ TEST_F(ConfigTest, testNondataNodes)
|
|
298
298
|
if (newix == -1) {
|
299
299
|
continue;
|
300
300
|
} else {
|
301
|
-
ASSERT_TRUE(newix < cfg_ex->ndatasrv);
|
301
|
+
ASSERT_TRUE(newix < (int)cfg_ex->ndatasrv);
|
302
302
|
}
|
303
303
|
}
|
304
304
|
}
|
@@ -310,7 +310,7 @@ TEST_F(ConfigTest, testNondataNodes)
|
|
310
310
|
const string& s = keys[ii];
|
311
311
|
lcbvb_map_key(cfg_old, s.c_str(), s.size(), &vbid, &ix_exp);
|
312
312
|
lcbvb_map_key(cfg_ex, s.c_str(), s.size(), &vbid, &ix_cur);
|
313
|
-
ASSERT_TRUE(ix_exp > -1 && ix_exp < cfg_old->ndatasrv);
|
313
|
+
ASSERT_TRUE(ix_exp > -1 && ix_exp < (int)cfg_old->ndatasrv);
|
314
314
|
ASSERT_EQ(ix_exp, ix_cur);
|
315
315
|
}
|
316
316
|
|
@@ -339,3 +339,33 @@ TEST_F(ConfigTest, testKetamaUniformity)
|
|
339
339
|
ASSERT_STREQ("localhost:12006", vbc->servers[3].authority);
|
340
340
|
lcbvb_destroy(vbc);
|
341
341
|
}
|
342
|
+
|
343
|
+
TEST_F(ConfigTest, testKetamaCompliance) {
|
344
|
+
string txt = getConfigFile("memd_ketama_config.json");
|
345
|
+
lcbvb_CONFIG *vbc = lcbvb_parse_json(txt.c_str());
|
346
|
+
ASSERT_TRUE(vbc != NULL);
|
347
|
+
ASSERT_EQ(4, vbc->nsrv);
|
348
|
+
ASSERT_EQ(LCBVB_DIST_KETAMA, vbc->dtype);
|
349
|
+
|
350
|
+
lcbvb_replace_host(vbc, "192.168.1.104");
|
351
|
+
// Now, load the hash file
|
352
|
+
string expected_txt = getConfigFile("ketama_expected.json");
|
353
|
+
Json::Value json;
|
354
|
+
ASSERT_TRUE(Json::Reader().parse(expected_txt, json));
|
355
|
+
|
356
|
+
ASSERT_EQ(json.size(), vbc->ncontinuum);
|
357
|
+
|
358
|
+
// Iterate over the continuum in the vbuckets
|
359
|
+
for (size_t ii = 0; ii < json.size(); ++ii) {
|
360
|
+
const Json::Value& cur = json[static_cast<int>(ii)];
|
361
|
+
unsigned exp_hash = cur["hash"].asUInt();
|
362
|
+
string exp_server = cur["hostname"].asString();
|
363
|
+
unsigned got_hash = vbc->continuum[ii].point;
|
364
|
+
unsigned got_index = vbc->continuum[ii].index;
|
365
|
+
|
366
|
+
ASSERT_EQ(exp_server, vbc->servers[got_index].authority);
|
367
|
+
ASSERT_EQ(exp_hash, got_hash);
|
368
|
+
}
|
369
|
+
|
370
|
+
lcbvb_destroy(vbc);
|
371
|
+
}
|
@@ -4,7 +4,7 @@ FILE(GLOB T_COMMONSRC common/*.cc)
|
|
4
4
|
ADD_LIBRARY(lcbtools OBJECT ${T_COMMONSRC})
|
5
5
|
|
6
6
|
ADD_EXECUTABLE(cbc cbc.cc
|
7
|
-
$<TARGET_OBJECTS:lcbtools> $<TARGET_OBJECTS:cliopts>)
|
7
|
+
$<TARGET_OBJECTS:lcbtools> $<TARGET_OBJECTS:cliopts> $<TARGET_OBJECTS:lcb_jsoncpp>)
|
8
8
|
TARGET_LINK_LIBRARIES(cbc couchbase)
|
9
9
|
|
10
10
|
ADD_EXECUTABLE(cbc-pillowfight cbc-pillowfight.cc
|
@@ -38,7 +38,7 @@ IF(NOT WIN32)
|
|
38
38
|
cat create observe observe-seqno incr decr mcflush hash lock
|
39
39
|
unlock rm stats version verbosity view n1ql admin
|
40
40
|
bucket-create bucket-delete bucket-flush connstr write-config strerror
|
41
|
-
touch)
|
41
|
+
touch role-list user-list user-upsert user-delete)
|
42
42
|
|
43
43
|
FOREACH(subcmd IN ITEMS ${CBC_SUBCOMMANDS})
|
44
44
|
ADD_CUSTOM_COMMAND(TARGET cbc POST_BUILD
|
@@ -367,6 +367,134 @@ protected:
|
|
367
367
|
|
368
368
|
};
|
369
369
|
|
370
|
+
class RbacHandler : public AdminHandler {
|
371
|
+
public:
|
372
|
+
HANDLER_USAGE("[OPTIONS ...]")
|
373
|
+
RbacHandler(const char *name) : AdminHandler(name),
|
374
|
+
o_raw('r', "raw")
|
375
|
+
{
|
376
|
+
o_raw.description("Do not reformat output from server (display JSON response)");
|
377
|
+
}
|
378
|
+
|
379
|
+
protected:
|
380
|
+
virtual void run();
|
381
|
+
virtual void format() = 0;
|
382
|
+
virtual void addOptions() {
|
383
|
+
AdminHandler::addOptions();
|
384
|
+
parser.addOption(o_raw);
|
385
|
+
}
|
386
|
+
|
387
|
+
private:
|
388
|
+
cliopts::BoolOption o_raw;
|
389
|
+
};
|
390
|
+
|
391
|
+
class RoleListHandler : public RbacHandler {
|
392
|
+
public:
|
393
|
+
HANDLER_DESCRIPTION("List roles")
|
394
|
+
RoleListHandler() : RbacHandler("role-list")
|
395
|
+
{
|
396
|
+
}
|
397
|
+
|
398
|
+
protected:
|
399
|
+
virtual void format();
|
400
|
+
virtual void addOptions() {
|
401
|
+
RbacHandler::addOptions();
|
402
|
+
}
|
403
|
+
std::string getURI() { return "/settings/rbac/roles"; }
|
404
|
+
const std::string& getBody() { static std::string e; return e; }
|
405
|
+
lcb_http_method_t getMethod() { return LCB_HTTP_METHOD_GET; }
|
406
|
+
};
|
407
|
+
|
408
|
+
class UserListHandler : public RbacHandler {
|
409
|
+
public:
|
410
|
+
HANDLER_DESCRIPTION("List users")
|
411
|
+
UserListHandler() : RbacHandler("user-list")
|
412
|
+
{
|
413
|
+
}
|
414
|
+
|
415
|
+
protected:
|
416
|
+
virtual void format();
|
417
|
+
virtual void addOptions() {
|
418
|
+
RbacHandler::addOptions();
|
419
|
+
}
|
420
|
+
std::string getURI() { return "/settings/rbac/users"; }
|
421
|
+
const std::string& getBody() { static std::string e; return e; }
|
422
|
+
lcb_http_method_t getMethod() { return LCB_HTTP_METHOD_GET; }
|
423
|
+
};
|
424
|
+
|
425
|
+
class UserDeleteHandler : public AdminHandler {
|
426
|
+
public:
|
427
|
+
HANDLER_DESCRIPTION("Delete a user")
|
428
|
+
HANDLER_USAGE("NAME [OPTIONS ...]")
|
429
|
+
UserDeleteHandler() : AdminHandler("user-delete"),
|
430
|
+
o_domain("domain")
|
431
|
+
{
|
432
|
+
o_domain.description("The domain, where user account defined {local,external}").setDefault("local");
|
433
|
+
}
|
434
|
+
|
435
|
+
protected:
|
436
|
+
virtual void addOptions() {
|
437
|
+
AdminHandler::addOptions();
|
438
|
+
parser.addOption(o_domain);
|
439
|
+
}
|
440
|
+
void run() {
|
441
|
+
name = getRequiredArg();
|
442
|
+
domain = o_domain.result();
|
443
|
+
if (domain != "local" && domain != "external") {
|
444
|
+
throw BadArg("Unrecognized domain type");
|
445
|
+
}
|
446
|
+
AdminHandler::run();
|
447
|
+
}
|
448
|
+
std::string getURI() { return std::string("/settings/rbac/users/") + domain + "/" + name; }
|
449
|
+
const std::string& getBody() { static std::string e; return e; }
|
450
|
+
lcb_http_method_t getMethod() { return LCB_HTTP_METHOD_DELETE; }
|
451
|
+
|
452
|
+
private:
|
453
|
+
cliopts::StringOption o_domain;
|
454
|
+
std::string name;
|
455
|
+
std::string domain;
|
456
|
+
};
|
457
|
+
|
458
|
+
class UserUpsertHandler : public AdminHandler {
|
459
|
+
public:
|
460
|
+
HANDLER_DESCRIPTION("Create or update a user")
|
461
|
+
HANDLER_USAGE("NAME [OPTIONS ...]")
|
462
|
+
UserUpsertHandler() : AdminHandler("user-upsert"),
|
463
|
+
o_domain("domain"),
|
464
|
+
o_full_name("full-name"),
|
465
|
+
o_password("user-password"),
|
466
|
+
o_roles("role")
|
467
|
+
{
|
468
|
+
o_domain.description("The domain, where user account defined {local,external}").setDefault("local");
|
469
|
+
o_full_name.description("The user's fullname");
|
470
|
+
o_roles.description("The role associated with user (can be specified multiple times if needed)");
|
471
|
+
o_password.description("The password for the user");
|
472
|
+
}
|
473
|
+
|
474
|
+
protected:
|
475
|
+
virtual void addOptions() {
|
476
|
+
AdminHandler::addOptions();
|
477
|
+
parser.addOption(o_domain);
|
478
|
+
parser.addOption(o_full_name);
|
479
|
+
parser.addOption(o_roles);
|
480
|
+
parser.addOption(o_password);
|
481
|
+
}
|
482
|
+
virtual void run();
|
483
|
+
std::string getURI() { return std::string("/settings/rbac/users/") + domain + "/" + name; }
|
484
|
+
const std::string& getBody() { return body; }
|
485
|
+
std::string getContentType() { return "application/x-www-form-urlencoded"; }
|
486
|
+
lcb_http_method_t getMethod() { return LCB_HTTP_METHOD_PUT; }
|
487
|
+
|
488
|
+
private:
|
489
|
+
cliopts::StringOption o_domain;
|
490
|
+
cliopts::StringOption o_full_name;
|
491
|
+
cliopts::StringOption o_password;
|
492
|
+
cliopts::ListOption o_roles;
|
493
|
+
std::string name;
|
494
|
+
std::string domain;
|
495
|
+
std::string body;
|
496
|
+
};
|
497
|
+
|
370
498
|
class BucketCreateHandler : public AdminHandler {
|
371
499
|
public:
|
372
500
|
HANDLER_DESCRIPTION("Create a bucket")
|
@@ -74,6 +74,8 @@ public:
|
|
74
74
|
start_time = last_update;
|
75
75
|
}
|
76
76
|
|
77
|
+
size_t nerrors() { return n_errors; }
|
78
|
+
|
77
79
|
void update_row(size_t n = 1) { n_rows += n; update_display(); }
|
78
80
|
void update_done(size_t n = 1) { n_queries += n; update_display(); }
|
79
81
|
void update_error(size_t n = 1) { n_errors += n; update_display(); }
|
@@ -139,8 +141,8 @@ private:
|
|
139
141
|
final_suffix = "\n";
|
140
142
|
}
|
141
143
|
|
142
|
-
printf("%sQUERIES/SEC: %lu\n", prefix, n_queries / duration);
|
143
|
-
printf("%sROWS/SEC: %lu\n", prefix, n_rows / duration);
|
144
|
+
printf("%sQUERIES/SEC: %lu\n", prefix, (long int)(n_queries / duration));
|
145
|
+
printf("%sROWS/SEC: %lu\n", prefix, (long int)(n_rows / duration));
|
144
146
|
printf("%sERRORS: %lu%s", prefix, n_errors, final_suffix);
|
145
147
|
|
146
148
|
if (hg != NULL) {
|
@@ -168,7 +170,7 @@ Metrics GlobalMetrics;
|
|
168
170
|
class Configuration
|
169
171
|
{
|
170
172
|
public:
|
171
|
-
Configuration() : o_file("queryfile"), o_threads("num-threads") {
|
173
|
+
Configuration() : o_file("queryfile"), o_threads("num-threads"), o_errlog("error-log"), m_errlog(NULL) {
|
172
174
|
o_file.mandatory(true);
|
173
175
|
o_file.description(
|
174
176
|
"Path to a file containing all the queries to execute. "
|
@@ -178,12 +180,24 @@ public:
|
|
178
180
|
o_threads.description("Number of threads to run");
|
179
181
|
o_threads.abbrev('t');
|
180
182
|
o_threads.setDefault(1);
|
183
|
+
|
184
|
+
o_errlog.description(
|
185
|
+
"Path to a file containing failed queries");
|
186
|
+
o_errlog.abbrev('e');
|
187
|
+
o_errlog.setDefault("");
|
181
188
|
}
|
182
189
|
|
190
|
+
~Configuration() {
|
191
|
+
if (m_errlog != NULL) {
|
192
|
+
delete m_errlog;
|
193
|
+
m_errlog = NULL;
|
194
|
+
}
|
195
|
+
}
|
183
196
|
void addToParser(Parser& parser)
|
184
197
|
{
|
185
198
|
parser.addOption(o_file);
|
186
199
|
parser.addOption(o_threads);
|
200
|
+
parser.addOption(o_errlog);
|
187
201
|
m_params.addToParser(parser);
|
188
202
|
}
|
189
203
|
|
@@ -200,22 +214,38 @@ public:
|
|
200
214
|
|
201
215
|
string curline;
|
202
216
|
while (std::getline(ifs, curline).good() && !ifs.eof()) {
|
203
|
-
|
217
|
+
if (!curline.empty()) {
|
218
|
+
m_queries.push_back(curline);
|
219
|
+
}
|
204
220
|
}
|
205
221
|
if (m_params.useTimings()) {
|
206
222
|
GlobalMetrics.prepare_timings();
|
207
223
|
}
|
224
|
+
|
225
|
+
if (o_errlog.passed()) {
|
226
|
+
m_errlog = new std::ofstream(o_errlog.const_result().c_str());
|
227
|
+
if (!m_errlog->is_open()) {
|
228
|
+
int ec_save = errno;
|
229
|
+
string errstr(o_file.const_result());
|
230
|
+
errstr += ": ";
|
231
|
+
errstr += strerror(ec_save);
|
232
|
+
throw std::runtime_error(errstr);
|
233
|
+
}
|
234
|
+
}
|
208
235
|
}
|
209
236
|
|
210
237
|
void set_cropts(lcb_create_st &opts) { m_params.fillCropts(opts); }
|
211
238
|
const vector<string>& queries() const { return m_queries; }
|
212
239
|
size_t nthreads() { return o_threads.result(); }
|
240
|
+
std::ofstream* errlog() { return m_errlog; }
|
213
241
|
|
214
242
|
private:
|
215
243
|
vector<string> m_queries;
|
216
244
|
StringOption o_file;
|
217
245
|
UIntOption o_threads;
|
218
246
|
ConnParams m_params;
|
247
|
+
StringOption o_errlog;
|
248
|
+
std::ofstream *m_errlog;
|
219
249
|
};
|
220
250
|
|
221
251
|
extern "C" { static void n1qlcb(lcb_t, int, const lcb_RESPN1QL *resp); }
|
@@ -287,16 +317,25 @@ public:
|
|
287
317
|
|
288
318
|
if (resp->rflags & LCB_RESP_F_FINAL) {
|
289
319
|
if (resp->rc != LCB_SUCCESS) {
|
290
|
-
|
320
|
+
if (m_errlog != NULL) {
|
321
|
+
std::stringstream ss;
|
322
|
+
ss.write(m_cmd.query, m_cmd.nquery);
|
323
|
+
ss << endl;
|
324
|
+
ss.write(resp->row, resp->nrow);
|
325
|
+
log_error(resp->rc, ss.str().c_str(), ss.str().size());
|
326
|
+
} else {
|
327
|
+
log_error(resp->rc, NULL, 0);
|
328
|
+
}
|
291
329
|
}
|
292
330
|
} else {
|
293
331
|
last_nrow++;
|
294
332
|
}
|
295
333
|
}
|
296
334
|
|
297
|
-
ThreadContext(lcb_t instance, const vector<string>& initial_queries)
|
335
|
+
ThreadContext(lcb_t instance, const vector<string>& initial_queries, std::ofstream *errlog)
|
298
336
|
: m_instance(instance), last_nerr(0), last_nrow(0),
|
299
|
-
m_metrics(&GlobalMetrics), m_cancelled(false), m_thr(NULL)
|
337
|
+
m_metrics(&GlobalMetrics), m_cancelled(false), m_thr(NULL),
|
338
|
+
m_errlog(errlog)
|
300
339
|
{
|
301
340
|
memset(&m_cmd, 0, sizeof m_cmd);
|
302
341
|
m_cmd.content_type = "application/json";
|
@@ -309,11 +348,25 @@ public:
|
|
309
348
|
|
310
349
|
private:
|
311
350
|
|
312
|
-
void log_error(lcb_error_t)
|
351
|
+
void log_error(lcb_error_t err, const char* info, size_t ninfo)
|
313
352
|
{
|
353
|
+
size_t erridx;
|
314
354
|
m_metrics->lock();
|
315
355
|
m_metrics->update_error();
|
356
|
+
erridx = m_metrics->nerrors();
|
316
357
|
m_metrics->unlock();
|
358
|
+
|
359
|
+
if (m_errlog != NULL) {
|
360
|
+
std::stringstream ss;
|
361
|
+
ss << "[" << erridx << "] 0x" << std::hex << err << ", "
|
362
|
+
<< lcb_strerror(NULL, err) << endl;
|
363
|
+
if (ninfo) {
|
364
|
+
ss.write(info, ninfo);
|
365
|
+
ss << endl;
|
366
|
+
}
|
367
|
+
*m_errlog << ss.str();
|
368
|
+
m_errlog->flush();
|
369
|
+
}
|
317
370
|
}
|
318
371
|
|
319
372
|
void run_one_query(const string& txt)
|
@@ -330,7 +383,7 @@ private:
|
|
330
383
|
|
331
384
|
lcb_error_t rc = lcb_n1ql_query(m_instance, &qctx, &m_cmd);
|
332
385
|
if (rc != LCB_SUCCESS) {
|
333
|
-
log_error(rc);
|
386
|
+
log_error(rc, txt.c_str(), txt.size());
|
334
387
|
} else {
|
335
388
|
lcb_wait(m_instance);
|
336
389
|
m_metrics->lock();
|
@@ -352,6 +405,7 @@ private:
|
|
352
405
|
#else
|
353
406
|
void *m_thr;
|
354
407
|
#endif
|
408
|
+
std::ofstream *m_errlog;
|
355
409
|
};
|
356
410
|
|
357
411
|
static void n1qlcb(lcb_t, int, const lcb_RESPN1QL *resp)
|
@@ -409,7 +463,7 @@ static void real_main(int argc, char **argv) {
|
|
409
463
|
throw std::runtime_error("Cluster does not support N1QL!");
|
410
464
|
}
|
411
465
|
|
412
|
-
ThreadContext* cx = new ThreadContext(instance, config.queries());
|
466
|
+
ThreadContext* cx = new ThreadContext(instance, config.queries(), config.errlog());
|
413
467
|
threads.push_back(cx);
|
414
468
|
instances.push_back(instance);
|
415
469
|
}
|
@@ -170,7 +170,7 @@ public:
|
|
170
170
|
}
|
171
171
|
maxCycles = est;
|
172
172
|
o_sequential.setDefault(true);
|
173
|
-
fprintf(stderr, "Populating using %
|
173
|
+
fprintf(stderr, "Populating using %d cycles\n", maxCycles);
|
174
174
|
}
|
175
175
|
|
176
176
|
if (depr.iterations.passed()) {
|
@@ -630,7 +630,7 @@ private:
|
|
630
630
|
|
631
631
|
const lcb_U64 elapsed_ns = now - previous_time;
|
632
632
|
const lcb_U64 wanted_duration_ns =
|
633
|
-
config.opsPerCycle * 1e9 / config.getRateLimit();
|
633
|
+
(config.getNumThreads() * config.opsPerCycle * 1e9) / config.getRateLimit();
|
634
634
|
// On first invocation no previous_time, so skip attempting to sleep.
|
635
635
|
if (elapsed_ns > 0 && elapsed_ns < wanted_duration_ns) {
|
636
636
|
// Dampen the sleep time by averaging with the previous
|