libcouchbase 1.0.4 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +11 -8
- data/ext/libcouchbase/CMakeLists.txt +1 -1
- data/ext/libcouchbase/README.markdown +38 -6
- data/ext/libcouchbase/RELEASE_NOTES.markdown +151 -0
- data/ext/libcouchbase/cmake/Modules/GenerateConfigDotH.cmake +2 -2
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/source_files.cmake +1 -0
- data/ext/libcouchbase/contrib/cJSON/cJSON.c +686 -288
- data/ext/libcouchbase/contrib/cJSON/cJSON.h +0 -0
- data/ext/libcouchbase/contrib/cbsasl/src/hash.c +17 -17
- data/ext/libcouchbase/contrib/cliopts/cliopts.c +76 -0
- data/ext/libcouchbase/contrib/cliopts/cliopts.h +66 -15
- data/ext/libcouchbase/contrib/genhash/genhash.c +1 -2
- data/ext/libcouchbase/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +4 -3
- data/ext/libcouchbase/example/instancepool/main.cc +12 -2
- data/ext/libcouchbase/example/libeventdirect/main.c +99 -25
- data/ext/libcouchbase/example/minimal/minimal.c +7 -5
- data/ext/libcouchbase/example/observe/durability.c +102 -0
- data/ext/libcouchbase/example/observe/observe.c +19 -6
- data/ext/libcouchbase/example/subdoc/subdoc-xattrs.c +1 -2
- data/ext/libcouchbase/include/libcouchbase/cntl-private.h +6 -8
- data/ext/libcouchbase/include/libcouchbase/cntl.h +84 -64
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +295 -78
- data/ext/libcouchbase/include/libcouchbase/deprecated.h +2 -2
- data/ext/libcouchbase/include/libcouchbase/error.h +1 -1
- data/ext/libcouchbase/include/libcouchbase/iops.h +9 -9
- data/ext/libcouchbase/include/libcouchbase/ixmgmt.h +2 -2
- data/ext/libcouchbase/include/libcouchbase/n1ql.h +69 -7
- data/ext/libcouchbase/include/libcouchbase/vbucket.h +17 -0
- data/ext/libcouchbase/include/libcouchbase/views.h +3 -3
- data/ext/libcouchbase/include/memcached/protocol_binary.h +62 -1
- data/ext/libcouchbase/packaging/deb/control +1 -1
- data/ext/libcouchbase/packaging/rpm/libcouchbase.spec.in +37 -36
- data/ext/libcouchbase/src/bootstrap.cc +22 -8
- data/ext/libcouchbase/src/bucketconfig/bc_cccp.cc +1 -1
- data/ext/libcouchbase/src/bucketconfig/bc_http.cc +0 -1
- data/ext/libcouchbase/src/bucketconfig/confmon.cc +13 -8
- data/ext/libcouchbase/src/callbacks.c +2 -0
- data/ext/libcouchbase/src/cntl.cc +28 -17
- data/ext/libcouchbase/src/dns-srv.cc +1 -2
- data/ext/libcouchbase/src/dump.cc +4 -0
- data/ext/libcouchbase/src/errmap.h +89 -16
- data/ext/libcouchbase/src/handler.cc +28 -11
- data/ext/libcouchbase/src/http/http-priv.h +4 -1
- data/ext/libcouchbase/src/http/http.cc +3 -0
- data/ext/libcouchbase/src/instance.cc +1 -1
- data/ext/libcouchbase/src/internal.h +1 -0
- data/ext/libcouchbase/src/lcbio/connect.cc +2 -3
- data/ext/libcouchbase/src/lcbio/manager.cc +2 -2
- data/ext/libcouchbase/src/lcbio/ssl.h +10 -0
- data/ext/libcouchbase/src/mc/mcreq.c +8 -0
- data/ext/libcouchbase/src/mcserver/mcserver.cc +14 -1
- data/ext/libcouchbase/src/n1ql/ixmgmt.cc +0 -3
- data/ext/libcouchbase/src/n1ql/n1ql.cc +22 -29
- data/ext/libcouchbase/src/n1ql/params.cc +46 -1
- data/ext/libcouchbase/src/newconfig.cc +4 -4
- data/ext/libcouchbase/src/operations/durability-seqno.cc +4 -0
- data/ext/libcouchbase/src/operations/durability.cc +3 -0
- data/ext/libcouchbase/src/operations/ping.cc +315 -0
- data/ext/libcouchbase/src/operations/stats.cc +10 -0
- data/ext/libcouchbase/src/operations/subdoc.cc +13 -1
- data/ext/libcouchbase/src/retrychk.cc +1 -0
- data/ext/libcouchbase/src/settings.c +2 -0
- data/ext/libcouchbase/src/settings.h +13 -7
- data/ext/libcouchbase/src/ssl/ssl_c.c +28 -2
- data/ext/libcouchbase/src/ssl/ssl_common.c +3 -0
- data/ext/libcouchbase/src/ssl/ssl_e.c +15 -1
- data/ext/libcouchbase/src/ssl/ssl_iot_common.h +3 -1
- data/ext/libcouchbase/src/timings.c +0 -1
- data/ext/libcouchbase/src/vbucket/vbucket.c +49 -1
- data/ext/libcouchbase/tests/iotests/mock-environment.cc +58 -40
- data/ext/libcouchbase/tests/iotests/mock-environment.h +23 -4
- data/ext/libcouchbase/tests/iotests/mock-unit-test.h +8 -8
- data/ext/libcouchbase/tests/iotests/t_behavior.cc +5 -5
- data/ext/libcouchbase/tests/iotests/t_durability.cc +50 -0
- data/ext/libcouchbase/tests/iotests/t_eerrs.cc +4 -2
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +6 -3
- data/ext/libcouchbase/tests/iotests/t_lock.cc +5 -6
- data/ext/libcouchbase/tests/iotests/t_misc.cc +44 -0
- data/ext/libcouchbase/tests/iotests/t_serverops.cc +1 -0
- data/ext/libcouchbase/tests/iotests/t_subdoc.cc +28 -0
- data/ext/libcouchbase/tests/iotests/t_views.cc +22 -10
- data/ext/libcouchbase/tools/CMakeLists.txt +21 -1
- data/ext/libcouchbase/tools/cbc-handlers.h +23 -3
- data/ext/libcouchbase/tools/cbc-n1qlback.cc +1 -1
- data/ext/libcouchbase/tools/cbc-pillowfight.cc +126 -26
- data/ext/libcouchbase/tools/cbc-proxy.cc +403 -0
- data/ext/libcouchbase/tools/cbc-subdoc.cc +826 -0
- data/ext/libcouchbase/tools/cbc.cc +149 -37
- data/ext/libcouchbase/tools/common/options.h +5 -2
- data/ext/libcouchbase/tools/linenoise/linenoise.c +15 -15
- data/lib/libcouchbase.rb +4 -0
- data/lib/libcouchbase/bucket.rb +51 -0
- data/lib/libcouchbase/connection.rb +100 -13
- data/lib/libcouchbase/ext/libcouchbase.rb +40 -0
- data/lib/libcouchbase/ext/libcouchbase/cmdsubdoc.rb +13 -1
- data/lib/libcouchbase/ext/libcouchbase/enums.rb +2 -1
- data/lib/libcouchbase/ext/libcouchbase/sdspec.rb +5 -0
- data/lib/libcouchbase/subdoc_request.rb +129 -0
- data/lib/libcouchbase/version.rb +1 -1
- data/spec/bucket_spec.rb +15 -1
- data/spec/connection_spec.rb +1 -1
- data/spec/subdoc_spec.rb +192 -0
- metadata +13 -4
- data/ext/libcouchbase/.travis.yml +0 -19
@@ -184,6 +184,7 @@ handle_bcast(mc_PIPELINE *pipeline, mc_PACKET *req, lcb_error_t err,
|
|
184
184
|
lcb_RESPVERBOSITY *verbosity;
|
185
185
|
lcb_RESPMCVERSION *version;
|
186
186
|
lcb_RESPFLUSH *flush;
|
187
|
+
lcb_RESPNOOP *noop;
|
187
188
|
} u_resp;
|
188
189
|
|
189
190
|
union {
|
@@ -191,6 +192,7 @@ handle_bcast(mc_PIPELINE *pipeline, mc_PACKET *req, lcb_error_t err,
|
|
191
192
|
lcb_RESPVERBOSITY verbosity;
|
192
193
|
lcb_RESPMCVERSION version;
|
193
194
|
lcb_RESPFLUSH flush;
|
195
|
+
lcb_RESPNOOP noop;
|
194
196
|
} u_empty;
|
195
197
|
|
196
198
|
memset(&u_empty, 0, sizeof(u_empty));
|
@@ -258,6 +260,8 @@ pkt_bcast_simple(lcb_t instance, const void *cookie, lcb_CALLBACKTYPE type)
|
|
258
260
|
hdr.request.opcode = PROTOCOL_BINARY_CMD_FLUSH;
|
259
261
|
} else if (type == LCB_CALLBACK_VERSIONS) {
|
260
262
|
hdr.request.opcode = PROTOCOL_BINARY_CMD_VERSION;
|
263
|
+
} else if (type == LCB_CALLBACK_NOOP) {
|
264
|
+
hdr.request.opcode = PROTOCOL_BINARY_CMD_NOOP;
|
261
265
|
} else {
|
262
266
|
fprintf(stderr, "pkt_bcast_simple passed unknown type %u\n", type);
|
263
267
|
assert(0);
|
@@ -284,6 +288,12 @@ lcb_server_versions3(lcb_t instance, const void *cookie, const lcb_CMDBASE *)
|
|
284
288
|
return pkt_bcast_simple(instance, cookie, LCB_CALLBACK_VERSIONS);
|
285
289
|
}
|
286
290
|
|
291
|
+
LIBCOUCHBASE_API
|
292
|
+
lcb_error_t
|
293
|
+
lcb_noop3(lcb_t instance, const void *cookie, const lcb_CMDNOOP *)
|
294
|
+
{
|
295
|
+
return pkt_bcast_simple(instance, cookie, LCB_CALLBACK_NOOP);
|
296
|
+
}
|
287
297
|
|
288
298
|
LIBCOUCHBASE_API
|
289
299
|
lcb_error_t
|
@@ -234,8 +234,20 @@ make_doc_flags(const uint32_t user) {
|
|
234
234
|
}
|
235
235
|
|
236
236
|
struct MultiBuilder {
|
237
|
+
static unsigned infer_mode(const lcb_CMDSUBDOC *cmd) {
|
238
|
+
if (cmd->nspecs == 0) {
|
239
|
+
return 0;
|
240
|
+
}
|
241
|
+
const SubdocCmdTraits::Traits& trait = SubdocCmdTraits::find(cmd->specs[0].sdcmd);
|
242
|
+
if (!trait.valid()) {
|
243
|
+
return 0;
|
244
|
+
}
|
245
|
+
return trait.mode();
|
246
|
+
}
|
247
|
+
|
237
248
|
MultiBuilder(const lcb_CMDSUBDOC *cmd_)
|
238
|
-
: cmd(cmd_), payload_size(0)
|
249
|
+
: cmd(cmd_), payload_size(0) {
|
250
|
+
mode = infer_mode(cmd_);
|
239
251
|
size_t ebufsz = is_lookup() ? cmd->nspecs * 4 : cmd->nspecs * 8;
|
240
252
|
extra_body = new char[ebufsz];
|
241
253
|
bodysz = 0;
|
@@ -60,6 +60,8 @@ void lcb_default_settings(lcb_settings *settings)
|
|
60
60
|
settings->select_bucket = LCB_DEFAULT_SELECT_BUCKET;
|
61
61
|
settings->tcp_keepalive = LCB_DEFAULT_TCP_KEEPALIVE;
|
62
62
|
settings->send_hello = 1;
|
63
|
+
settings->config_poll_interval = LCB_DEFAULT_CONFIG_POLL_INTERVAL;
|
64
|
+
settings->use_errmap = 1;
|
63
65
|
}
|
64
66
|
|
65
67
|
LCB_INTERNAL_API
|
@@ -23,21 +23,23 @@
|
|
23
23
|
*/
|
24
24
|
|
25
25
|
/** Convert seconds to millis */
|
26
|
-
#define LCB_S2MS(s) ((lcb_uint32_t)s) * 1000
|
26
|
+
#define LCB_S2MS(s) (((lcb_uint32_t)s) * 1000)
|
27
27
|
|
28
28
|
/** Convert seconds to microseconds */
|
29
|
-
#define LCB_S2US(s) ((lcb_uint32_t)s) * 1000000
|
29
|
+
#define LCB_S2US(s) (((lcb_uint32_t)s) * 1000000)
|
30
30
|
|
31
31
|
/** Convert seconds to nanoseconds */
|
32
|
-
#define LCB_S2NS(s) ((hrtime_t)s) * 1000000000
|
32
|
+
#define LCB_S2NS(s) (((hrtime_t)s) * 1000000000)
|
33
33
|
|
34
34
|
/** Convert nanoseconds to microseconds */
|
35
35
|
#define LCB_NS2US(s) (lcb_uint32_t) ((s) / 1000)
|
36
36
|
|
37
|
-
#define LCB_MS2US(s) (s) * 1000
|
37
|
+
#define LCB_MS2US(s) ((s) * 1000)
|
38
38
|
|
39
39
|
/** Convert microseconds to nanoseconds */
|
40
|
-
#define LCB_US2NS(s) ((hrtime_t)s) * 1000
|
40
|
+
#define LCB_US2NS(s) (((hrtime_t)s) * 1000)
|
41
|
+
/** Convert milliseconds to nanoseconds */
|
42
|
+
#define LCB_MS2NS(s) (((hrtime_t)s) * 1000000)
|
41
43
|
|
42
44
|
|
43
45
|
#define LCB_DEFAULT_TIMEOUT LCB_MS2US(2500)
|
@@ -56,8 +58,8 @@
|
|
56
58
|
#define LCB_DEFAULT_CONFIG_MAXIMUM_REDIRECTS 3
|
57
59
|
#define LCB_DEFAULT_CONFIG_ERRORS_THRESHOLD 100
|
58
60
|
|
59
|
-
/* 10
|
60
|
-
#define LCB_DEFAULT_CONFIG_ERRORS_DELAY LCB_MS2US(
|
61
|
+
/* 10 milliseconds */
|
62
|
+
#define LCB_DEFAULT_CONFIG_ERRORS_DELAY LCB_MS2US(10)
|
61
63
|
|
62
64
|
/* 1 second */
|
63
65
|
#define LCB_DEFAULT_CLCONFIG_GRACE_CYCLE LCB_MS2US(1000)
|
@@ -86,6 +88,10 @@
|
|
86
88
|
#define LCB_DEFAULT_TCP_NODELAY 1
|
87
89
|
#define LCB_DEFAULT_SELECT_BUCKET 1
|
88
90
|
#define LCB_DEFAULT_TCP_KEEPALIVE 1
|
91
|
+
/* 2.5 s */
|
92
|
+
#define LCB_DEFAULT_CONFIG_POLL_INTERVAL LCB_MS2US(2500)
|
93
|
+
/* 50 ms */
|
94
|
+
#define LCB_CONFIG_POLL_INTERVAL_FLOOR LCB_MS2US(50)
|
89
95
|
|
90
96
|
#include "config.h"
|
91
97
|
#include <libcouchbase/couchbase.h>
|
@@ -189,16 +189,26 @@ appdata_read(lcbio_CSSL *cs)
|
|
189
189
|
static void
|
190
190
|
read_callback(lcb_sockdata_t *sd, lcb_ssize_t nr, void *arg)
|
191
191
|
{
|
192
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
192
193
|
lcbio_CSSL *cs = arg;
|
194
|
+
#else
|
195
|
+
my_WBUF *rb = arg;
|
196
|
+
lcbio_CSSL *cs = rb->parent;
|
197
|
+
#endif
|
198
|
+
|
193
199
|
cs->rdactive = 0;
|
194
200
|
cs->entered++;
|
195
201
|
|
196
202
|
if (nr > 0) {
|
203
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
197
204
|
BUF_MEM *mb;
|
198
205
|
|
199
206
|
BIO_clear_retry_flags(cs->rbio);
|
200
207
|
BIO_get_mem_ptr(cs->rbio, &mb);
|
201
208
|
mb->length += nr;
|
209
|
+
#else
|
210
|
+
BIO_write(cs->rbio, rb->buf, nr);
|
211
|
+
#endif
|
202
212
|
|
203
213
|
} else if (nr == 0) {
|
204
214
|
cs->closed = 1;
|
@@ -208,6 +218,9 @@ read_callback(lcb_sockdata_t *sd, lcb_ssize_t nr, void *arg)
|
|
208
218
|
cs->error = 1;
|
209
219
|
IOTSSL_ERRNO(cs) = IOT_ERRNO(cs->orig);
|
210
220
|
}
|
221
|
+
#if !LCB_CAN_OPTIMIZE_SSL_BIO
|
222
|
+
free(rb);
|
223
|
+
#endif
|
211
224
|
|
212
225
|
appdata_encode(cs);
|
213
226
|
appdata_read(cs);
|
@@ -271,17 +284,30 @@ schedule_wants(lcbio_CSSL *cs)
|
|
271
284
|
|
272
285
|
} else if (SSL_want_read(cs->ssl) || (cs->urd_cb && has_appdata == 0)) {
|
273
286
|
/* request more data from the socket */
|
274
|
-
BUF_MEM *mb;
|
275
287
|
lcb_IOV iov;
|
288
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
289
|
+
BUF_MEM *mb;
|
290
|
+
#else
|
291
|
+
#define BUFSZ 4096
|
292
|
+
my_WBUF *rb = malloc(sizeof(*rb) + BUFSZ);
|
293
|
+
rb->parent = cs;
|
294
|
+
#endif
|
276
295
|
|
277
296
|
cs->rdactive = 1;
|
297
|
+
lcbio_table_ref(&cs->base_);
|
298
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
278
299
|
BIO_get_mem_ptr(cs->rbio, &mb);
|
279
300
|
iotssl_bm_reserve(mb);
|
280
301
|
iov.iov_base = mb->data + mb->length;
|
281
302
|
iov.iov_len = mb->max - mb->length;
|
282
|
-
lcbio_table_ref(&cs->base_);
|
283
303
|
IOT_V1(cs->orig).read2(
|
284
304
|
IOT_ARG(cs->orig), cs->sd, &iov, 1, cs, read_callback);
|
305
|
+
#else
|
306
|
+
iov.iov_base = rb->buf;
|
307
|
+
iov.iov_len = BUFSZ;
|
308
|
+
IOT_V1(cs->orig).read2(
|
309
|
+
IOT_ARG(cs->orig), cs->sd, &iov, 1, rb, read_callback);
|
310
|
+
#endif
|
285
311
|
}
|
286
312
|
|
287
313
|
}
|
@@ -127,6 +127,7 @@ iotssl_destroy_common(lcbio_XSSL *xs)
|
|
127
127
|
lcbio_table_unref(xs->orig);
|
128
128
|
}
|
129
129
|
|
130
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
130
131
|
void
|
131
132
|
iotssl_bm_reserve(BUF_MEM *bm)
|
132
133
|
{
|
@@ -139,6 +140,7 @@ iotssl_bm_reserve(BUF_MEM *bm)
|
|
139
140
|
}
|
140
141
|
bm->length = oldlen;
|
141
142
|
}
|
143
|
+
#endif
|
142
144
|
|
143
145
|
void
|
144
146
|
iotssl_log_errors(lcbio_XSSL *xs)
|
@@ -428,6 +430,7 @@ ossl_init_locks(void)
|
|
428
430
|
for (ii = 0; ii < nlocks; ii++) {
|
429
431
|
ossl_lock_init(ossl_locks + ii);
|
430
432
|
}
|
433
|
+
/* TODO: locking API has been removed in OpenSSL 1.1 */
|
431
434
|
CRYPTO_set_locking_callback(ossl_lockfn);
|
432
435
|
}
|
433
436
|
|
@@ -112,24 +112,38 @@ schedule_pending(lcbio_ESSL *es)
|
|
112
112
|
static int
|
113
113
|
read_ssl_data(lcbio_ESSL *es)
|
114
114
|
{
|
115
|
-
BUF_MEM *rmb;
|
116
115
|
int nr;
|
117
116
|
lcbio_pTABLE iot = es->orig;
|
118
117
|
|
118
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
119
|
+
BUF_MEM *rmb;
|
120
|
+
|
119
121
|
/* This block is an optimization over BIO_write to avoid copying the memory
|
120
122
|
* to a temporary buffer and _then_ copying it into the BIO */
|
121
123
|
|
122
124
|
BIO_get_mem_ptr(es->rbio, &rmb);
|
125
|
+
#endif
|
126
|
+
|
123
127
|
while (1) {
|
128
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
124
129
|
/* I don't know why this is here, but it's found inside BIO_write */
|
125
130
|
BIO_clear_retry_flags(es->rbio);
|
126
131
|
iotssl_bm_reserve(rmb);
|
127
132
|
nr = IOT_V0IO(iot).recv(IOT_ARG(iot), es->fd,
|
128
133
|
rmb->data + rmb->length, rmb->max - rmb->length, 0);
|
134
|
+
#else
|
135
|
+
#define BUFSZ 4096
|
136
|
+
char buf[BUFSZ];
|
137
|
+
nr = IOT_V0IO(iot).recv(IOT_ARG(iot), es->fd, buf, BUFSZ, 0);
|
138
|
+
#endif
|
129
139
|
|
130
140
|
if (nr > 0) {
|
141
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
131
142
|
/* Extend the BIO used length */
|
132
143
|
rmb->length += nr;
|
144
|
+
#else
|
145
|
+
BIO_write(es->rbio, buf, nr);
|
146
|
+
#endif
|
133
147
|
} else if (nr == 0) {
|
134
148
|
es->closed = 1;
|
135
149
|
return -1;
|
@@ -31,7 +31,7 @@
|
|
31
31
|
lcbio_pTABLE orig; /**< Table pointer we are wrapping */ \
|
32
32
|
SSL *ssl; /**< SSL object */ \
|
33
33
|
BIO *wbio; /**< BIO used for writing data to network */ \
|
34
|
-
BIO *rbio;
|
34
|
+
BIO *rbio; /**< BIO used for reading data from network */\
|
35
35
|
lcb_io_opt_t iops_dummy_; /**< Dummy IOPS structure which is exposed to LCB */ \
|
36
36
|
int error; /**< Internal error flag set once a fatal error is detect */\
|
37
37
|
lcb_error_t errcode; /**< The error, converted into libcouchbase */
|
@@ -113,6 +113,7 @@ iotssl_init_common(lcbio_XSSL *xs, lcbio_TABLE *orig, SSL_CTX *ctx);
|
|
113
113
|
void
|
114
114
|
iotssl_destroy_common(lcbio_XSSL *xs);
|
115
115
|
|
116
|
+
#if LCB_CAN_OPTIMIZE_SSL_BIO
|
116
117
|
/**
|
117
118
|
* Reserve a specified amount of bytes for reading into a `BUF_MEM*` structure.
|
118
119
|
* Currently the amount reserved is hard coded.
|
@@ -132,6 +133,7 @@ iotssl_destroy_common(lcbio_XSSL *xs);
|
|
132
133
|
*/
|
133
134
|
void
|
134
135
|
iotssl_bm_reserve(BUF_MEM *bm);
|
136
|
+
#endif
|
135
137
|
|
136
138
|
/**
|
137
139
|
* Prepare the SSL structure so that a subsequent call to SSL_pending will
|
@@ -329,6 +329,7 @@ extract_services(lcbvb_CONFIG *cfg, cJSON *jsvc, lcbvb_SERVICES *svc, int is_ssl
|
|
329
329
|
EXTRACT_SERVICE("fts", fts);
|
330
330
|
EXTRACT_SERVICE("indexAdmin", ixadmin);
|
331
331
|
EXTRACT_SERVICE("indexScan", ixquery);
|
332
|
+
EXTRACT_SERVICE("cbas", cbas);
|
332
333
|
|
333
334
|
#undef EXTRACT_SERVICE
|
334
335
|
|
@@ -360,6 +361,9 @@ build_server_strings(lcbvb_CONFIG *cfg, lcbvb_SERVER *server)
|
|
360
361
|
if (server->ftspath == NULL && server->svc.fts) {
|
361
362
|
server->ftspath = strdup("/");
|
362
363
|
}
|
364
|
+
if (server->cbaspath == NULL && server->svc.cbas) {
|
365
|
+
server->cbaspath = strdup("/query/service");
|
366
|
+
}
|
363
367
|
return 1;
|
364
368
|
}
|
365
369
|
|
@@ -538,6 +542,36 @@ lcbvb_load_json(lcbvb_CONFIG *cfg, const char *data)
|
|
538
542
|
cfg->revid = -1;
|
539
543
|
}
|
540
544
|
|
545
|
+
cfg->caps = 0;
|
546
|
+
{
|
547
|
+
cJSON *jcaps = NULL;
|
548
|
+
if (get_jarray(cj, "bucketCapabilities", &jcaps)) {
|
549
|
+
unsigned ncaps = cJSON_GetArraySize(jcaps);
|
550
|
+
for (ii = 0; ii < ncaps; ii++) {
|
551
|
+
cJSON *jcap = cJSON_GetArrayItem(jcaps, ii);
|
552
|
+
if (jcap || jcap->type == cJSON_String) {
|
553
|
+
if (strcmp(jcap->valuestring, "xattr") == 0) {
|
554
|
+
cfg->caps |= LCBVB_CAP_XATTR;
|
555
|
+
} else if (strcmp(jcap->valuestring, "dcp") == 0) {
|
556
|
+
cfg->caps |= LCBVB_CAP_DCP;
|
557
|
+
} else if (strcmp(jcap->valuestring, "cbhello") == 0) {
|
558
|
+
cfg->caps |= LCBVB_CAP_CBHELLO;
|
559
|
+
} else if (strcmp(jcap->valuestring, "touch") == 0) {
|
560
|
+
cfg->caps |= LCBVB_CAP_TOUCH;
|
561
|
+
} else if (strcmp(jcap->valuestring, "couchapi") == 0) {
|
562
|
+
cfg->caps |= LCBVB_CAP_COUCHAPI;
|
563
|
+
} else if (strcmp(jcap->valuestring, "cccp") == 0) {
|
564
|
+
cfg->caps |= LCBVB_CAP_CCCP;
|
565
|
+
} else if (strcmp(jcap->valuestring, "xdcrCheckpointing") == 0) {
|
566
|
+
cfg->caps |= LCBVB_CAP_XDCR_CHECKPOINTING;
|
567
|
+
} else if (strcmp(jcap->valuestring, "nodesExt") == 0) {
|
568
|
+
cfg->caps |= LCBVB_CAP_NODES_EXT;
|
569
|
+
}
|
570
|
+
}
|
571
|
+
}
|
572
|
+
}
|
573
|
+
}
|
574
|
+
|
541
575
|
/** Get the number of nodes. This traverses the list. Yuck */
|
542
576
|
cfg->nsrv = cJSON_GetArraySize(jnodes);
|
543
577
|
|
@@ -680,6 +714,7 @@ free_service_strs(lcbvb_SERVICES *svc)
|
|
680
714
|
free(svc->views_base_);
|
681
715
|
free(svc->query_base_);
|
682
716
|
free(svc->fts_base_);
|
717
|
+
free(svc->cbas_base_);
|
683
718
|
}
|
684
719
|
|
685
720
|
void
|
@@ -692,6 +727,7 @@ lcbvb_destroy(lcbvb_CONFIG *conf)
|
|
692
727
|
free(srv->viewpath);
|
693
728
|
free(srv->querypath);
|
694
729
|
free(srv->ftspath);
|
730
|
+
free(srv->cbaspath);
|
695
731
|
free_service_strs(&srv->svc);
|
696
732
|
free_service_strs(&srv->svc_ssl);
|
697
733
|
}
|
@@ -1115,6 +1151,8 @@ lcbvb_get_port(lcbvb_CONFIG *cfg,
|
|
1115
1151
|
return svc->n1ql;
|
1116
1152
|
} else if (type == LCBVB_SVCTYPE_FTS) {
|
1117
1153
|
return svc->fts;
|
1154
|
+
} else if (type == LCBVB_SVCTYPE_CBAS) {
|
1155
|
+
return svc->cbas;
|
1118
1156
|
} else {
|
1119
1157
|
return 0;
|
1120
1158
|
}
|
@@ -1190,7 +1228,8 @@ lcbvb_get_randhost_ex(const lcbvb_CONFIG *cfg,
|
|
1190
1228
|
(type == LCBVB_SVCTYPE_MGMT && svcs->mgmt) ||
|
1191
1229
|
(type == LCBVB_SVCTYPE_N1QL && svcs->n1ql) ||
|
1192
1230
|
(type == LCBVB_SVCTYPE_FTS && svcs->fts) ||
|
1193
|
-
(type == LCBVB_SVCTYPE_VIEWS && svcs->views)
|
1231
|
+
(type == LCBVB_SVCTYPE_VIEWS && svcs->views) ||
|
1232
|
+
(type == LCBVB_SVCTYPE_CBAS && svcs->cbas);
|
1194
1233
|
|
1195
1234
|
if (has_svc) {
|
1196
1235
|
cfg->randbuf[oix++] = (int)nn;
|
@@ -1251,6 +1290,9 @@ lcbvb_get_resturl(lcbvb_CONFIG *cfg, unsigned ix,
|
|
1251
1290
|
} else if (svc == LCBVB_SVCTYPE_FTS) {
|
1252
1291
|
path = srv->ftspath;
|
1253
1292
|
strp = &svcs->fts_base_;
|
1293
|
+
} else if (svc == LCBVB_SVCTYPE_CBAS) {
|
1294
|
+
path = srv->cbaspath;
|
1295
|
+
strp = &svcs->cbas_base_;
|
1254
1296
|
} else {
|
1255
1297
|
/* Unknown service! */
|
1256
1298
|
return NULL;
|
@@ -1310,6 +1352,9 @@ copy_service(const char *hostname,
|
|
1310
1352
|
if (src->fts_base_) {
|
1311
1353
|
dst->fts_base_ = strdup(src->fts_base_);
|
1312
1354
|
}
|
1355
|
+
if (src->cbas_base_) {
|
1356
|
+
dst->cbas_base_ = strdup(src->cbas_base_);
|
1357
|
+
}
|
1313
1358
|
if (dst->data) {
|
1314
1359
|
sprintf(buf, "%s:%d", hostname, dst->data);
|
1315
1360
|
dst->hoststrs[LCBVB_SVCTYPE_DATA] = strdup(buf);
|
@@ -1401,6 +1446,9 @@ lcbvb_genconfig_ex(lcbvb_CONFIG *vb,
|
|
1401
1446
|
if (src->ftspath) {
|
1402
1447
|
dst->ftspath = strdup(src->ftspath);
|
1403
1448
|
}
|
1449
|
+
if (src->cbaspath) {
|
1450
|
+
dst->cbaspath = strdup(src->cbaspath);
|
1451
|
+
}
|
1404
1452
|
|
1405
1453
|
copy_service(src->hostname, &src->svc, &dst->svc);
|
1406
1454
|
copy_service(src->hostname, &src->svc_ssl, &dst->svc_ssl);
|
@@ -21,6 +21,9 @@
|
|
21
21
|
#include <mocksupport/server.h>
|
22
22
|
#include "mock-environment.h"
|
23
23
|
#include <sstream>
|
24
|
+
#include "internal.h" /* settings from lcb_t for logging */
|
25
|
+
|
26
|
+
#define LOGARGS(instance, lvl) instance->settings, "tests-ENV", LCB_LOG_##lvl, __FILE__, __LINE__
|
24
27
|
|
25
28
|
MockEnvironment *MockEnvironment::instance;
|
26
29
|
|
@@ -66,9 +69,10 @@ MockEnvironment::MockEnvironment(const char **args, std::string bucketname)
|
|
66
69
|
SetUp();
|
67
70
|
}
|
68
71
|
|
69
|
-
void MockEnvironment::failoverNode(int index, std::string bucket)
|
72
|
+
void MockEnvironment::failoverNode(int index, std::string bucket, bool rebalance)
|
70
73
|
{
|
71
74
|
MockBucketCommand bCmd(MockCommand::FAILOVER, index, bucket);
|
75
|
+
bCmd.set("rebalance", rebalance);
|
72
76
|
sendCommand(bCmd);
|
73
77
|
getResponse();
|
74
78
|
}
|
@@ -250,44 +254,61 @@ void MockEnvironment::createConnection(lcb_t &instance)
|
|
250
254
|
|
251
255
|
}
|
252
256
|
|
253
|
-
#define
|
257
|
+
#define STAT_VERSION "version"
|
254
258
|
|
255
259
|
extern "C" {
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
MockEnvironment *me = (MockEnvironment *)cookie;
|
261
|
-
ASSERT_EQ(LCB_SUCCESS, err);
|
262
|
-
|
263
|
-
if (resp->v.v0.server_endpoint == NULL) {
|
264
|
-
return;
|
265
|
-
}
|
266
|
-
|
267
|
-
if (!resp->v.v0.nkey) {
|
268
|
-
return;
|
269
|
-
}
|
260
|
+
static void statsCallback(lcb_t instance, const void *cookie, lcb_error_t err, const lcb_server_stat_resp_t *resp)
|
261
|
+
{
|
262
|
+
MockEnvironment *me = (MockEnvironment *)cookie;
|
263
|
+
ASSERT_EQ(LCB_SUCCESS, err);
|
270
264
|
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
return;
|
275
|
-
}
|
276
|
-
int version = ((const char *)resp->v.v0.bytes)[0] - '0';
|
277
|
-
if (version == 1) {
|
278
|
-
me->setServerVersion(MockEnvironment::VERSION_10);
|
279
|
-
} else if (version == 2) {
|
280
|
-
me->setServerVersion(MockEnvironment::VERSION_20);
|
265
|
+
if (resp->v.v0.server_endpoint == NULL) {
|
266
|
+
return;
|
267
|
+
}
|
281
268
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
resp->v.v0.nbytes);
|
286
|
-
std::cerr << "' assuming 1.x" << std::endl;
|
269
|
+
if (!resp->v.v0.nkey) {
|
270
|
+
return;
|
271
|
+
}
|
287
272
|
|
288
|
-
|
273
|
+
if (resp->v.v0.nkey != sizeof(STAT_VERSION) - 1 ||
|
274
|
+
memcmp(resp->v.v0.key, STAT_VERSION, sizeof(STAT_VERSION) - 1) != 0) {
|
275
|
+
return;
|
276
|
+
}
|
277
|
+
MockEnvironment::ServerVersion version = MockEnvironment::VERSION_UNKNOWN;
|
278
|
+
if (resp->v.v0.nbytes > 2) {
|
279
|
+
int major = ((const char *)resp->v.v0.bytes)[0] - '0';
|
280
|
+
int minor = ((const char *)resp->v.v0.bytes)[2] - '0';
|
281
|
+
switch (major) {
|
282
|
+
case 4:
|
283
|
+
switch (minor) {
|
284
|
+
case 0:
|
285
|
+
version = MockEnvironment::VERSION_40;
|
286
|
+
break;
|
287
|
+
case 1:
|
288
|
+
version = MockEnvironment::VERSION_41;
|
289
|
+
break;
|
290
|
+
case 5:
|
291
|
+
version = MockEnvironment::VERSION_45;
|
292
|
+
break;
|
293
|
+
case 6:
|
294
|
+
version = MockEnvironment::VERSION_46;
|
295
|
+
break;
|
296
|
+
}
|
297
|
+
break;
|
298
|
+
case 5:
|
299
|
+
version = MockEnvironment::VERSION_50;
|
300
|
+
break;
|
289
301
|
}
|
290
302
|
}
|
303
|
+
if (version == MockEnvironment::VERSION_UNKNOWN) {
|
304
|
+
lcb_log(LOGARGS(instance, ERROR), "Unable to determine version from string '%.*s', assuming 4.0",
|
305
|
+
(int)resp->v.v0.nbytes, (const char *)resp->v.v0.bytes);
|
306
|
+
version = MockEnvironment::VERSION_40;
|
307
|
+
}
|
308
|
+
me->setServerVersion(version);
|
309
|
+
lcb_log(LOGARGS(instance, INFO), "Using real cluster version %.*s (id=%d)", (int)resp->v.v0.nbytes,
|
310
|
+
(const char *)resp->v.v0.bytes, version);
|
311
|
+
}
|
291
312
|
}
|
292
313
|
|
293
314
|
void MockEnvironment::bootstrapRealCluster()
|
@@ -318,14 +339,11 @@ void MockEnvironment::bootstrapRealCluster()
|
|
318
339
|
// no body
|
319
340
|
}
|
320
341
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
featureRegistry.insert("replica_read");
|
327
|
-
featureRegistry.insert("lock");
|
328
|
-
}
|
342
|
+
featureRegistry.insert("observe");
|
343
|
+
featureRegistry.insert("views");
|
344
|
+
featureRegistry.insert("http");
|
345
|
+
featureRegistry.insert("replica_read");
|
346
|
+
featureRegistry.insert("lock");
|
329
347
|
|
330
348
|
numNodes = ii;
|
331
349
|
lcb_destroy(tmphandle);
|