couchbase 3.2.2 → 3.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. package/binding.gyp +5 -0
  2. package/deps/lcb/CMakeLists.txt +1 -1
  3. package/deps/lcb/CONTRIBUTING.md +1 -1
  4. package/deps/lcb/README.markdown +2 -2
  5. package/deps/lcb/RELEASE_NOTES.markdown +84 -17
  6. package/deps/lcb/cmake/Modules/GetVersionInfo.cmake +1 -1
  7. package/deps/lcb/contrib/cbsasl/src/scram-sha/scram_utils.cc +22 -26
  8. package/deps/lcb/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +20 -6
  9. package/deps/lcb/doc/Doxyfile +1 -1
  10. package/deps/lcb/example/minimal/query.c +9 -7
  11. package/deps/lcb/gyp_config/common/libcouchbase/configuration.h +3 -3
  12. package/deps/lcb/gyp_config/linux/arm64/config.h +243 -0
  13. package/deps/lcb/include/libcouchbase/couchbase.h +55 -1
  14. package/deps/lcb/include/libcouchbase/error.h +6 -1
  15. package/deps/lcb/include/libcouchbase/ixmgmt.h +15 -10
  16. package/deps/lcb/include/libcouchbase/tracing.h +2 -2
  17. package/deps/lcb/include/memcached/protocol_binary.h +21 -0
  18. package/deps/lcb/libcouchbase.gyp +353 -349
  19. package/deps/lcb/packaging/deb/control +1 -1
  20. package/deps/lcb/src/analytics/analytics_handle.cc +7 -5
  21. package/deps/lcb/src/analytics/analytics_handle.hh +28 -0
  22. package/deps/lcb/src/capi/cmd_counter.hh +18 -0
  23. package/deps/lcb/src/capi/cmd_exists.hh +18 -0
  24. package/deps/lcb/src/capi/cmd_get.hh +17 -0
  25. package/deps/lcb/src/capi/cmd_get_replica.hh +20 -1
  26. package/deps/lcb/src/capi/cmd_query.cc +13 -0
  27. package/deps/lcb/src/capi/cmd_query.hh +22 -14
  28. package/deps/lcb/src/capi/cmd_remove.hh +18 -0
  29. package/deps/lcb/src/capi/cmd_search.hh +6 -0
  30. package/deps/lcb/src/capi/cmd_store.hh +28 -21
  31. package/deps/lcb/src/capi/cmd_subdoc.hh +30 -0
  32. package/deps/lcb/src/capi/cmd_touch.hh +18 -0
  33. package/deps/lcb/src/capi/cmd_unlock.hh +18 -0
  34. package/deps/lcb/src/capi/cmd_view.hh +6 -0
  35. package/deps/lcb/src/capi/collection_qualifier.hh +6 -8
  36. package/deps/lcb/src/cntl.cc +42 -8
  37. package/deps/lcb/src/dns-srv.cc +5 -3
  38. package/deps/lcb/src/errmap.cc +5 -9
  39. package/deps/lcb/src/errmap.h +7 -3
  40. package/deps/lcb/src/handler.cc +24 -18
  41. package/deps/lcb/src/internal.h +2 -1
  42. package/deps/lcb/src/lcbio/ctx.cc +4 -2
  43. package/deps/lcb/src/mcserver/mcserver.cc +8 -5
  44. package/deps/lcb/src/mcserver/negotiate.cc +42 -17
  45. package/deps/lcb/src/n1ql/ixmgmt.cc +1 -2
  46. package/deps/lcb/src/n1ql/n1ql.cc +5 -1
  47. package/deps/lcb/src/n1ql/query_handle.cc +80 -44
  48. package/deps/lcb/src/n1ql/query_handle.hh +41 -3
  49. package/deps/lcb/src/operations/counter.cc +13 -1
  50. package/deps/lcb/src/operations/exists.cc +14 -2
  51. package/deps/lcb/src/operations/get.cc +14 -2
  52. package/deps/lcb/src/operations/get_replica.cc +18 -6
  53. package/deps/lcb/src/operations/observe.cc +1 -1
  54. package/deps/lcb/src/operations/remove.cc +13 -1
  55. package/deps/lcb/src/operations/store.cc +13 -1
  56. package/deps/lcb/src/operations/subdoc.cc +13 -2
  57. package/deps/lcb/src/operations/touch.cc +14 -2
  58. package/deps/lcb/src/operations/unlock.cc +14 -2
  59. package/deps/lcb/src/search/search_handle.cc +26 -8
  60. package/deps/lcb/src/search/search_handle.hh +29 -0
  61. package/deps/lcb/src/ssl/ssl_common.c +7 -8
  62. package/deps/lcb/src/tracing/span.cc +43 -10
  63. package/deps/lcb/src/tracing/tracing-internal.h +105 -93
  64. package/deps/lcb/src/utilities.cc +21 -0
  65. package/deps/lcb/src/utilities.h +3 -0
  66. package/deps/lcb/src/views/view_handle.cc +13 -5
  67. package/deps/lcb/src/views/view_handle.hh +29 -0
  68. package/deps/lcb/tests/CMakeLists.txt +21 -0
  69. package/deps/lcb/tests/basic/t_ctlcodes.cc +24 -3
  70. package/deps/lcb/tests/basic/t_jsparse.cc +8 -0
  71. package/deps/lcb/tests/iotests/mock-environment.cc +25 -1
  72. package/deps/lcb/tests/iotests/mock-environment.h +49 -1
  73. package/deps/lcb/tests/iotests/mock-unit-test.cc +96 -5
  74. package/deps/lcb/tests/iotests/mock-unit-test.h +32 -0
  75. package/deps/lcb/tests/iotests/serverparams.h +7 -2
  76. package/deps/lcb/tests/iotests/t_collections.cc +1 -1
  77. package/deps/lcb/tests/iotests/t_confmon.cc +4 -2
  78. package/deps/lcb/tests/iotests/t_get.cc +14 -4
  79. package/deps/lcb/tests/iotests/t_n1ql.cc +17 -1
  80. package/deps/lcb/tests/iotests/t_ratelimit.cc +729 -0
  81. package/deps/lcb/tests/iotests/t_views.cc +1 -0
  82. package/deps/lcb/tests/iotests/testutil.cc +342 -0
  83. package/deps/lcb/tests/iotests/testutil.h +164 -0
  84. package/deps/lcb/tests/mocksupport/procutil.c +32 -28
  85. package/deps/lcb/tests/mocksupport/server.c +0 -1
  86. package/deps/lcb/tools/cbc.cc +7 -0
  87. package/dist/analyticsexecutor.js +2 -2
  88. package/dist/analyticsindexmanager.js +512 -524
  89. package/dist/binarycollection.d.ts +17 -0
  90. package/dist/binding.d.ts +2 -0
  91. package/dist/binding.js +1 -1
  92. package/dist/bindingutilities.js +9 -1
  93. package/dist/bucketmanager.d.ts +32 -23
  94. package/dist/bucketmanager.js +197 -189
  95. package/dist/cluster.js +37 -36
  96. package/dist/collection.js +17 -23
  97. package/dist/collectionmanager.js +181 -200
  98. package/dist/connection.js +6 -3
  99. package/dist/connspec.js +5 -1
  100. package/dist/couchbase.js +7 -14
  101. package/dist/datastructures.js +239 -310
  102. package/dist/diagnosticsexecutor.js +70 -85
  103. package/dist/errors.d.ts +18 -0
  104. package/dist/errors.js +26 -2
  105. package/dist/eventingfunctionmanager.js +267 -294
  106. package/dist/httpexecutor.js +31 -38
  107. package/dist/logging.js +1 -1
  108. package/dist/queryexecutor.js +3 -3
  109. package/dist/queryindexmanager.js +236 -263
  110. package/dist/scope.js +8 -2
  111. package/dist/searchexecutor.js +3 -0
  112. package/dist/searchindexmanager.js +240 -271
  113. package/dist/searchquery.d.ts +17 -0
  114. package/dist/searchquery.js +22 -1
  115. package/dist/searchtypes.d.ts +7 -2
  116. package/dist/searchtypes.js +2 -2
  117. package/dist/usermanager.js +250 -263
  118. package/dist/utilities.d.ts +3 -2
  119. package/dist/utilities.js +16 -4
  120. package/dist/viewexecutor.js +1 -1
  121. package/dist/viewindexmanager.js +131 -150
  122. package/package.json +1 -1
  123. package/src/connection.cpp +2 -0
  124. package/src/constants.cpp +2 -0
  125. package/src/instance.cpp +8 -1
  126. package/src/instance.h +1 -0
  127. package/src/uv-plugin-all.cpp +1 -0
  128. package/dist/cas.d.ts +0 -0
  129. 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
