couchbase 3.2.2 → 3.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -106,6 +106,12 @@ LIBCOUCHBASE_API lcb_STATUS lcb_cmdunlock_on_behalf_of(lcb_CMDUNLOCK *cmd, const
106
106
  return cmd->on_behalf_of(std::string(data, data_len));
107
107
  }
108
108
 
109
+ LIBCOUCHBASE_API lcb_STATUS lcb_cmdunlock_on_behalf_of_extra_privilege(lcb_CMDUNLOCK *cmd, const char *privilege,
110
+ size_t privilege_len)
111
+ {
112
+ return cmd->on_behalf_of_add_extra_privilege(std::string(privilege, privilege_len));
113
+ }
114
+
109
115
  static lcb_STATUS unlock_validate(lcb_INSTANCE *instance, const lcb_CMDUNLOCK *cmd)
110
116
  {
111
117
  if (cmd->key().empty()) {
@@ -137,6 +143,12 @@ static lcb_STATUS unlock_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
137
143
  if (err != LCB_SUCCESS) {
138
144
  return err;
139
145
  }
146
+ for (const auto &privilege : cmd->extra_privileges()) {
147
+ err = lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(privilege, framing_extras);
148
+ if (err != LCB_SUCCESS) {
149
+ return err;
150
+ }
151
+ }
140
152
  }
141
153
 
142
154
  hdr.request.magic = framing_extras.empty() ? PROTOCOL_BINARY_REQ : PROTOCOL_BINARY_AREQ;
@@ -157,7 +169,7 @@ static lcb_STATUS unlock_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
157
169
 
158
170
  hdr.request.opcode = PROTOCOL_BINARY_CMD_UNLOCK_KEY;
159
171
  hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
160
- hdr.request.bodylen = htonl((lcb_uint32_t)ntohs(hdr.request.keylen));
172
+ hdr.request.bodylen = htonl(mcreq_get_key_size(&hdr));
161
173
  hdr.request.opaque = pkt->opaque;
162
174
  hdr.request.cas = lcb_htonll(cmd->cas());
163
175
 
@@ -166,7 +178,7 @@ static lcb_STATUS unlock_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
166
178
  if (!framing_extras.empty()) {
167
179
  memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, framing_extras.data(), framing_extras.size());
168
180
  }
169
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd, LCBTRACE_OP_UNLOCK, rd->span);
181
+ rd->span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
170
182
  LCB_SCHED_ADD(instance, pl, pkt);
171
183
  TRACE_UNLOCK_BEGIN(instance, &hdr, cmd);
172
184
  return LCB_SUCCESS;
@@ -23,6 +23,8 @@
23
23
  #include "search_handle.hh"
24
24
  #include "capi/cmd_http.hh"
25
25
 
26
+ #include <regex>
27
+
26
28
  #define LOGFMT "(NR=%p) "
27
29
  #define LOGID(req) static_cast<const void *>(req)
28
30
  #define LOGARGS(req, lvl) (req)->instance_->settings, "searchh", LCB_LOG_##lvl, __FILE__, __LINE__
