couchbase 3.2.2 → 3.2.5
Sign up to get free protection for your applications and to get access to all the features.
- package/binding.gyp +5 -0
- package/deps/lcb/CMakeLists.txt +1 -1
- package/deps/lcb/CONTRIBUTING.md +1 -1
- package/deps/lcb/README.markdown +2 -2
- package/deps/lcb/RELEASE_NOTES.markdown +84 -17
- package/deps/lcb/cmake/Modules/GetVersionInfo.cmake +1 -1
- package/deps/lcb/contrib/cbsasl/src/scram-sha/scram_utils.cc +22 -26
- package/deps/lcb/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +20 -6
- package/deps/lcb/doc/Doxyfile +1 -1
- package/deps/lcb/example/minimal/query.c +9 -7
- package/deps/lcb/gyp_config/common/libcouchbase/configuration.h +3 -3
- package/deps/lcb/gyp_config/linux/arm64/config.h +243 -0
- package/deps/lcb/include/libcouchbase/couchbase.h +55 -1
- package/deps/lcb/include/libcouchbase/error.h +6 -1
- package/deps/lcb/include/libcouchbase/ixmgmt.h +15 -10
- package/deps/lcb/include/libcouchbase/tracing.h +2 -2
- package/deps/lcb/include/memcached/protocol_binary.h +21 -0
- package/deps/lcb/libcouchbase.gyp +353 -349
- package/deps/lcb/packaging/deb/control +1 -1
- package/deps/lcb/src/analytics/analytics_handle.cc +7 -5
- package/deps/lcb/src/analytics/analytics_handle.hh +28 -0
- package/deps/lcb/src/capi/cmd_counter.hh +18 -0
- package/deps/lcb/src/capi/cmd_exists.hh +18 -0
- package/deps/lcb/src/capi/cmd_get.hh +17 -0
- package/deps/lcb/src/capi/cmd_get_replica.hh +20 -1
- package/deps/lcb/src/capi/cmd_query.cc +13 -0
- package/deps/lcb/src/capi/cmd_query.hh +22 -14
- package/deps/lcb/src/capi/cmd_remove.hh +18 -0
- package/deps/lcb/src/capi/cmd_search.hh +6 -0
- package/deps/lcb/src/capi/cmd_store.hh +28 -21
- package/deps/lcb/src/capi/cmd_subdoc.hh +30 -0
- package/deps/lcb/src/capi/cmd_touch.hh +18 -0
- package/deps/lcb/src/capi/cmd_unlock.hh +18 -0
- package/deps/lcb/src/capi/cmd_view.hh +6 -0
- package/deps/lcb/src/capi/collection_qualifier.hh +6 -8
- package/deps/lcb/src/cntl.cc +42 -8
- package/deps/lcb/src/dns-srv.cc +5 -3
- package/deps/lcb/src/errmap.cc +5 -9
- package/deps/lcb/src/errmap.h +7 -3
- package/deps/lcb/src/handler.cc +24 -18
- package/deps/lcb/src/internal.h +2 -1
- package/deps/lcb/src/lcbio/ctx.cc +4 -2
- package/deps/lcb/src/mcserver/mcserver.cc +8 -5
- package/deps/lcb/src/mcserver/negotiate.cc +42 -17
- package/deps/lcb/src/n1ql/ixmgmt.cc +1 -2
- package/deps/lcb/src/n1ql/n1ql.cc +5 -1
- package/deps/lcb/src/n1ql/query_handle.cc +80 -44
- package/deps/lcb/src/n1ql/query_handle.hh +41 -3
- package/deps/lcb/src/operations/counter.cc +13 -1
- package/deps/lcb/src/operations/exists.cc +14 -2
- package/deps/lcb/src/operations/get.cc +14 -2
- package/deps/lcb/src/operations/get_replica.cc +18 -6
- package/deps/lcb/src/operations/observe.cc +1 -1
- package/deps/lcb/src/operations/remove.cc +13 -1
- package/deps/lcb/src/operations/store.cc +13 -1
- package/deps/lcb/src/operations/subdoc.cc +13 -2
- package/deps/lcb/src/operations/touch.cc +14 -2
- package/deps/lcb/src/operations/unlock.cc +14 -2
- package/deps/lcb/src/search/search_handle.cc +26 -8
- package/deps/lcb/src/search/search_handle.hh +29 -0
- package/deps/lcb/src/ssl/ssl_common.c +7 -8
- package/deps/lcb/src/tracing/span.cc +43 -10
- package/deps/lcb/src/tracing/tracing-internal.h +105 -93
- package/deps/lcb/src/utilities.cc +21 -0
- package/deps/lcb/src/utilities.h +3 -0
- package/deps/lcb/src/views/view_handle.cc +13 -5
- package/deps/lcb/src/views/view_handle.hh +29 -0
- package/deps/lcb/tests/CMakeLists.txt +21 -0
- package/deps/lcb/tests/basic/t_ctlcodes.cc +24 -3
- package/deps/lcb/tests/basic/t_jsparse.cc +8 -0
- package/deps/lcb/tests/iotests/mock-environment.cc +25 -1
- package/deps/lcb/tests/iotests/mock-environment.h +49 -1
- package/deps/lcb/tests/iotests/mock-unit-test.cc +96 -5
- package/deps/lcb/tests/iotests/mock-unit-test.h +32 -0
- package/deps/lcb/tests/iotests/serverparams.h +7 -2
- package/deps/lcb/tests/iotests/t_collections.cc +1 -1
- package/deps/lcb/tests/iotests/t_confmon.cc +4 -2
- package/deps/lcb/tests/iotests/t_get.cc +14 -4
- package/deps/lcb/tests/iotests/t_n1ql.cc +17 -1
- package/deps/lcb/tests/iotests/t_ratelimit.cc +729 -0
- package/deps/lcb/tests/iotests/t_views.cc +1 -0
- package/deps/lcb/tests/iotests/testutil.cc +342 -0
- package/deps/lcb/tests/iotests/testutil.h +164 -0
- package/deps/lcb/tests/mocksupport/procutil.c +32 -28
- package/deps/lcb/tests/mocksupport/server.c +0 -1
- package/deps/lcb/tools/cbc.cc +7 -0
- package/dist/analyticsexecutor.js +2 -2
- package/dist/analyticsindexmanager.js +512 -524
- package/dist/binarycollection.d.ts +17 -0
- package/dist/binding.d.ts +2 -0
- package/dist/binding.js +1 -1
- package/dist/bindingutilities.js +9 -1
- package/dist/bucketmanager.d.ts +32 -23
- package/dist/bucketmanager.js +197 -189
- package/dist/cluster.js +37 -36
- package/dist/collection.js +17 -23
- package/dist/collectionmanager.js +181 -200
- package/dist/connection.js +6 -3
- package/dist/connspec.js +5 -1
- package/dist/couchbase.js +7 -14
- package/dist/datastructures.js +239 -310
- package/dist/diagnosticsexecutor.js +70 -85
- package/dist/errors.d.ts +18 -0
- package/dist/errors.js +26 -2
- package/dist/eventingfunctionmanager.js +267 -294
- package/dist/httpexecutor.js +31 -38
- package/dist/logging.js +1 -1
- package/dist/queryexecutor.js +3 -3
- package/dist/queryindexmanager.js +236 -263
- package/dist/scope.js +8 -2
- package/dist/searchexecutor.js +3 -0
- package/dist/searchindexmanager.js +240 -271
- package/dist/searchquery.d.ts +17 -0
- package/dist/searchquery.js +22 -1
- package/dist/searchtypes.d.ts +7 -2
- package/dist/searchtypes.js +2 -2
- package/dist/usermanager.js +250 -263
- package/dist/utilities.d.ts +3 -2
- package/dist/utilities.js +16 -4
- package/dist/viewexecutor.js +1 -1
- package/dist/viewindexmanager.js +131 -150
- package/package.json +1 -1
- package/src/connection.cpp +2 -0
- package/src/constants.cpp +2 -0
- package/src/instance.cpp +8 -1
- package/src/instance.h +1 -0
- package/src/uv-plugin-all.cpp +1 -0
- package/dist/cas.d.ts +0 -0
- package/dist/cas.js +0 -1
@@ -95,32 +95,52 @@ static void prepare_rowcb(lcb_INSTANCE *instance, int, const lcb_RESPQUERY *row)
|
|
95
95
|
|
96
96
|
bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &rc)
|
97
97
|
{
|
98
|
-
|
99
|
-
|
98
|
+
first_error.message.clear();
|
99
|
+
first_error.code = 0;
|
100
100
|
|
101
101
|
Json::Value meta;
|
102
|
-
if (!Json::Reader().parse(row, row + row_len, meta)) {
|
102
|
+
if (!Json::Reader(Json::Features::strictMode()).parse(row, row + row_len, meta)) {
|
103
103
|
return false;
|
104
104
|
}
|
105
105
|
const Json::Value &errors = meta["errors"];
|
106
106
|
if (errors.isArray() && !errors.empty()) {
|
107
107
|
const Json::Value &err = errors[0];
|
108
|
+
if (err.isMember("retry") && err["retry"].isBool()) {
|
109
|
+
first_error.retry = err["retry"].asBool();
|
110
|
+
}
|
111
|
+
if (err.isMember("reason") && err["reason"].isObject()) {
|
112
|
+
const Json::Value &reason = err["reason"];
|
113
|
+
if (reason.isMember("code") && reason["code"].isNumeric()) {
|
114
|
+
first_error.reason_code = reason["code"].asInt();
|
115
|
+
}
|
116
|
+
}
|
108
117
|
const Json::Value &msg = err["msg"];
|
109
118
|
if (msg.isString()) {
|
110
|
-
|
119
|
+
first_error.message = msg.asString();
|
111
120
|
}
|
112
121
|
const Json::Value &code = err["code"];
|
113
122
|
if (code.isNumeric()) {
|
114
|
-
|
115
|
-
switch (
|
123
|
+
first_error.code = code.asUInt();
|
124
|
+
switch (first_error.code) {
|
116
125
|
case 3000:
|
117
126
|
rc = LCB_ERR_PARSING_FAILURE;
|
118
127
|
break;
|
119
128
|
case 12009:
|
120
129
|
rc = LCB_ERR_DML_FAILURE;
|
121
|
-
if (
|
130
|
+
if (first_error.message.find("CAS mismatch") != std::string::npos) {
|
122
131
|
rc = LCB_ERR_CAS_MISMATCH;
|
123
132
|
}
|
133
|
+
switch (first_error.reason_code) {
|
134
|
+
case 12033:
|
135
|
+
rc = LCB_ERR_CAS_MISMATCH;
|
136
|
+
break;
|
137
|
+
case 17014:
|
138
|
+
rc = LCB_ERR_DOCUMENT_NOT_FOUND;
|
139
|
+
break;
|
140
|
+
case 17012:
|
141
|
+
rc = LCB_ERR_DOCUMENT_EXISTS;
|
142
|
+
break;
|
143
|
+
}
|
124
144
|
break;
|
125
145
|
case 4040:
|
126
146
|
case 4050:
|
@@ -132,29 +152,34 @@ bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &
|
|
132
152
|
break;
|
133
153
|
case 4300:
|
134
154
|
rc = LCB_ERR_PLANNING_FAILURE;
|
135
|
-
if (!
|
155
|
+
if (!first_error.message.empty()) {
|
136
156
|
std::regex already_exists("index.+already exists");
|
137
|
-
if (std::regex_search(
|
157
|
+
if (std::regex_search(first_error.message, already_exists)) {
|
138
158
|
rc = LCB_ERR_INDEX_EXISTS;
|
139
159
|
}
|
140
160
|
}
|
141
161
|
break;
|
142
162
|
case 5000:
|
143
163
|
rc = LCB_ERR_INTERNAL_SERVER_FAILURE;
|
144
|
-
if (!
|
164
|
+
if (!first_error.message.empty()) {
|
145
165
|
std::regex already_exists("Index.+already exists"); /* NOTE: case sensitive */
|
146
|
-
|
166
|
+
std::regex not_found("index.+not found");
|
167
|
+
if (std::regex_search(first_error.message, already_exists)) {
|
147
168
|
rc = LCB_ERR_INDEX_EXISTS;
|
148
|
-
} else {
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
169
|
+
} else if (std::regex_search(first_error.message, not_found)) {
|
170
|
+
rc = LCB_ERR_INDEX_NOT_FOUND;
|
171
|
+
} else if (first_error.message.find(
|
172
|
+
"Limit for number of indexes that can be created per scope has been reached") !=
|
173
|
+
std::string::npos) {
|
174
|
+
rc = LCB_ERR_QUOTA_LIMITED;
|
153
175
|
}
|
154
176
|
}
|
155
177
|
break;
|
156
|
-
case 12004:
|
157
178
|
case 12016:
|
179
|
+
/* see MB-50643 */
|
180
|
+
first_error.retry = false;
|
181
|
+
/* fallthrough */
|
182
|
+
case 12004:
|
158
183
|
rc = LCB_ERR_INDEX_NOT_FOUND;
|
159
184
|
break;
|
160
185
|
case 12003:
|
@@ -166,15 +191,23 @@ bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &
|
|
166
191
|
case 13014:
|
167
192
|
rc = LCB_ERR_AUTHENTICATION_FAILURE;
|
168
193
|
break;
|
194
|
+
|
195
|
+
case 1191:
|
196
|
+
case 1192:
|
197
|
+
case 1193:
|
198
|
+
case 1194:
|
199
|
+
rc = LCB_ERR_RATE_LIMITED;
|
200
|
+
break;
|
201
|
+
|
169
202
|
default:
|
170
|
-
if (
|
203
|
+
if (first_error.code >= 4000 && first_error.code < 5000) {
|
171
204
|
rc = LCB_ERR_PLANNING_FAILURE;
|
172
|
-
} else if (
|
205
|
+
} else if (first_error.code >= 5000 && first_error.code < 6000) {
|
173
206
|
rc = LCB_ERR_INTERNAL_SERVER_FAILURE;
|
174
|
-
} else if (
|
207
|
+
} else if (first_error.code >= 10000 && first_error.code < 11000) {
|
175
208
|
rc = LCB_ERR_AUTHENTICATION_FAILURE;
|
176
|
-
} else if ((
|
177
|
-
(
|
209
|
+
} else if ((first_error.code >= 12000 && first_error.code < 13000) ||
|
210
|
+
(first_error.code >= 14000 && first_error.code < 15000)) {
|
178
211
|
rc = LCB_ERR_INDEX_FAILURE;
|
179
212
|
}
|
180
213
|
break;
|
@@ -195,8 +228,8 @@ void lcb_QUERY_HANDLE_::invoke_row(lcb_RESPQUERY *resp, bool is_last)
|
|
195
228
|
resp->ctx.endpoint = resp->htresp->ctx.endpoint;
|
196
229
|
resp->ctx.endpoint_len = resp->htresp->ctx.endpoint_len;
|
197
230
|
}
|
198
|
-
resp->ctx.client_context_id =
|
199
|
-
resp->ctx.client_context_id_len =
|
231
|
+
resp->ctx.client_context_id = client_context_id_.c_str();
|
232
|
+
resp->ctx.client_context_id_len = client_context_id_.size();
|
200
233
|
resp->ctx.statement = statement_.c_str();
|
201
234
|
resp->ctx.statement_len = statement_.size();
|
202
235
|
|
@@ -208,14 +241,18 @@ void lcb_QUERY_HANDLE_::invoke_row(lcb_RESPQUERY *resp, bool is_last)
|
|
208
241
|
resp->row = static_cast<const char *>(meta_buf.iov_base);
|
209
242
|
resp->nrow = meta_buf.iov_len;
|
210
243
|
parse_meta(resp->row, resp->nrow, resp->ctx.rc);
|
211
|
-
|
212
|
-
|
213
|
-
|
244
|
+
resp->ctx.error_response_body = resp->row;
|
245
|
+
resp->ctx.error_response_body_len = resp->nrow;
|
246
|
+
if (!first_error.message.empty()) {
|
247
|
+
resp->ctx.first_error_message = first_error.message.c_str();
|
248
|
+
resp->ctx.first_error_message_len = first_error.message.size();
|
249
|
+
}
|
250
|
+
resp->ctx.first_error_code = first_error.code;
|
251
|
+
if (span_ != nullptr) {
|
252
|
+
lcb::trace::finish_http_span(span_, this);
|
253
|
+
span_ = nullptr;
|
214
254
|
}
|
215
|
-
resp->ctx.first_error_code = first_error_code;
|
216
|
-
LCBTRACE_ADD_RETRIES(span_, retries_);
|
217
255
|
|
218
|
-
LCBTRACE_HTTP_FINISH(span_);
|
219
256
|
if (http_request_ != nullptr) {
|
220
257
|
http_request_->span = nullptr;
|
221
258
|
}
|
@@ -346,27 +383,27 @@ lcb_RETRY_ACTION lcb_QUERY_HANDLE_::has_retriable_error(lcb_STATUS &rc)
|
|
346
383
|
const uint32_t default_backoff = 100 /* ms */;
|
347
384
|
if (rc == LCB_ERR_PREPARED_STATEMENT_FAILURE) {
|
348
385
|
lcb_log(LOGARGS(this, TRACE), LOGFMT "Will retry request. rc: %s, code: %d, msg: %s", LOGID(this),
|
349
|
-
lcb_strerror_short(rc),
|
386
|
+
lcb_strerror_short(rc), first_error.code, first_error.message.c_str());
|
350
387
|
return {1, default_backoff};
|
351
388
|
}
|
352
|
-
if (
|
389
|
+
if (first_error.code == 13014 &&
|
353
390
|
LCBT_SETTING(instance_, auth)->mode() == LCBAUTH_MODE_DYNAMIC) { // datastore.couchbase.insufficient_credentials
|
354
391
|
auto result = request_credentials(LCBAUTH_REASON_AUTHENTICATION_FAILURE);
|
355
392
|
bool credentials_found = result == LCBAUTH_RESULT_OK;
|
356
393
|
lcb_log(LOGARGS(this, TRACE),
|
357
394
|
LOGFMT "Invalidate credentials and retry request. creds: %s, rc: %s, code: %d, msg: %s", LOGID(this),
|
358
|
-
credentials_found ? "ok" : "not_found", lcb_strerror_short(rc),
|
359
|
-
|
395
|
+
credentials_found ? "ok" : "not_found", lcb_strerror_short(rc), first_error.code,
|
396
|
+
first_error.message.c_str());
|
360
397
|
return {credentials_found, default_backoff};
|
361
398
|
}
|
362
|
-
if (!
|
399
|
+
if (!first_error.message.empty()) {
|
363
400
|
for (const auto &magic_string : wtf_magic_strings) {
|
364
|
-
if (
|
401
|
+
if (first_error.message.find(magic_string) != std::string::npos) {
|
365
402
|
lcb_log(LOGARGS(this, TRACE),
|
366
403
|
LOGFMT
|
367
404
|
"Special error message detected. Will retry request. rc: %s (update to %s), code: %d, msg: %s",
|
368
405
|
LOGID(this), lcb_strerror_short(rc), lcb_strerror_short(LCB_ERR_PREPARED_STATEMENT_FAILURE),
|
369
|
-
|
406
|
+
first_error.code, first_error.message.c_str());
|
370
407
|
rc = LCB_ERR_PREPARED_STATEMENT_FAILURE;
|
371
408
|
return {1, default_backoff};
|
372
409
|
}
|
@@ -376,7 +413,7 @@ lcb_RETRY_ACTION lcb_QUERY_HANDLE_::has_retriable_error(lcb_STATUS &rc)
|
|
376
413
|
if (rc == LCB_SUCCESS) {
|
377
414
|
return {0, 0};
|
378
415
|
}
|
379
|
-
return lcb_query_should_retry(instance_->settings, this, rc);
|
416
|
+
return lcb_query_should_retry(instance_->settings, this, rc, first_error.retry);
|
380
417
|
}
|
381
418
|
|
382
419
|
lcb_STATUS lcb_QUERY_HANDLE_::issue_htreq(const std::string &body)
|
@@ -426,7 +463,7 @@ lcb_STATUS lcb_QUERY_HANDLE_::issue_htreq(const std::string &body)
|
|
426
463
|
lcb_log(LOGARGS(this, TRACE),
|
427
464
|
LOGFMT "execute query: %.*s, idempotent=%s, timeout=%uus, grace_period=%uus, client_context_id=\"%s\"",
|
428
465
|
LOGID(this), (int)body.size(), body.c_str(), idempotent_ ? "true" : "false", timeout,
|
429
|
-
LCBT_SETTING(instance_, n1ql_grace_period),
|
466
|
+
LCBT_SETTING(instance_, n1ql_grace_period), client_context_id_.c_str());
|
430
467
|
return rc;
|
431
468
|
}
|
432
469
|
|
@@ -517,10 +554,10 @@ lcb_QUERY_HANDLE_::lcb_QUERY_HANDLE_(lcb_INSTANCE *obj, void *user_cookie, const
|
|
517
554
|
if (ccid.isNull()) {
|
518
555
|
char buf[32];
|
519
556
|
size_t nbuf = snprintf(buf, sizeof(buf), "%016" PRIx64, lcb_next_rand64());
|
520
|
-
|
521
|
-
json["client_context_id"] =
|
557
|
+
client_context_id_.assign(buf, nbuf);
|
558
|
+
json["client_context_id"] = client_context_id_;
|
522
559
|
} else {
|
523
|
-
|
560
|
+
client_context_id_ = ccid.asString();
|
524
561
|
}
|
525
562
|
if (json.isMember("readonly") && json["readonly"].asBool()) {
|
526
563
|
idempotent_ = true;
|
@@ -554,8 +591,7 @@ lcb_QUERY_HANDLE_::lcb_QUERY_HANDLE_(lcb_INSTANCE *obj, void *user_cookie, const
|
|
554
591
|
}
|
555
592
|
if (instance_->settings->tracer) {
|
556
593
|
parent_span_ = cmd->parent_span();
|
557
|
-
|
558
|
-
LCBTRACE_THRESHOLD_QUERY, span_);
|
594
|
+
span_ = lcb::trace::start_http_span_with_statement(instance_->settings, this, statement_);
|
559
595
|
}
|
560
596
|
}
|
561
597
|
|
@@ -27,6 +27,19 @@
|
|
27
27
|
#include "capi/cmd_query.hh"
|
28
28
|
#include "query_cache.hh"
|
29
29
|
|
30
|
+
/**
|
31
|
+
* @private
|
32
|
+
*/
|
33
|
+
namespace lcb
|
34
|
+
{
|
35
|
+
struct query_error {
|
36
|
+
std::string message{};
|
37
|
+
uint32_t code{};
|
38
|
+
bool retry{false};
|
39
|
+
uint32_t reason_code{0};
|
40
|
+
};
|
41
|
+
} // namespace lcb
|
42
|
+
|
30
43
|
/**
|
31
44
|
* @private
|
32
45
|
*/
|
@@ -246,6 +259,32 @@ struct lcb_QUERY_HANDLE_ : lcb::jsparse::Parser::Actions {
|
|
246
259
|
return LCB_SUCCESS;
|
247
260
|
}
|
248
261
|
|
262
|
+
static lcbtrace_THRESHOLDOPTS service()
|
263
|
+
{
|
264
|
+
return LCBTRACE_THRESHOLD_QUERY;
|
265
|
+
}
|
266
|
+
|
267
|
+
static const std::string &operation_name()
|
268
|
+
{
|
269
|
+
static std::string name = LCBTRACE_OP_QUERY;
|
270
|
+
return name;
|
271
|
+
}
|
272
|
+
|
273
|
+
lcbtrace_SPAN *parent_span() const
|
274
|
+
{
|
275
|
+
return parent_span_;
|
276
|
+
}
|
277
|
+
|
278
|
+
const std::string &client_context_id() const
|
279
|
+
{
|
280
|
+
return client_context_id_;
|
281
|
+
}
|
282
|
+
|
283
|
+
int retries() const
|
284
|
+
{
|
285
|
+
return retries_;
|
286
|
+
}
|
287
|
+
|
249
288
|
private:
|
250
289
|
void on_backoff();
|
251
290
|
|
@@ -269,9 +308,8 @@ struct lcb_QUERY_HANDLE_ : lcb::jsparse::Parser::Actions {
|
|
269
308
|
Json::Value json;
|
270
309
|
/** String of the original statement. Cached here to avoid jsoncpp lookups */
|
271
310
|
std::string statement_;
|
272
|
-
std::string
|
273
|
-
|
274
|
-
uint32_t first_error_code{};
|
311
|
+
std::string client_context_id_;
|
312
|
+
lcb::query_error first_error{};
|
275
313
|
|
276
314
|
/** Whether we're retrying this */
|
277
315
|
int retries_{0};
|
@@ -141,6 +141,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdcounter_on_behalf_of(lcb_CMDCOUNTER *cmd, con
|
|
141
141
|
return cmd->on_behalf_of(std::string(data, data_len));
|
142
142
|
}
|
143
143
|
|
144
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdcounter_on_behalf_of_extra_privilege(lcb_CMDCOUNTER *cmd, const char *privilege,
|
145
|
+
size_t privilege_len)
|
146
|
+
{
|
147
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
148
|
+
}
|
149
|
+
|
144
150
|
static lcb_STATUS counter_validate(lcb_INSTANCE *instance, const lcb_CMDCOUNTER *cmd)
|
145
151
|
{
|
146
152
|
if (cmd->key().empty()) {
|
@@ -184,6 +190,12 @@ static lcb_STATUS counter_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_C
|
|
184
190
|
if (err != LCB_SUCCESS) {
|
185
191
|
return err;
|
186
192
|
}
|
193
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
194
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
195
|
+
if (err != LCB_SUCCESS) {
|
196
|
+
return err;
|
197
|
+
}
|
198
|
+
}
|
187
199
|
}
|
188
200
|
|
189
201
|
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
@@ -237,7 +249,7 @@ static lcb_STATUS counter_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_C
|
|
237
249
|
}
|
238
250
|
memcpy(SPAN_BUFFER(&packet->kh_span) + offset, &expiry, sizeof(expiry));
|
239
251
|
|
240
|
-
|
252
|
+
rdata->span = lcb::trace::start_kv_span(instance->settings, packet, cmd);
|
241
253
|
TRACE_ARITHMETIC_BEGIN(instance, &hdr, cmd);
|
242
254
|
LCB_SCHED_ADD(instance, pipeline, packet);
|
243
255
|
return LCB_SUCCESS;
|
@@ -112,6 +112,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdexists_on_behalf_of(lcb_CMDEXISTS *cmd, const
|
|
112
112
|
return cmd->on_behalf_of(std::string(data, data_len));
|
113
113
|
}
|
114
114
|
|
115
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdexists_on_behalf_of_extra_privilege(lcb_CMDEXISTS *cmd, const char *privilege,
|
116
|
+
size_t privilege_len)
|
117
|
+
{
|
118
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
119
|
+
}
|
120
|
+
|
115
121
|
static lcb_STATUS exists_validate(lcb_INSTANCE *instance, const lcb_CMDEXISTS *cmd)
|
116
122
|
{
|
117
123
|
if (cmd->key().empty()) {
|
@@ -139,6 +145,12 @@ static lcb_STATUS exists_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
|
|
139
145
|
if (err != LCB_SUCCESS) {
|
140
146
|
return err;
|
141
147
|
}
|
148
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
149
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
150
|
+
if (err != LCB_SUCCESS) {
|
151
|
+
return err;
|
152
|
+
}
|
153
|
+
}
|
142
154
|
}
|
143
155
|
|
144
156
|
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
@@ -153,7 +165,7 @@ static lcb_STATUS exists_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
|
|
153
165
|
|
154
166
|
hdr.request.opcode = PROTOCOL_BINARY_CMD_GET_META;
|
155
167
|
hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
|
156
|
-
hdr.request.bodylen =
|
168
|
+
hdr.request.bodylen = ntohl(mcreq_get_key_size(&hdr));
|
157
169
|
hdr.request.opaque = pkt->opaque;
|
158
170
|
hdr.request.cas = 0;
|
159
171
|
|
@@ -168,7 +180,7 @@ static lcb_STATUS exists_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
|
|
168
180
|
memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, framing_extras.data(), framing_extras.size());
|
169
181
|
}
|
170
182
|
|
171
|
-
|
183
|
+
pkt->u_rdata.reqdata.span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
|
172
184
|
LCB_SCHED_ADD(instance, pipeline, pkt)
|
173
185
|
TRACE_EXISTS_BEGIN(instance, &hdr, cmd);
|
174
186
|
return LCB_SUCCESS;
|
@@ -129,6 +129,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdget_on_behalf_of(lcb_CMDGET *cmd, const char
|
|
129
129
|
return cmd->on_behalf_of(std::string(data, data_len));
|
130
130
|
}
|
131
131
|
|
132
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdget_on_behalf_of_extra_privilege(lcb_CMDGET *cmd, const char *privilege,
|
133
|
+
size_t privilege_len)
|
134
|
+
{
|
135
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
136
|
+
}
|
137
|
+
|
132
138
|
static lcb_STATUS get_validate(lcb_INSTANCE *instance, const lcb_CMDGET *cmd)
|
133
139
|
{
|
134
140
|
if (cmd->key().empty()) {
|
@@ -159,6 +165,12 @@ static lcb_STATUS get_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMDGE
|
|
159
165
|
if (err != LCB_SUCCESS) {
|
160
166
|
return err;
|
161
167
|
}
|
168
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
169
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
170
|
+
if (err != LCB_SUCCESS) {
|
171
|
+
return err;
|
172
|
+
}
|
173
|
+
}
|
162
174
|
}
|
163
175
|
|
164
176
|
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
@@ -187,7 +199,7 @@ static lcb_STATUS get_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMDGE
|
|
187
199
|
|
188
200
|
hdr.request.opcode = opcode;
|
189
201
|
hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
|
190
|
-
hdr.request.bodylen = htonl(extlen + ffextlen +
|
202
|
+
hdr.request.bodylen = htonl(extlen + ffextlen + mcreq_get_key_size(&hdr));
|
191
203
|
hdr.request.opaque = pkt->opaque;
|
192
204
|
hdr.request.cas = 0;
|
193
205
|
|
@@ -209,7 +221,7 @@ static lcb_STATUS get_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMDGE
|
|
209
221
|
memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, &expiry, sizeof(expiry));
|
210
222
|
}
|
211
223
|
|
212
|
-
|
224
|
+
rdata->span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
|
213
225
|
LCB_SCHED_ADD(instance, pl, pkt)
|
214
226
|
TRACE_GET_BEGIN(instance, &hdr, cmd);
|
215
227
|
return LCB_SUCCESS;
|
@@ -144,6 +144,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdgetreplica_on_behalf_of(lcb_CMDGETREPLICA *cm
|
|
144
144
|
return cmd->on_behalf_of(std::string(data, data_len));
|
145
145
|
}
|
146
146
|
|
147
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdgetreplica_on_behalf_of_extra_privilege(lcb_CMDGETREPLICA *cmd,
|
148
|
+
const char *privilege, size_t privilege_len)
|
149
|
+
{
|
150
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
151
|
+
}
|
152
|
+
|
147
153
|
struct RGetCookie : mc_REQDATAEX {
|
148
154
|
RGetCookie(void *cookie, lcb_INSTANCE *instance, get_replica_mode, int vb);
|
149
155
|
void decref()
|
@@ -349,20 +355,26 @@ static lcb_STATUS get_replica_schedule(lcb_INSTANCE *instance, std::shared_ptr<l
|
|
349
355
|
return LCB_ERR_NO_MATCHING_SERVER;
|
350
356
|
}
|
351
357
|
|
352
|
-
/* Initialize the cookie */
|
353
|
-
auto *rck = new RGetCookie(cmd->cookie(), instance, cmd->mode(), vbid);
|
354
|
-
rck->start = cmd->start_time_or_default_in_nanoseconds(gethrtime());
|
355
|
-
rck->deadline =
|
356
|
-
rck->start + cmd->timeout_or_default_in_nanoseconds(LCB_US2NS(LCBT_SETTING(instance, operation_timeout)));
|
357
|
-
|
358
358
|
std::vector<std::uint8_t> framing_extras;
|
359
359
|
if (cmd->want_impersonation()) {
|
360
360
|
lcb_STATUS err = lcb::flexible_framing_extras::encode_impersonate_user(cmd->impostor(), framing_extras);
|
361
361
|
if (err != LCB_SUCCESS) {
|
362
362
|
return err;
|
363
363
|
}
|
364
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
365
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
366
|
+
if (err != LCB_SUCCESS) {
|
367
|
+
return err;
|
368
|
+
}
|
369
|
+
}
|
364
370
|
}
|
365
371
|
|
372
|
+
/* Initialize the cookie */
|
373
|
+
auto *rck = new RGetCookie(cmd->cookie(), instance, cmd->mode(), vbid);
|
374
|
+
rck->start = cmd->start_time_or_default_in_nanoseconds(gethrtime());
|
375
|
+
rck->deadline =
|
376
|
+
rck->start + cmd->timeout_or_default_in_nanoseconds(LCB_US2NS(LCBT_SETTING(instance, operation_timeout)));
|
377
|
+
|
366
378
|
/* Initialize the packet */
|
367
379
|
req.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
368
380
|
req.request.opcode = PROTOCOL_BINARY_CMD_GET_REPLICA;
|
@@ -129,7 +129,7 @@ static void handle_observe_callback(mc_PIPELINE *pl, mc_PACKET *pkt, lcb_CALLBAC
|
|
129
129
|
opc->remaining--;
|
130
130
|
if (opc->remaining == 0) {
|
131
131
|
TRACE_OBSERVE_END(instance, pkt);
|
132
|
-
|
132
|
+
lcb::trace::finish_kv_span(pl, pkt, nullptr);
|
133
133
|
delete opc;
|
134
134
|
}
|
135
135
|
}
|
@@ -117,6 +117,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdremove_on_behalf_of(lcb_CMDREMOVE *cmd, const
|
|
117
117
|
return cmd->on_behalf_of(std::string(data, data_len));
|
118
118
|
}
|
119
119
|
|
120
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdremove_on_behalf_of_extra_privilege(lcb_CMDREMOVE *cmd, const char *privilege,
|
121
|
+
size_t privilege_len)
|
122
|
+
{
|
123
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
124
|
+
}
|
125
|
+
|
120
126
|
static lcb_STATUS remove_validate(lcb_INSTANCE *instance, const lcb_CMDREMOVE *cmd)
|
121
127
|
{
|
122
128
|
if (cmd->key().empty()) {
|
@@ -159,6 +165,12 @@ static lcb_STATUS remove_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
|
|
159
165
|
if (err != LCB_SUCCESS) {
|
160
166
|
return err;
|
161
167
|
}
|
168
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
169
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
170
|
+
if (err != LCB_SUCCESS) {
|
171
|
+
return err;
|
172
|
+
}
|
173
|
+
}
|
162
174
|
}
|
163
175
|
|
164
176
|
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
@@ -188,7 +200,7 @@ static lcb_STATUS remove_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
|
|
188
200
|
if (!framing_extras.empty()) {
|
189
201
|
memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, framing_extras.data(), framing_extras.size());
|
190
202
|
}
|
191
|
-
|
203
|
+
pkt->u_rdata.reqdata.span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
|
192
204
|
TRACE_REMOVE_BEGIN(instance, &hdr, cmd);
|
193
205
|
LCB_SCHED_ADD(instance, pl, pkt)
|
194
206
|
return LCB_SUCCESS;
|
@@ -234,6 +234,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdstore_on_behalf_of(lcb_CMDSTORE *cmd, const c
|
|
234
234
|
return cmd->on_behalf_of(std::string(data, data_len));
|
235
235
|
}
|
236
236
|
|
237
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdstore_on_behalf_of_extra_privilege(lcb_CMDSTORE *cmd, const char *privilege,
|
238
|
+
size_t privilege_len)
|
239
|
+
{
|
240
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
241
|
+
}
|
242
|
+
|
237
243
|
struct DurStoreCtx : mc_REQDATAEX {
|
238
244
|
lcb_INSTANCE *instance;
|
239
245
|
lcb_U16 persist_to;
|
@@ -400,6 +406,12 @@ static lcb_STATUS store_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
|
|
400
406
|
if (err != LCB_SUCCESS) {
|
401
407
|
return err;
|
402
408
|
}
|
409
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
410
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
411
|
+
if (err != LCB_SUCCESS) {
|
412
|
+
return err;
|
413
|
+
}
|
414
|
+
}
|
403
415
|
}
|
404
416
|
auto ffextlen = static_cast<std::uint8_t>(framing_extras.size());
|
405
417
|
hdr.request.magic = (ffextlen == 0) ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
@@ -485,7 +497,7 @@ static lcb_STATUS store_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
|
|
485
497
|
if (cmd->is_replace_semantics()) {
|
486
498
|
packet->flags |= MCREQ_F_REPLACE_SEMANTICS;
|
487
499
|
}
|
488
|
-
|
500
|
+
rdata->span = lcb::trace::start_kv_span_with_durability(instance->settings, packet, cmd);
|
489
501
|
LCB_SCHED_ADD(instance, pipeline, packet)
|
490
502
|
|
491
503
|
TRACE_STORE_BEGIN(instance, &hdr, cmd);
|
@@ -409,6 +409,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdsubdoc_on_behalf_of(lcb_CMDSUBDOC *cmd, const
|
|
409
409
|
return cmd->on_behalf_of(std::string(data, data_len));
|
410
410
|
}
|
411
411
|
|
412
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdsubdoc_on_behalf_of_extra_privilege(lcb_CMDSUBDOC *cmd, const char *privilege,
|
413
|
+
size_t privilege_len)
|
414
|
+
{
|
415
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
416
|
+
}
|
417
|
+
|
412
418
|
namespace SubdocCmdTraits
|
413
419
|
{
|
414
420
|
enum Options {
|
@@ -798,6 +804,12 @@ static lcb_STATUS subdoc_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
|
|
798
804
|
if (rc != LCB_SUCCESS) {
|
799
805
|
return rc;
|
800
806
|
}
|
807
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
808
|
+
rc = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
809
|
+
if (rc != LCB_SUCCESS) {
|
810
|
+
return rc;
|
811
|
+
}
|
812
|
+
}
|
801
813
|
}
|
802
814
|
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
803
815
|
auto ffextlen = static_cast<std::uint8_t>(framing_extras.size());
|
@@ -853,8 +865,7 @@ static lcb_STATUS subdoc_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
|
|
853
865
|
MCREQ_PKT_RDATA(pkt)->start +
|
854
866
|
cmd->timeout_or_default_in_nanoseconds(LCB_US2NS(LCBT_SETTING(instance, operation_timeout)));
|
855
867
|
MCREQ_PKT_RDATA(pkt)->nsubreq = cmd->specs().specs().size();
|
856
|
-
|
857
|
-
ctx.is_mutate() ? LCBTRACE_OP_MUTATEIN : LCBTRACE_OP_LOOKUPIN, MCREQ_PKT_RDATA(pkt)->span);
|
868
|
+
MCREQ_PKT_RDATA(pkt)->span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
|
858
869
|
LCB_SCHED_ADD(instance, pl, pkt)
|
859
870
|
return LCB_SUCCESS;
|
860
871
|
}
|
@@ -117,6 +117,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdtouch_on_behalf_of(lcb_CMDTOUCH *cmd, const c
|
|
117
117
|
return cmd->on_behalf_of(std::string(data, data_len));
|
118
118
|
}
|
119
119
|
|
120
|
+
LIBCOUCHBASE_API lcb_STATUS lcb_cmdtouch_on_behalf_of_extra_privilege(lcb_CMDTOUCH *cmd, const char *privilege,
|
121
|
+
size_t privilege_len)
|
122
|
+
{
|
123
|
+
return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
|
124
|
+
}
|
125
|
+
|
120
126
|
static lcb_STATUS touch_validate(lcb_INSTANCE *instance, const lcb_CMDTOUCH *cmd)
|
121
127
|
{
|
122
128
|
if (cmd->key().empty()) {
|
@@ -142,6 +148,12 @@ static lcb_STATUS touch_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
|
|
142
148
|
if (err != LCB_SUCCESS) {
|
143
149
|
return err;
|
144
150
|
}
|
151
|
+
for (const auto &privilege : cmd->extra_privileges()) {
|
152
|
+
err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
|
153
|
+
if (err != LCB_SUCCESS) {
|
154
|
+
return err;
|
155
|
+
}
|
156
|
+
}
|
145
157
|
}
|
146
158
|
|
147
159
|
hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
|
@@ -158,7 +170,7 @@ static lcb_STATUS touch_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
|
|
158
170
|
hdr.request.cas = 0;
|
159
171
|
hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
|
160
172
|
hdr.request.opaque = pkt->opaque;
|
161
|
-
hdr.request.bodylen = htonl(hdr.request.extlen + ffextlen +
|
173
|
+
hdr.request.bodylen = htonl(hdr.request.extlen + ffextlen + mcreq_get_key_size(&hdr));
|
162
174
|
|
163
175
|
memcpy(SPAN_BUFFER(&pkt->kh_span), &hdr, sizeof(hdr));
|
164
176
|
std::size_t offset = sizeof(hdr);
|
@@ -174,7 +186,7 @@ static lcb_STATUS touch_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
|
|
174
186
|
pkt->u_rdata.reqdata.deadline =
|
175
187
|
pkt->u_rdata.reqdata.start +
|
176
188
|
cmd->timeout_or_default_in_nanoseconds(LCB_US2NS(LCBT_SETTING(instance, operation_timeout)));
|
177
|
-
|
189
|
+
pkt->u_rdata.reqdata.span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
|
178
190
|
LCB_SCHED_ADD(instance, pl, pkt);
|
179
191
|
TRACE_TOUCH_BEGIN(instance, &hdr, cmd);
|
180
192
|
return LCB_SUCCESS;
|