- first_error_message.clear();
99
- first_error_code = 0;
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
- first_error_message = msg.asString();
119
+ first_error.message = msg.asString();
111
120
  }
112
121
  const Json::Value &code = err["code"];
113
122
  if (code.isNumeric()) {
114
- first_error_code = code.asUInt();
115
- switch (first_error_code) {
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 (first_error_message.find("CAS mismatch") != std::string::npos) {
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 (!first_error_message.empty()) {
155
+ if (!first_error.message.empty()) {
136
156
  std::regex already_exists("index.+already exists");
137
- if (std::regex_search(first_error_message, already_exists)) {
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 (!first_error_message.empty()) {
164
+ if (!first_error.message.empty()) {
145
165
  std::regex already_exists("Index.+already exists"); /* NOTE: case sensitive */
146
- if (std::regex_search(first_error_message, already_exists)) {
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
- std::regex not_found("index.+not found");
150
- if (std::regex_search(first_error_message, not_found)) {
151
- rc = LCB_ERR_INDEX_NOT_FOUND;
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 (first_error_code >= 4000 && first_error_code < 5000) {
203
+ if (first_error.code >= 4000 && first_error.code < 5000) {
171
204
  rc = LCB_ERR_PLANNING_FAILURE;
172
- } else if (first_error_code >= 5000 && first_error_code < 6000) {
205
+ } else if (first_error.code >= 5000 && first_error.code < 6000) {
173
206
  rc = LCB_ERR_INTERNAL_SERVER_FAILURE;
174
- } else if (first_error_code >= 10000 && first_error_code < 11000) {
207
+ } else if (first_error.code >= 10000 && first_error.code < 11000) {
175
208
  rc = LCB_ERR_AUTHENTICATION_FAILURE;
176
- } else if ((first_error_code >= 12000 && first_error_code < 13000) ||
177
- (first_error_code >= 14000 && first_error_code < 15000)) {
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 = client_context_id.c_str();
199
- resp->ctx.client_context_id_len = client_context_id.size();
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
- if (!first_error_message.empty()) {
212
- resp->ctx.first_error_message = first_error_message.c_str();
213
- resp->ctx.first_error_message_len = first_error_message.size();
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), first_error_code, first_error_message.c_str());
386
+ lcb_strerror_short(rc), first_error.code, first_error.message.c_str());
350
387
  return {1, default_backoff};
351
388
  }
352
- if (first_error_code == 13014 &&
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), first_error_code,
359
- first_error_message.c_str());
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 (!first_error_message.empty()) {
399
+ if (!first_error.message.empty()) {
363
400
  for (const auto &magic_string : wtf_magic_strings) {
364
- if (first_error_message.find(magic_string) != std::string::npos) {
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
- first_error_code, first_error_message.c_str());
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), client_context_id.c_str());
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
- client_context_id.assign(buf, nbuf);
521
- json["client_context_id"] = client_context_id;
557
+ client_context_id_.assign(buf, nbuf);
558
+ json["client_context_id"] = client_context_id_;
522
559
  } else {
523
- client_context_id = ccid.asString();
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
- LCBTRACE_HTTP_START(instance_->settings, client_context_id.c_str(), parent_span_, LCBTRACE_TAG_SERVICE_N1QL,
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 client_context_id;
273
- std::string first_error_message{};
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
- LCBTRACE_KV_START(instance->settings, packet->opaque, cmd, LCBTRACE_OP_COUNTER, rdata->span);
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 = htonl(ntohs(hdr.request.keylen));
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
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd, LCBTRACE_OP_EXISTS, pkt->u_rdata.reqdata.span);
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 + ntohs(hdr.request.keylen));
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
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd, LCBTRACE_OP_GET, rdata->span);
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
- LCBTRACE_KV_FINISH(pl, pkt, resp, 0);
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
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd, LCBTRACE_OP_REMOVE, pkt->u_rdata.reqdata.span);
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
- LCBTRACE_KVSTORE_START(instance->settings, packet->opaque, cmd, cmd->operation_name(), rdata->span);
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
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd,
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 + ntohs(hdr.request.keylen));
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
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd, LCBTRACE_OP_TOUCH, pkt->u_rdata.reqdata.span);
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;