@@ -73,7 +75,7 @@ void lcb_SEARCH_HANDLE_::invoke_row(lcb_RESPSEARCH *resp)
73
75
  if (callback_) {
74
76
  if (resp->rflags & LCB_RESP_F_FINAL) {
75
77
  Json::Value meta;
76
- if (Json::Reader().parse(resp->row, resp->row + resp->nrow, meta)) {
78
+ if (Json::Reader(Json::Features::strictMode()).parse(resp->row, resp->row + resp->nrow, meta)) {
77
79
  const Json::Value &top_error = meta["error"];
78
80
  if (top_error.isString()) {
79
81
  resp->ctx.has_top_level_error = 1;
@@ -92,9 +94,18 @@ void lcb_SEARCH_HANDLE_::invoke_row(lcb_RESPSEARCH *resp)
92
94
  resp->ctx.error_message_len = error_message_.size();
93
95
  if (error_message_.find("QueryBleve parsing") != std::string::npos) {
94
96
  resp->ctx.rc = LCB_ERR_PARSING_FAILURE;
95
- } else if (resp->ctx.http_response_code == 400 &&
96
- error_message_.find("not_found") != std::string::npos) {
97
- resp->ctx.rc = LCB_ERR_INDEX_NOT_FOUND;
97
+ } else if (resp->ctx.http_response_code == 400) {
98
+ if (error_message_.find("not_found") != std::string::npos) {
99
+ resp->ctx.rc = LCB_ERR_INDEX_NOT_FOUND;
100
+ } else if (error_message_.find("num_fts_indexes") != std::string::npos) {
101
+ resp->ctx.rc = LCB_ERR_QUOTA_LIMITED;
102
+ }
103
+ } else if (resp->ctx.http_response_code == 429) {
104
+ std::regex rate_limiting_message(
105
+ "num_concurrent_requests|num_queries_per_min|ingress_mib_per_min|egress_mib_per_min");
106
+ if (std::regex_search(error_message_, rate_limiting_message)) {
107
+ resp->ctx.rc = LCB_ERR_RATE_LIMITED;
108
+ }
98
109
  }
99
110
  }
100
111
  }
@@ -116,7 +127,10 @@ void lcb_SEARCH_HANDLE_::invoke_last()
116
127
  resp.nrow = meta.iov_len;
117
128
  }
118
129
 
119
- LCBTRACE_HTTP_FINISH(span_);
130
+ if (span_ != nullptr) {
131
+ lcb::trace::finish_http_span(span_, this);
132
+ span_ = nullptr;
133
+ }
120
134
  if (http_request_ != nullptr) {
121
135
  http_request_->span = nullptr;
122
136
  }
@@ -154,8 +168,13 @@ lcb_SEARCH_HANDLE_::lcb_SEARCH_HANDLE_(lcb_INSTANCE *instance, void *cookie, con
154
168
  return;
155
169
  }
156
170
  index_name_ = j_ixname.asString();
171
+ {
172
+ char buf[32];
173
+ size_t nbuf = snprintf(buf, sizeof(buf), "%016" PRIx64, lcb_next_rand64());
174
+ client_context_id_.assign(buf, nbuf);
175
+ }
157
176
  if (instance_->settings->tracer) {
158
- span_ = cmd->parent_span();
177
+ parent_span_ = cmd->parent_span();
159
178
  }
160
179
 
161
180
  std::string url;
@@ -182,8 +201,7 @@ lcb_SEARCH_HANDLE_::lcb_SEARCH_HANDLE_(lcb_INSTANCE *instance, void *cookie, con
182
201
  std::string qbody(Json::FastWriter().write(root));
183
202
  lcb_cmdhttp_body(htcmd, qbody.c_str(), qbody.size());
184
203
 
185
- LCBTRACE_HTTP_START(instance_->settings, nullptr, span_, LCBTRACE_TAG_SERVICE_SEARCH, LCBTRACE_THRESHOLD_SEARCH,
186
- span_);
204
+ span_ = lcb::trace::start_http_span(instance_->settings, this);
187
205
  lcb_cmdhttp_parent_span(htcmd, span_);
188
206
 
189
207
  last_error_ = lcb_http(instance_, this, htcmd);
@@ -115,6 +115,32 @@ struct lcb_SEARCH_HANDLE_ : lcb::jsparse::Parser::Actions {
115
115
  }
116
116
  }
117
117
 
118
+ static lcbtrace_THRESHOLDOPTS service()
119
+ {
120
+ return LCBTRACE_THRESHOLD_SEARCH;
121
+ }
122
+
123
+ static const std::string &operation_name()
124
+ {
125
+ static std::string name = LCBTRACE_OP_SEARCH;
126
+ return name;
127
+ }
128
+
129
+ lcbtrace_SPAN *parent_span() const
130
+ {
131
+ return parent_span_;
132
+ }
133
+
134
+ const std::string &client_context_id() const
135
+ {
136
+ return client_context_id_;
137
+ }
138
+
139
+ int retries() const
140
+ {
141
+ return retries_;
142
+ }
143
+
118
144
  private:
119
145
  const lcb_RESPHTTP *http_response_{nullptr};
120
146
  lcb_HTTP_HANDLE *http_request_{nullptr};
@@ -124,9 +150,12 @@ struct lcb_SEARCH_HANDLE_ : lcb::jsparse::Parser::Actions {
124
150
  lcb_INSTANCE *instance_{nullptr};
125
151
  size_t rows_number_{0};
126
152
  lcb_STATUS last_error_{LCB_SUCCESS};
153
+ lcbtrace_SPAN *parent_span_{nullptr};
127
154
  lcbtrace_SPAN *span_{nullptr};
128
155
  std::string index_name_;
129
156
  std::string error_message_;
157
+ std::string client_context_id_{};
158
+ int retries_{0};
130
159
  };
131
160
 
132
161
  #endif // LIBCOUCHBASE_SEARCH_HANDLE_HH
@@ -219,7 +219,6 @@ int iotssl_maybe_error(lcbio_XSSL *xs, int rv)
219
219
  ******************************************************************************/
220
220
  static void log_callback(const SSL *ssl, int where, int ret)
221
221
  {
222
- const char *retstr;
223
222
  int should_log = 0;
224
223
  lcbio_SOCKET *sock = SSL_get_app_data(ssl);
225
224
  /* Ignore low-level SSL stuff */
@@ -238,9 +237,9 @@ static void log_callback(const SSL *ssl, int where, int ret)
238
237
  return;
239
238
  }
240
239
 
241
- retstr = SSL_alert_type_string(ret);
242
- lcb_log(LOGARGS(ssl, LCB_LOG_TRACE), "sock=%p: ST(0x%x). %s. R(0x%x)%s", (void *)sock, where,
243
- SSL_state_string_long(ssl), ret, retstr);
240
+ lcb_log(LOGARGS(ssl, LCB_LOG_TRACE), "<%s:%s> sock=%p: ST(0x%x). %s. R(0x%x) %s (%s)",
241
+ sock->info ? sock->info->ep_remote.host : "", sock->info ? sock->info->ep_remote.port : "", (void *)sock,
242
+ where, SSL_state_string_long(ssl), ret, SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret));
244
243
 
245
244
  if (where == SSL_CB_HANDSHAKE_DONE) {
246
245
  lcb_log(LOGARGS(ssl, LCB_LOG_DEBUG), "sock=%p. Using SSL version %s. Cipher=%s", (void *)sock,
@@ -311,11 +310,11 @@ lcbio_pSSLCTX lcbio_ssl_new(const char *tsfile, const char *cafile, const char *
311
310
  "MD5:RC4-SHA:RC4-MD5:RC4-MD5:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:DES-CBC-MD5:EXP-EDH-RSA-DES-"
312
311
  "CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC2-CBC-MD5:EXP-RC4-MD5:EXP-RC4-MD5";
313
312
 
314
- const char* cipher_list = getenv("LCB_SSL_CIPHER_LIST");
313
+ const char *cipher_list = getenv("LCB_SSL_CIPHER_LIST");
315
314
  #ifdef HAVE_CIPHERSUITES
316
- const char* ciphersuites = getenv("LCB_SSL_CIPHERSUITES");
315
+ const char *ciphersuites = getenv("LCB_SSL_CIPHERSUITES");
317
316
  #endif
318
- const char* minimum_tls = getenv("LCB_SSL_MINIMUM_TLS");
317
+ const char *minimum_tls = getenv("LCB_SSL_MINIMUM_TLS");
319
318
 
320
319
  if (!cipher_list) {
321
320
  cipher_list = default_ssl_cipher_list;
@@ -360,7 +359,7 @@ lcbio_pSSLCTX lcbio_ssl_new(const char *tsfile, const char *cafile, const char *
360
359
  }
361
360
  if (cafile && keyfile) {
362
361
  lcb_log(LOGARGS_S(settings, LCB_LOG_DEBUG), "Authenticate with key \"%s\", cert \"%s\"", keyfile, cafile);
363
- if (!SSL_CTX_use_certificate_file(ret->ctx, cafile, SSL_FILETYPE_PEM)) {
362
+ if (!SSL_CTX_use_certificate_chain_file(ret->ctx, cafile)) {
364
363
  *errp = LCB_ERR_SSL_ERROR;
365
364
  goto GT_ERR;
366
365
  }
@@ -21,6 +21,8 @@
21
21
  #include <sys/timeb.h>
22
22
  #endif
23
23
 
24
+ #include "n1ql/query_handle.hh"
25
+
24
26
  typedef enum { TAGVAL_STRING, TAGVAL_UINT64, TAGVAL_DOUBLE, TAGVAL_BOOL } tag_type;
25
27
  typedef struct tag_value {
26
28
  sllist_node slnode;
@@ -129,7 +131,7 @@ void lcbtrace_span_add_tag_bool(lcbtrace_SPAN *span, const char *name, int value
129
131
  }
130
132
 
131
133
  LCB_INTERNAL_API
132
- void lcbtrace_span_add_system_tags(lcbtrace_SPAN *span, lcb_settings *settings, lcbtrace_THRESHOLDOPTS svc)
134
+ void lcbtrace_span_add_system_tags(lcbtrace_SPAN *span, const lcb_settings *settings, lcbtrace_THRESHOLDOPTS svc)
133
135
  {
134
136
  if (!span) {
135
137
  return;
@@ -138,6 +140,7 @@ void lcbtrace_span_add_system_tags(lcbtrace_SPAN *span, lcb_settings *settings,
138
140
  span->service(svc);
139
141
  }
140
142
  span->add_tag(LCBTRACE_TAG_SYSTEM, 0, "couchbase", 0);
143
+ span->add_tag(LCBTRACE_TAG_TRANSPORT, 0, "IP.TCP", 0);
141
144
  std::string client_string(LCB_CLIENT_ID);
142
145
  if (settings->client_string) {
143
146
  client_string += " ";
@@ -158,15 +161,6 @@ lcbtrace_SPAN *lcbtrace_span_get_parent(lcbtrace_SPAN *span)
158
161
  return span->m_parent;
159
162
  }
160
163
 
161
- LCB_INTERNAL_API
162
- void lcbtrace_span_set_parent(lcbtrace_SPAN *span, lcbtrace_SPAN *parent)
163
- {
164
- if (!span) {
165
- return;
166
- }
167
- span->m_parent = parent;
168
- }
169
-
170
164
  LIBCOUCHBASE_API
171
165
  uint64_t lcbtrace_span_get_start_ts(lcbtrace_SPAN *span)
172
166
  {
@@ -412,6 +406,38 @@ LIBCOUCHBASE_API lcb_STATUS lcbtrace_span_get_is_encode(lcbtrace_SPAN *span, int
412
406
  return LCB_SUCCESS;
413
407
  }
414
408
 
409
+ namespace lcb
410
+ {
411
+ namespace trace
412
+ {
413
+ void finish_kv_span(const mc_PIPELINE *pipeline, const mc_PACKET *request_pkt,
414
+ const lcb::MemcachedResponse *response_pkt)
415
+ {
416
+ lcbtrace_SPAN *dispatch_span = MCREQ_PKT_RDATA(request_pkt)->span;
417
+ if (dispatch_span) {
418
+ if (response_pkt != nullptr) {
419
+ dispatch_span->increment_server(response_pkt->duration());
420
+ }
421
+ auto *server = static_cast<const lcb::Server *>(pipeline);
422
+ dispatch_span->find_outer_or_this()->add_tag(LCBTRACE_TAG_RETRIES, 0, (uint64_t)request_pkt->retries);
423
+ lcbtrace_span_add_tag_str_nocopy(dispatch_span, LCBTRACE_TAG_TRANSPORT, "IP.TCP");
424
+ lcbio_CTX *ctx = server->connctx;
425
+ if (ctx) {
426
+ char local_id[34] = {};
427
+ snprintf(local_id, sizeof(local_id), "%016" PRIx64 "/%016" PRIx64, (uint64_t)server->get_settings()->iid,
428
+ (uint64_t)ctx->sock->id);
429
+ lcbtrace_span_add_tag_str(dispatch_span, LCBTRACE_TAG_LOCAL_ID, local_id);
430
+ lcbtrace_span_add_host_and_port(dispatch_span, ctx->sock->info);
431
+ }
432
+ if (dispatch_span->should_finish()) {
433
+ lcbtrace_span_finish(dispatch_span, LCBTRACE_NOW);
434
+ }
435
+ }
436
+ }
437
+
438
+ } // namespace trace
439
+ } // namespace lcb
440
+
415
441
  using namespace lcb::trace;
416
442
 
417
443
  Span::Span(lcbtrace_TRACER *tracer, const char *opname, uint64_t start, lcbtrace_REF_TYPE ref, lcbtrace_SPAN *other,
@@ -601,6 +627,13 @@ void Span::add_tag(const char *name, int copy_key, const char *value, int copy_v
601
627
  }
602
628
  }
603
629
 
630
+ void Span::add_tag(const char *name, const std::string &value)
631
+ {
632
+ if (name != nullptr && !value.empty()) {
633
+ add_tag(name, 0, value.c_str(), value.size(), 1);
634
+ }
635
+ }
636
+
604
637
  void Span::add_tag(const char *name, int copy_key, const char *value, size_t value_len, int copy_value)
605
638
  {
606
639
  if (nullptr != m_extspan && nullptr != m_tracer) {
@@ -26,6 +26,13 @@
26
26
  #include <queue>
27
27
  #include <map>
28
28
  #include <string>
29
+ #include <memory>
30
+
31
+ LCB_INTERNAL_API
32
+ void lcbtrace_span_add_system_tags(lcbtrace_SPAN *span, const lcb_settings *settings, lcbtrace_THRESHOLDOPTS svc);
33
+ LIBCOUCHBASE_API
34
+ void lcbtrace_span_add_tag_str_nocopy(lcbtrace_SPAN *span, const char *name, const char *value);
35
+ void lcbtrace_span_add_host_and_port(lcbtrace_SPAN *span, lcbio_CONNINFO *info);
29
36
 
30
37
  namespace lcb
31
38
  {
@@ -45,6 +52,7 @@ class Span
45
52
  return m_finish - m_start;
46
53
  }
47
54
 
55
+ void add_tag(const char *name, const std::string &value);
48
56
  void add_tag(const char *name, int copy, const char *value, int copy_value);
49
57
  void add_tag(const char *name, int copy_key, const char *value, size_t value_len, int copy_value);
50
58
  void add_tag(const char *name, int copy, uint64_t value);
@@ -141,7 +149,7 @@ class ThresholdLoggingTracer
141
149
  QueueEntry convert(lcbtrace_SPAN *span);
142
150
 
143
151
  public:
144
- ThresholdLoggingTracer(lcb_INSTANCE *instance);
152
+ explicit ThresholdLoggingTracer(lcb_INSTANCE *instance);
145
153
 
146
154
  lcbtrace_TRACER *wrap();
147
155
  void add_orphan(lcbtrace_SPAN *span);
@@ -156,108 +164,112 @@ class ThresholdLoggingTracer
156
164
  lcb::io::Timer<ThresholdLoggingTracer, &ThresholdLoggingTracer::flush_threshold> m_tflush;
157
165
  };
158
166
 
159
- } // namespace trace
160
- } // namespace lcb
161
-
162
- extern "C" {
163
- #endif /* __cplusplus */
164
- LCB_INTERNAL_API
165
- void lcbtrace_span_add_system_tags(lcbtrace_SPAN *span, lcb_settings *settings, lcbtrace_THRESHOLDOPTS svc);
166
- LCB_INTERNAL_API
167
- void lcbtrace_span_set_parent(lcbtrace_SPAN *span, lcbtrace_SPAN *parent);
168
- LCB_INTERNAL_API
169
- void lcbtrace_span_set_orphaned(lcbtrace_SPAN *span, int val);
170
- LIBCOUCHBASE_API
171
- void lcbtrace_span_add_tag_str_nocopy(lcbtrace_SPAN *span, const char *name, const char *value);
172
-
173
- const char *dur_level_to_string(lcb_DURABILITY_LEVEL dur_level);
174
- void lcbtrace_span_add_host_and_port(lcbtrace_SPAN *span, lcbio_CONNINFO *info);
175
- #ifdef __cplusplus
176
- #define LCBTRACE_ADD_RETRIES(span, retries) \
177
- if (span) { \
178
- span->find_outer_or_this()->add_tag(LCBTRACE_TAG_RETRIES, 0, (uint64_t)retries); \
167
+ template <typename COMMAND>
168
+ lcbtrace_SPAN *start_kv_span(const lcb_settings *settings, const mc_PACKET *packet, std::shared_ptr<COMMAND> cmd)
169
+ {
170
+ if (settings == nullptr || settings->tracer == nullptr) {
171
+ return nullptr;
172
+ }
173
+ lcbtrace_SPAN *span;
174
+ lcbtrace_SPAN *parent_span = cmd->parent_span();
175
+ if (parent_span != nullptr && parent_span->is_outer() && settings->tracer->flags & LCBTRACE_F_THRESHOLD) {
176
+ span = parent_span;
177
+ span->should_finish(false);
178
+ } else {
179
+ lcbtrace_REF ref;
180
+ ref.type = LCBTRACE_REF_CHILD_OF;
181
+ ref.span = parent_span;
182
+ bool is_dispatch = (parent_span != nullptr && parent_span->is_outer());
183
+ span = lcbtrace_span_start((settings)->tracer,
184
+ is_dispatch ? LCBTRACE_OP_DISPATCH_TO_SERVER : cmd->operation_name().c_str(),
185
+ LCBTRACE_NOW, &ref);
186
+ span->should_finish(true);
187
+ span->is_outer(!is_dispatch);
179
188
  }
189
+ span->is_dispatch(true);
190
+ std::string operation_id = std::to_string(packet->opaque);
191
+ lcbtrace_span_add_tag_str(span, LCBTRACE_TAG_OPERATION_ID, operation_id.c_str());
192
+ lcbtrace_span_add_system_tags(span, settings, LCBTRACE_THRESHOLD_KV);
193
+ span->add_tag(LCBTRACE_TAG_SCOPE, cmd->collection().scope());
194
+ span->add_tag(LCBTRACE_TAG_COLLECTION, cmd->collection().collection());
195
+ span->add_tag(LCBTRACE_TAG_OPERATION, cmd->operation_name());
196
+ return span;
197
+ }
180
198
 
181
- // called by lcb_query, etc... The underlying lcb_http call will fill in the dispatch span tags
182
- #define LCBTRACE_HTTP_START(settings, opaque, pspan, operation_name, svc, outspan) \
183
- LCBTRACE_START(settings, opaque, pspan, operation_name, svc, outspan)
199
+ void finish_kv_span(const mc_PIPELINE *pipeline, const mc_PACKET *request_pkt, const MemcachedResponse *response_pkt);
184
200
 
185
- #define LCBTRACE_KV_START(settings, opaque, cmd, operation_name, outspan) \
186
- if (nullptr != (settings)->tracer) { \
187
- lcbtrace_SPAN *pspan = cmd->parent_span(); \
188
- char opid[20] = {}; \
189
- snprintf(opid, sizeof(opid), "%p", reinterpret_cast<void *>(opaque)); \
190
- LCBTRACE_START(settings, opid, pspan, operation_name, LCBTRACE_THRESHOLD_KV, outspan) \
201
+ template <typename COMMAND>
202
+ lcbtrace_SPAN *start_kv_span_with_durability(const lcb_settings *settings, const mc_PACKET *packet,
203
+ std::shared_ptr<COMMAND> cmd)
204
+ {
205
+ lcbtrace_SPAN *span = start_kv_span(settings, packet, cmd);
206
+ if (span != nullptr && cmd->durability_level() != LCB_DURABILITYLEVEL_NONE) {
207
+ span->add_tag(LCBTRACE_TAG_DURABILITY, 0, dur_level_to_string(cmd->durability_level()), 0);
191
208
  }
209
+ return span;
210
+ }
192
211
 
193
- // don't create a span if passed an outer parent, if we are the threshold logger,
194
- // and use its close to determine times, etc...
195
- #define LCBTRACE_START(settings, opaque, pspan, operation_name, svc, outspan) \
196
- if (nullptr != (settings)->tracer) { \
197
- if (nullptr != pspan && pspan->is_outer() && (settings)->tracer->flags & LCBTRACE_F_THRESHOLD) { \
198
- outspan = pspan; \
199
- outspan->should_finish(false); \
200
- } else { \
201
- lcbtrace_REF ref; \
202
- ref.type = LCBTRACE_REF_CHILD_OF; \
203
- ref.span = pspan; \
204
- bool is_dispatch = (pspan && pspan->is_outer()); \
205
- outspan = \
206
- lcbtrace_span_start((settings)->tracer, is_dispatch ? LCBTRACE_OP_DISPATCH_TO_SERVER : operation_name, \
207
- LCBTRACE_NOW, &ref); \
208
- outspan->should_finish(true); \
209
- outspan->is_outer(!is_dispatch); \
210
- } \
211
- outspan->is_dispatch(true); \
212
- if (opaque) { \
213
- lcbtrace_span_add_tag_str(outspan, LCBTRACE_TAG_OPERATION_ID, opaque); \
214
- } \
215
- lcbtrace_span_add_system_tags(outspan, settings, svc); \
216
- } else { \
217
- outspan = nullptr; \
212
+ template <typename COMMAND>
213
+ lcbtrace_SPAN *start_http_span(const lcb_settings *settings, const COMMAND *cmd)
214
+ {
215
+ if (settings == nullptr || settings->tracer == nullptr) {
216
+ return nullptr;
217
+ }
218
+ lcbtrace_SPAN *span;
219
+ lcbtrace_SPAN *parent_span = cmd->parent_span();
220
+ if (parent_span != nullptr && parent_span->is_outer() && settings->tracer->flags & LCBTRACE_F_THRESHOLD) {
221
+ span = parent_span;
222
+ span->should_finish(false);
223
+ } else {
224
+ lcbtrace_REF ref;
225
+ ref.type = LCBTRACE_REF_CHILD_OF;
226
+ ref.span = parent_span;
227
+ bool is_dispatch = (parent_span != nullptr && parent_span->is_outer());
228
+ span = lcbtrace_span_start((settings)->tracer,
229
+ is_dispatch ? LCBTRACE_OP_DISPATCH_TO_SERVER : cmd->operation_name().c_str(),
230
+ LCBTRACE_NOW, &ref);
231
+ span->should_finish(true);
232
+ span->is_outer(!is_dispatch);
218
233
  }
234
+ span->is_dispatch(true);
235
+ lcbtrace_span_add_tag_str(span, LCBTRACE_TAG_OPERATION_ID, cmd->client_context_id().c_str());
236
+ lcbtrace_span_add_system_tags(span, settings, cmd->service());
237
+ span->add_tag(LCBTRACE_TAG_OPERATION, cmd->operation_name());
238
+ return span;
239
+ }
219
240
 
220
- #define LCBTRACE_KVSTORE_START(settings, opaque, cmd, operation_name, outspan) \
221
- LCBTRACE_KV_START(settings, opaque, cmd, operation_name, outspan) \
222
- if ((settings)->tracer) { \
223
- outspan->add_tag(LCBTRACE_TAG_DURABILITY, 0, dur_level_to_string(cmd->durability_level()), 0); \
241
+ template <typename COMMAND>
242
+ lcbtrace_SPAN *start_http_span_with_statement(const lcb_settings *settings, const COMMAND *cmd,
243
+ const std::string &statement)
244
+ {
245
+ lcbtrace_SPAN *span = start_http_span(settings, cmd);
246
+ if (span != nullptr && !statement.empty()) {
247
+ span->add_tag(LCBTRACE_TAG_STATEMENT, statement);
224
248
  }
249
+ return span;
250
+ }
225
251
 
226
- #define LCBTRACE_KV_FINISH(pipeline, request, resp, server_duration) \
227
- do { \
228
- lcbtrace_SPAN *dispatch_span__ = MCREQ_PKT_RDATA(request)->span; \
229
- if (dispatch_span__) { \
230
- dispatch_span__->increment_server(server_duration); \
231
- lcb::Server *server = static_cast<lcb::Server *>(pipeline); \
232
- dispatch_span__->find_outer_or_this()->add_tag(LCBTRACE_TAG_RETRIES, 0, (uint64_t)request->retries); \
233
- lcbtrace_span_add_tag_str_nocopy(dispatch_span__, LCBTRACE_TAG_TRANSPORT, "IP.TCP"); \
234
- lcbio_CTX *ctx = server->connctx; \
235
- if (ctx) { \
236
- char local_id[34] = {}; \
237
- snprintf(local_id, sizeof(local_id), "%016" PRIx64 "/%016" PRIx64, \
238
- (uint64_t)server->get_settings()->iid, (uint64_t)ctx->sock->id); \
239
- lcbtrace_span_add_tag_str(dispatch_span__, LCBTRACE_TAG_LOCAL_ID, local_id); \
240
- lcbtrace_span_add_host_and_port(dispatch_span__, ctx->sock->info); \
241
- } \
242
- if (dispatch_span__->should_finish()) { \
243
- lcbtrace_span_finish(dispatch_span__, LCBTRACE_NOW); \
244
- } \
245
- } \
246
- } while (0)
247
-
248
- #define LCBTRACE_HTTP_FINISH(span) \
249
- if (nullptr != span) { \
250
- lcbtrace_span_add_tag_str_nocopy(span, LCBTRACE_TAG_TRANSPORT, "IP.TCP"); \
251
- if (span->should_finish()) { \
252
- lcbtrace_span_finish(span, LCBTRACE_NOW); \
253
- } \
254
- span = nullptr; \
252
+ template <typename COMMAND>
253
+ void finish_http_span(lcbtrace_SPAN *span, const COMMAND *cmd)
254
+ {
255
+ if (span != nullptr) {
256
+ span->find_outer_or_this()->add_tag(LCBTRACE_TAG_RETRIES, 0, (uint64_t)cmd->retries());
257
+ if (span->should_finish()) {
258
+ lcbtrace_span_finish(span, LCBTRACE_NOW);
259
+ }
255
260
  }
256
261
  }
257
- #else
258
- #define LCBTRACE_KVSTORE_START(settings, opaque, cmd, operation_name, outspan)
259
- #define LCBTRACE_HTTP_START(settings, opaque, pspan, operation_name, svc, outspan)
260
- #define LCBTRACE_KV_FINISH(pipeline, request, server_duration)
261
- #define LCBTRACE_HTTP_FINISH(span)
262
+
263
+ } // namespace trace
264
+ } // namespace lcb
265
+
266
+ extern "C" {
267
+ #endif /* __cplusplus */
268
+ LCB_INTERNAL_API
269
+ void lcbtrace_span_set_orphaned(lcbtrace_SPAN *span, int val);
270
+
271
+ const char *dur_level_to_string(lcb_DURABILITY_LEVEL dur_level);
272
+ #ifdef __cplusplus
273
+ }
262
274
  #endif /* __cplusplus*/
263
275
  #endif /* LCB_TRACING_INTERNAL_H */
@@ -214,3 +214,24 @@ lcb_STATUS lcb::flexible_framing_extras::encode_impersonate_user(const std::stri
214
214
  }
215
215
  return LCB_SUCCESS;
216
216
  }
217
+
218
+ lcb_STATUS lcb::flexible_framing_extras::encode_impersonate_users_extra_privilege(
219
+ const std::string &privilege, std::vector<std::uint8_t> &flexible_framing_extras)
220
+ {
221
+ auto privilege_len = privilege.size();
222
+ if (privilege_len > std::numeric_limits<std::uint8_t>::max() + 0xfU) {
223
+ return LCB_ERR_INVALID_ARGUMENT;
224
+ }
225
+ std::uint8_t frame_id = 0x06;
226
+ if (privilege_len < 15) {
227
+ auto frame_size = static_cast<std::uint8_t>(privilege_len);
228
+ flexible_framing_extras.emplace_back(frame_id << 4U | frame_size);
229
+ } else {
230
+ flexible_framing_extras.emplace_back(frame_id << 4U | 0xfU);
231
+ flexible_framing_extras.emplace_back(privilege_len - 0xfU);
232
+ }
233
+ for (const auto byte : privilege) {
234
+ flexible_framing_extras.emplace_back(byte);
235
+ }
236
+ return LCB_SUCCESS;
237
+ }
@@ -29,6 +29,9 @@ namespace lcb
29
29
  namespace flexible_framing_extras
30
30
  {
31
31
  lcb_STATUS encode_impersonate_user(const std::string &username, std::vector<std::uint8_t> &flexible_framing_extras);
32
+
33
+ lcb_STATUS encode_impersonate_users_extra_privilege(const std::string &privilege,
34
+ std::vector<std::uint8_t> &flexible_framing_extras);
32
35
  } // namespace flexible_framing_extras
33
36
  } // namespace lcb
34
37
 
@@ -80,8 +80,8 @@ void lcb_VIEW_HANDLE_::invoke_last(lcb_STATUS err)
80
80
  if (http_response_ && http_response_->ctx.response_code != 200 && http_response_->ctx.body_len) {
81
81
  // chances that were not able to parse response
82
82
  Json::Value meta;
83
- if (Json::Reader().parse(http_response_->ctx.body, http_response_->ctx.body + http_response_->ctx.body_len,
84
- meta)) {
83
+ if (Json::Reader(Json::Features::strictMode())
84
+ .parse(http_response_->ctx.body, http_response_->ctx.body + http_response_->ctx.body_len, meta)) {
85
85
  const Json::Value &error = meta["error"];
86
86
  if (error.isString()) {
87
87
  first_error_code_ = error.asString();
@@ -101,7 +101,10 @@ void lcb_VIEW_HANDLE_::invoke_last(lcb_STATUS err)
101
101
  resp.ctx.rc = LCB_ERR_VIEW_NOT_FOUND;
102
102
  }
103
103
 
104
- LCBTRACE_HTTP_FINISH(span_);
104
+ if (span_ != nullptr) {
105
+ lcb::trace::finish_http_span(span_, this);
106
+ span_ = nullptr;
107
+ }
105
108
  if (http_request_ != nullptr) {
106
109
  http_request_->span = nullptr;
107
110
  }
@@ -379,11 +382,16 @@ lcb_VIEW_HANDLE_::lcb_VIEW_HANDLE_(lcb_INSTANCE *instance, void *cookie, const l
379
382
  document_queue_->max_pending_response = cmd->max_concurrent_documents();
380
383
  }
381
384
  }
385
+ {
386
+ char buf[32];
387
+ size_t nbuf = snprintf(buf, sizeof(buf), "%016" PRIx64, lcb_next_rand64());
388
+ client_context_id_.assign(buf, nbuf);
389
+ }
382
390
 
383
391
  lcb_aspend_add(&instance_->pendops, LCB_PENDTYPE_COUNTER, nullptr);
384
392
  if (instance->settings->tracer) {
385
- LCBTRACE_HTTP_START(instance_->settings, nullptr, cmd->parent_span(), LCBTRACE_TAG_SERVICE_VIEW,
386
- LCBTRACE_THRESHOLD_VIEW, span_);
393
+ parent_span_ = cmd->parent_span();
394
+ span_ = lcb::trace::start_http_span(instance_->settings, this);
387
395
  }
388
396
  last_error_ = request_http(cmd);
389
397
  }