couchbase 3.2.3 → 3.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. package/deps/lcb/CMakeLists.txt +1 -1
  2. package/deps/lcb/CONTRIBUTING.md +1 -1
  3. package/deps/lcb/README.markdown +2 -2
  4. package/deps/lcb/RELEASE_NOTES.markdown +72 -17
  5. package/deps/lcb/cmake/Modules/GetVersionInfo.cmake +1 -1
  6. package/deps/lcb/contrib/cbsasl/src/scram-sha/scram_utils.cc +22 -26
  7. package/deps/lcb/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +20 -6
  8. package/deps/lcb/doc/Doxyfile +1 -1
  9. package/deps/lcb/example/minimal/query.c +9 -7
  10. package/deps/lcb/gyp_config/common/libcouchbase/configuration.h +3 -3
  11. package/deps/lcb/include/libcouchbase/couchbase.h +3 -1
  12. package/deps/lcb/include/libcouchbase/error.h +2 -0
  13. package/deps/lcb/include/libcouchbase/ixmgmt.h +15 -10
  14. package/deps/lcb/include/libcouchbase/tracing.h +2 -2
  15. package/deps/lcb/include/memcached/protocol_binary.h +21 -0
  16. package/deps/lcb/libcouchbase.gyp +347 -349
  17. package/deps/lcb/packaging/deb/control +1 -1
  18. package/deps/lcb/src/analytics/analytics_handle.cc +7 -5
  19. package/deps/lcb/src/analytics/analytics_handle.hh +28 -0
  20. package/deps/lcb/src/capi/cmd_counter.hh +6 -0
  21. package/deps/lcb/src/capi/cmd_exists.hh +6 -0
  22. package/deps/lcb/src/capi/cmd_get.hh +5 -0
  23. package/deps/lcb/src/capi/cmd_get_replica.hh +6 -0
  24. package/deps/lcb/src/capi/cmd_remove.hh +6 -0
  25. package/deps/lcb/src/capi/cmd_search.hh +6 -0
  26. package/deps/lcb/src/capi/cmd_store.hh +16 -21
  27. package/deps/lcb/src/capi/cmd_subdoc.hh +18 -0
  28. package/deps/lcb/src/capi/cmd_touch.hh +6 -0
  29. package/deps/lcb/src/capi/cmd_unlock.hh +6 -0
  30. package/deps/lcb/src/capi/cmd_view.hh +6 -0
  31. package/deps/lcb/src/capi/collection_qualifier.hh +2 -2
  32. package/deps/lcb/src/cntl.cc +42 -8
  33. package/deps/lcb/src/dns-srv.cc +5 -3
  34. package/deps/lcb/src/errmap.cc +5 -9
  35. package/deps/lcb/src/errmap.h +7 -3
  36. package/deps/lcb/src/handler.cc +24 -18
  37. package/deps/lcb/src/lcbio/ctx.cc +4 -2
  38. package/deps/lcb/src/mcserver/mcserver.cc +8 -5
  39. package/deps/lcb/src/mcserver/negotiate.cc +39 -17
  40. package/deps/lcb/src/n1ql/ixmgmt.cc +1 -2
  41. package/deps/lcb/src/n1ql/query_handle.cc +27 -16
  42. package/deps/lcb/src/n1ql/query_handle.hh +27 -1
  43. package/deps/lcb/src/operations/counter.cc +1 -1
  44. package/deps/lcb/src/operations/exists.cc +2 -2
  45. package/deps/lcb/src/operations/get.cc +2 -2
  46. package/deps/lcb/src/operations/observe.cc +1 -1
  47. package/deps/lcb/src/operations/remove.cc +1 -1
  48. package/deps/lcb/src/operations/store.cc +1 -1
  49. package/deps/lcb/src/operations/subdoc.cc +1 -2
  50. package/deps/lcb/src/operations/touch.cc +2 -2
  51. package/deps/lcb/src/operations/unlock.cc +2 -2
  52. package/deps/lcb/src/search/search_handle.cc +27 -8
  53. package/deps/lcb/src/search/search_handle.hh +29 -0
  54. package/deps/lcb/src/ssl/ssl_common.c +6 -7
  55. package/deps/lcb/src/tracing/span.cc +43 -10
  56. package/deps/lcb/src/tracing/tracing-internal.h +105 -93
  57. package/deps/lcb/src/views/view_handle.cc +13 -5
  58. package/deps/lcb/src/views/view_handle.hh +29 -0
  59. package/deps/lcb/tests/CMakeLists.txt +21 -0
  60. package/deps/lcb/tests/basic/t_ctlcodes.cc +24 -3
  61. package/deps/lcb/tests/basic/t_jsparse.cc +8 -0
  62. package/deps/lcb/tests/iotests/mock-environment.cc +15 -0
  63. package/deps/lcb/tests/iotests/mock-environment.h +47 -0
  64. package/deps/lcb/tests/iotests/mock-unit-test.cc +96 -5
  65. package/deps/lcb/tests/iotests/mock-unit-test.h +32 -0
  66. package/deps/lcb/tests/iotests/t_collections.cc +1 -1
  67. package/deps/lcb/tests/iotests/t_confmon.cc +4 -2
  68. package/deps/lcb/tests/iotests/t_get.cc +14 -4
  69. package/deps/lcb/tests/iotests/t_n1ql.cc +17 -1
  70. package/deps/lcb/tests/iotests/t_views.cc +1 -0
  71. package/deps/lcb/tests/iotests/testutil.cc +168 -0
  72. package/deps/lcb/tests/iotests/testutil.h +111 -0
  73. package/deps/lcb/tests/mocksupport/procutil.c +32 -28
  74. package/deps/lcb/tests/mocksupport/server.c +0 -1
  75. package/deps/lcb/tools/cbc.cc +7 -0
  76. package/dist/analyticsindexmanager.js +3 -3
  77. package/dist/binding.d.ts +2 -0
  78. package/dist/bindingutilities.js +4 -0
  79. package/dist/bucketmanager.d.ts +31 -1
  80. package/dist/bucketmanager.js +28 -2
  81. package/dist/collection.js +2 -2
  82. package/dist/collectionmanager.js +2 -2
  83. package/dist/connection.js +3 -0
  84. package/dist/errors.d.ts +18 -0
  85. package/dist/errors.js +26 -2
  86. package/dist/eventingfunctionmanager.js +6 -6
  87. package/dist/queryindexmanager.js +3 -3
  88. package/dist/searchexecutor.js +3 -0
  89. package/dist/searchindexmanager.js +1 -1
  90. package/dist/searchquery.d.ts +17 -0
  91. package/dist/searchquery.js +22 -1
  92. package/dist/searchtypes.d.ts +7 -2
  93. package/dist/searchtypes.js +2 -2
  94. package/dist/usermanager.js +1 -1
  95. package/dist/viewindexmanager.js +1 -1
  96. package/package.json +1 -1
  97. package/src/connection.cpp +2 -0
  98. package/src/constants.cpp +2 -0
  99. package/src/instance.cpp +8 -1
  100. package/src/instance.h +1 -0
@@ -185,6 +185,7 @@ class lcb::SessionRequestImpl : public SessionRequest
185
185
  SessionInfo *info;
186
186
  lcb_settings *settings;
187
187
  lcb_host_t host_{};
188
+ bool expecting_error_map{false};
188
189
  };
189
190
 
190
191
  static void handle_read(lcbio_CTX *ioctx, unsigned)
@@ -316,8 +317,9 @@ SessionRequestImpl::MechStatus SessionRequestImpl::set_chosen_mech(std::string &
316
317
  "PLAIN, but using SCRAM methods is strongly recommended over non-encrypted transports.",
317
318
  LOGID(this));
318
319
  #else
319
- lcb_log(LOGARGS(this, WARN), LOGFMT "SASL PLAIN authentication is not allowed on non-TLS connections",
320
- LOGID(this));
320
+ lcb_log(LOGARGS(this, WARN),
321
+ LOGFMT "SASL PLAIN authentication is not allowed on non-TLS connections (server supports: %s)",
322
+ LOGID(this), mechlist.c_str());
321
323
  return MECH_UNAVAILABLE;
322
324
  #endif
323
325
  }
@@ -642,15 +644,15 @@ GT_NEXT_PACKET:
642
644
  }
643
645
 
644
646
  if (settings->keypath) {
645
- completed = !maybe_select_bucket();
647
+ completed = !expecting_error_map && !maybe_select_bucket();
646
648
  }
647
649
  break;
648
650
  }
649
651
 
650
652
  case PROTOCOL_BINARY_CMD_GET_ERROR_MAP: {
653
+ expecting_error_map = false;
651
654
  if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
652
- if (!update_errmap(resp)) {
653
- }
655
+ update_errmap(resp);
654
656
  } else if (isUnsupported(status)) {
655
657
  lcb_log(LOGARGS(this, DEBUG), LOGFMT "Server does not support GET_ERRMAP (0x%x)", LOGID(this), status);
656
658
  } else {
@@ -664,18 +666,37 @@ GT_NEXT_PACKET:
664
666
  }
665
667
 
666
668
  case PROTOCOL_BINARY_CMD_SELECT_BUCKET: {
667
- if (status == PROTOCOL_BINARY_RESPONSE_SUCCESS) {
668
- completed = true;
669
- info->selected = true;
670
- } else if (status == PROTOCOL_BINARY_RESPONSE_EACCESS) {
671
- set_error(LCB_ERR_BUCKET_NOT_FOUND,
672
- "Provided credentials not allowed for bucket or bucket does not exist", &resp);
673
- } else if (status == PROTOCOL_BINARY_RESPONSE_KEY_ENOENT) {
674
- set_error(LCB_ERR_BUCKET_NOT_FOUND, "Key/Value service is not configured for given node", &resp);
675
- } else {
676
- lcb_log(LOGARGS(this, ERROR), LOGFMT "Unexpected status 0x%x received for SELECT_BUCKET", LOGID(this),
677
- status);
678
- set_error(LCB_ERR_PROTOCOL_ERROR, "Other auth error", &resp);
669
+ switch (status) {
670
+ case PROTOCOL_BINARY_RESPONSE_SUCCESS:
671
+ completed = true;
672
+ info->selected = true;
673
+ break;
674
+
675
+ case PROTOCOL_BINARY_RESPONSE_EACCESS:
676
+ set_error(LCB_ERR_BUCKET_NOT_FOUND,
677
+ "Provided credentials not allowed for bucket or bucket does not exist", &resp);
678
+ break;
679
+
680
+ case PROTOCOL_BINARY_RESPONSE_KEY_ENOENT:
681
+ set_error(LCB_ERR_BUCKET_NOT_FOUND, "Key/Value service is not configured for given node", &resp);
682
+ break;
683
+
684
+ case PROTOCOL_BINARY_RATE_LIMITED_MAX_COMMANDS:
685
+ case PROTOCOL_BINARY_RATE_LIMITED_MAX_CONNECTIONS:
686
+ case PROTOCOL_BINARY_RATE_LIMITED_NETWORK_EGRESS:
687
+ case PROTOCOL_BINARY_RATE_LIMITED_NETWORK_INGRESS:
688
+ set_error(LCB_ERR_RATE_LIMITED, "The tenant has reached rate limit", &resp);
689
+ break;
690
+
691
+ case PROTOCOL_BINARY_SCOPE_SIZE_LIMIT_EXCEEDED:
692
+ set_error(LCB_ERR_QUOTA_LIMITED, "The tenant has reached quota limit", &resp);
693
+ break;
694
+
695
+ default:
696
+ lcb_log(LOGARGS(this, ERROR), LOGFMT "Unexpected status 0x%x received for SELECT_BUCKET",
697
+ LOGID(this), status);
698
+ set_error(LCB_ERR_PROTOCOL_ERROR, "Other auth error", &resp);
699
+ break;
679
700
  }
680
701
  break;
681
702
  }
@@ -744,6 +765,7 @@ void SessionRequestImpl::start(lcbio_SOCKET *sock)
744
765
  send_hello();
745
766
  if (settings->use_errmap) {
746
767
  request_errmap();
768
+ expecting_error_map = true;
747
769
  } else {
748
770
  lcb_log(LOGARGS(this, TRACE), LOGFMT "GET_ERRORMAP disabled", LOGID(this));
749
771
  }
@@ -201,8 +201,7 @@ lcb_STATUS dispatch_common(lcb_INSTANCE *instance, const void *cookie, lcb_N1XMG
201
201
  Json::Value root;
202
202
  root["statement"] = ss;
203
203
  string reqbuf = Json::FastWriter().write(root);
204
- return dispatch_common<T>(instance, cookie, u_callback, i_callback, reqbuf.c_str(), reqbuf.size() - 1 /*newline*/,
205
- obj);
204
+ return dispatch_common<T>(instance, cookie, u_callback, i_callback, reqbuf.c_str(), reqbuf.size(), obj);
206
205
  }
207
206
 
208
207
  // Class to back the storage for the actual lcb_IXSPEC without doing too much
@@ -99,7 +99,7 @@ bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &
99
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"];
@@ -143,13 +143,15 @@ bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &
143
143
  rc = LCB_ERR_INTERNAL_SERVER_FAILURE;
144
144
  if (!first_error_message.empty()) {
145
145
  std::regex already_exists("Index.+already exists"); /* NOTE: case sensitive */
146
+ std::regex not_found("index.+not found");
146
147
  if (std::regex_search(first_error_message, already_exists)) {
147
148
  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
- }
149
+ } else if (std::regex_search(first_error_message, not_found)) {
150
+ rc = LCB_ERR_INDEX_NOT_FOUND;
151
+ } else if (first_error_message.find(
152
+ "Limit for number of indexes that can be created per scope has been reached") !=
153
+ std::string::npos) {
154
+ rc = LCB_ERR_QUOTA_LIMITED;
153
155
  }
154
156
  }
155
157
  break;
@@ -166,6 +168,14 @@ bool lcb_QUERY_HANDLE_::parse_meta(const char *row, size_t row_len, lcb_STATUS &
166
168
  case 13014:
167
169
  rc = LCB_ERR_AUTHENTICATION_FAILURE;
168
170
  break;
171
+
172
+ case 1191:
173
+ case 1192:
174
+ case 1193:
175
+ case 1194:
176
+ rc = LCB_ERR_RATE_LIMITED;
177
+ break;
178
+
169
179
  default:
170
180
  if (first_error_code >= 4000 && first_error_code < 5000) {
171
181
  rc = LCB_ERR_PLANNING_FAILURE;
@@ -195,8 +205,8 @@ void lcb_QUERY_HANDLE_::invoke_row(lcb_RESPQUERY *resp, bool is_last)
195
205
  resp->ctx.endpoint = resp->htresp->ctx.endpoint;
196
206
  resp->ctx.endpoint_len = resp->htresp->ctx.endpoint_len;
197
207
  }
198
- resp->ctx.client_context_id = client_context_id.c_str();
199
- resp->ctx.client_context_id_len = client_context_id.size();
208
+ resp->ctx.client_context_id = client_context_id_.c_str();
209
+ resp->ctx.client_context_id_len = client_context_id_.size();
200
210
  resp->ctx.statement = statement_.c_str();
201
211
  resp->ctx.statement_len = statement_.size();
202
212
 
@@ -213,9 +223,11 @@ void lcb_QUERY_HANDLE_::invoke_row(lcb_RESPQUERY *resp, bool is_last)
213
223
  resp->ctx.first_error_message_len = first_error_message.size();
214
224
  }
215
225
  resp->ctx.first_error_code = first_error_code;
216
- LCBTRACE_ADD_RETRIES(span_, retries_);
226
+ if (span_ != nullptr) {
227
+ lcb::trace::finish_http_span(span_, this);
228
+ span_ = nullptr;
229
+ }
217
230
 
218
- LCBTRACE_HTTP_FINISH(span_);
219
231
  if (http_request_ != nullptr) {
220
232
  http_request_->span = nullptr;
221
233
  }
@@ -426,7 +438,7 @@ lcb_STATUS lcb_QUERY_HANDLE_::issue_htreq(const std::string &body)
426
438
  lcb_log(LOGARGS(this, TRACE),
427
439
  LOGFMT "execute query: %.*s, idempotent=%s, timeout=%uus, grace_period=%uus, client_context_id=\"%s\"",
428
440
  LOGID(this), (int)body.size(), body.c_str(), idempotent_ ? "true" : "false", timeout,
429
- LCBT_SETTING(instance_, n1ql_grace_period), client_context_id.c_str());
441
+ LCBT_SETTING(instance_, n1ql_grace_period), client_context_id_.c_str());
430
442
  return rc;
431
443
  }
432
444
 
@@ -517,10 +529,10 @@ lcb_QUERY_HANDLE_::lcb_QUERY_HANDLE_(lcb_INSTANCE *obj, void *user_cookie, const
517
529
  if (ccid.isNull()) {
518
530
  char buf[32];
519
531
  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;
532
+ client_context_id_.assign(buf, nbuf);
533
+ json["client_context_id"] = client_context_id_;
522
534
  } else {
523
- client_context_id = ccid.asString();
535
+ client_context_id_ = ccid.asString();
524
536
  }
525
537
  if (json.isMember("readonly") && json["readonly"].asBool()) {
526
538
  idempotent_ = true;
@@ -554,8 +566,7 @@ lcb_QUERY_HANDLE_::lcb_QUERY_HANDLE_(lcb_INSTANCE *obj, void *user_cookie, const
554
566
  }
555
567
  if (instance_->settings->tracer) {
556
568
  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_);
569
+ span_ = lcb::trace::start_http_span_with_statement(instance_->settings, this, statement_);
559
570
  }
560
571
  }
561
572
 
@@ -246,6 +246,32 @@ struct lcb_QUERY_HANDLE_ : lcb::jsparse::Parser::Actions {
246
246
  return LCB_SUCCESS;
247
247
  }
248
248
 
249
+ static lcbtrace_THRESHOLDOPTS service()
250
+ {
251
+ return LCBTRACE_THRESHOLD_QUERY;
252
+ }
253
+
254
+ static const std::string &operation_name()
255
+ {
256
+ static std::string name = LCBTRACE_OP_QUERY;
257
+ return name;
258
+ }
259
+
260
+ lcbtrace_SPAN *parent_span() const
261
+ {
262
+ return parent_span_;
263
+ }
264
+
265
+ const std::string &client_context_id() const
266
+ {
267
+ return client_context_id_;
268
+ }
269
+
270
+ int retries() const
271
+ {
272
+ return retries_;
273
+ }
274
+
249
275
  private:
250
276
  void on_backoff();
251
277
 
@@ -269,7 +295,7 @@ struct lcb_QUERY_HANDLE_ : lcb::jsparse::Parser::Actions {
269
295
  Json::Value json;
270
296
  /** String of the original statement. Cached here to avoid jsoncpp lookups */
271
297
  std::string statement_;
272
- std::string client_context_id;
298
+ std::string client_context_id_;
273
299
  std::string first_error_message{};
274
300
  uint32_t first_error_code{};
275
301
 
@@ -237,7 +237,7 @@ static lcb_STATUS counter_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_C
237
237
  }
238
238
  memcpy(SPAN_BUFFER(&packet->kh_span) + offset, &expiry, sizeof(expiry));
239
239
 
240
- LCBTRACE_KV_START(instance->settings, packet->opaque, cmd, LCBTRACE_OP_COUNTER, rdata->span);
240
+ rdata->span = lcb::trace::start_kv_span(instance->settings, packet, cmd);
241
241
  TRACE_ARITHMETIC_BEGIN(instance, &hdr, cmd);
242
242
  LCB_SCHED_ADD(instance, pipeline, packet);
243
243
  return LCB_SUCCESS;
@@ -153,7 +153,7 @@ static lcb_STATUS exists_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
153
153
 
154
154
  hdr.request.opcode = PROTOCOL_BINARY_CMD_GET_META;
155
155
  hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
156
- hdr.request.bodylen = htonl(ntohs(hdr.request.keylen));
156
+ hdr.request.bodylen = ntohl(mcreq_get_key_size(&hdr));
157
157
  hdr.request.opaque = pkt->opaque;
158
158
  hdr.request.cas = 0;
159
159
 
@@ -168,7 +168,7 @@ static lcb_STATUS exists_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
168
168
  memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, framing_extras.data(), framing_extras.size());
169
169
  }
170
170
 
171
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd, LCBTRACE_OP_EXISTS, pkt->u_rdata.reqdata.span);
171
+ pkt->u_rdata.reqdata.span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
172
172
  LCB_SCHED_ADD(instance, pipeline, pkt)
173
173
  TRACE_EXISTS_BEGIN(instance, &hdr, cmd);
174
174
  return LCB_SUCCESS;
@@ -187,7 +187,7 @@ static lcb_STATUS get_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMDGE
187
187
 
188
188
  hdr.request.opcode = opcode;
189
189
  hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
190
- hdr.request.bodylen = htonl(extlen + ffextlen + ntohs(hdr.request.keylen));
190
+ hdr.request.bodylen = htonl(extlen + ffextlen + mcreq_get_key_size(&hdr));
191
191
  hdr.request.opaque = pkt->opaque;
192
192
  hdr.request.cas = 0;
193
193
 
@@ -209,7 +209,7 @@ static lcb_STATUS get_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMDGE
209
209
  memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, &expiry, sizeof(expiry));
210
210
  }
211
211
 
212
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd, LCBTRACE_OP_GET, rdata->span);
212
+ rdata->span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
213
213
  LCB_SCHED_ADD(instance, pl, pkt)
214
214
  TRACE_GET_BEGIN(instance, &hdr, cmd);
215
215
  return LCB_SUCCESS;
@@ -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
  }
@@ -188,7 +188,7 @@ static lcb_STATUS remove_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
188
188
  if (!framing_extras.empty()) {
189
189
  memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, framing_extras.data(), framing_extras.size());
190
190
  }
191
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd, LCBTRACE_OP_REMOVE, pkt->u_rdata.reqdata.span);
191
+ pkt->u_rdata.reqdata.span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
192
192
  TRACE_REMOVE_BEGIN(instance, &hdr, cmd);
193
193
  LCB_SCHED_ADD(instance, pl, pkt)
194
194
  return LCB_SUCCESS;
@@ -485,7 +485,7 @@ static lcb_STATUS store_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
485
485
  if (cmd->is_replace_semantics()) {
486
486
  packet->flags |= MCREQ_F_REPLACE_SEMANTICS;
487
487
  }
488
- LCBTRACE_KVSTORE_START(instance->settings, packet->opaque, cmd, cmd->operation_name(), rdata->span);
488
+ rdata->span = lcb::trace::start_kv_span_with_durability(instance->settings, packet, cmd);
489
489
  LCB_SCHED_ADD(instance, pipeline, packet)
490
490
 
491
491
  TRACE_STORE_BEGIN(instance, &hdr, cmd);
@@ -853,8 +853,7 @@ static lcb_STATUS subdoc_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
853
853
  MCREQ_PKT_RDATA(pkt)->start +
854
854
  cmd->timeout_or_default_in_nanoseconds(LCB_US2NS(LCBT_SETTING(instance, operation_timeout)));
855
855
  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);
856
+ MCREQ_PKT_RDATA(pkt)->span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
858
857
  LCB_SCHED_ADD(instance, pl, pkt)
859
858
  return LCB_SUCCESS;
860
859
  }
@@ -158,7 +158,7 @@ static lcb_STATUS touch_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
158
158
  hdr.request.cas = 0;
159
159
  hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
160
160
  hdr.request.opaque = pkt->opaque;
161
- hdr.request.bodylen = htonl(hdr.request.extlen + ffextlen + ntohs(hdr.request.keylen));
161
+ hdr.request.bodylen = htonl(hdr.request.extlen + ffextlen + mcreq_get_key_size(&hdr));
162
162
 
163
163
  memcpy(SPAN_BUFFER(&pkt->kh_span), &hdr, sizeof(hdr));
164
164
  std::size_t offset = sizeof(hdr);
@@ -174,7 +174,7 @@ static lcb_STATUS touch_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CMD
174
174
  pkt->u_rdata.reqdata.deadline =
175
175
  pkt->u_rdata.reqdata.start +
176
176
  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);
177
+ pkt->u_rdata.reqdata.span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
178
178
  LCB_SCHED_ADD(instance, pl, pkt);
179
179
  TRACE_TOUCH_BEGIN(instance, &hdr, cmd);
180
180
  return LCB_SUCCESS;
@@ -157,7 +157,7 @@ static lcb_STATUS unlock_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
157
157
 
158
158
  hdr.request.opcode = PROTOCOL_BINARY_CMD_UNLOCK_KEY;
159
159
  hdr.request.datatype = PROTOCOL_BINARY_RAW_BYTES;
160
- hdr.request.bodylen = htonl((lcb_uint32_t)ntohs(hdr.request.keylen));
160
+ hdr.request.bodylen = htonl(mcreq_get_key_size(&hdr));
161
161
  hdr.request.opaque = pkt->opaque;
162
162
  hdr.request.cas = lcb_htonll(cmd->cas());
163
163
 
@@ -166,7 +166,7 @@ static lcb_STATUS unlock_schedule(lcb_INSTANCE *instance, std::shared_ptr<lcb_CM
166
166
  if (!framing_extras.empty()) {
167
167
  memcpy(SPAN_BUFFER(&pkt->kh_span) + offset, framing_extras.data(), framing_extras.size());
168
168
  }
169
- LCBTRACE_KV_START(instance->settings, pkt->opaque, cmd, LCBTRACE_OP_UNLOCK, rd->span);
169
+ rd->span = lcb::trace::start_kv_span(instance->settings, pkt, cmd);
170
170
  LCB_SCHED_ADD(instance, pl, pkt);
171
171
  TRACE_UNLOCK_BEGIN(instance, &hdr, cmd);
172
172
  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,19 @@ 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("CreateIndex, Prepare failed, err: num_fts_indexes") !=
101
+ std::string::npos) {
102
+ resp->ctx.rc = LCB_ERR_QUOTA_LIMITED;
103
+ }
104
+ } else if (resp->ctx.http_response_code == 429) {
105
+ std::regex rate_limiting_message(
106
+ "num_concurrent_requests|num_queries_per_min|ingress_mib_per_min|egress_mib_per_min");
107
+ if (std::regex_search(error_message_, rate_limiting_message)) {
108
+ resp->ctx.rc = LCB_ERR_RATE_LIMITED;
109
+ }
98
110
  }
99
111
  }
100
112
  }
@@ -116,7 +128,10 @@ void lcb_SEARCH_HANDLE_::invoke_last()
116
128
  resp.nrow = meta.iov_len;
117
129
  }
118
130
 
119
- LCBTRACE_HTTP_FINISH(span_);
131
+ if (span_ != nullptr) {
132
+ lcb::trace::finish_http_span(span_, this);
133
+ span_ = nullptr;
134
+ }
120
135
  if (http_request_ != nullptr) {
121
136
  http_request_->span = nullptr;
122
137
  }
@@ -154,8 +169,13 @@ lcb_SEARCH_HANDLE_::lcb_SEARCH_HANDLE_(lcb_INSTANCE *instance, void *cookie, con
154
169
  return;
155
170
  }
156
171
  index_name_ = j_ixname.asString();
172
+ {
173
+ char buf[32];
174
+ size_t nbuf = snprintf(buf, sizeof(buf), "%016" PRIx64, lcb_next_rand64());
175
+ client_context_id_.assign(buf, nbuf);
176
+ }
157
177
  if (instance_->settings->tracer) {
158
- span_ = cmd->parent_span();
178
+ parent_span_ = cmd->parent_span();
159
179
  }
160
180
 
161
181
  std::string url;
@@ -182,8 +202,7 @@ lcb_SEARCH_HANDLE_::lcb_SEARCH_HANDLE_(lcb_INSTANCE *instance, void *cookie, con
182
202
  std::string qbody(Json::FastWriter().write(root));
183
203
  lcb_cmdhttp_body(htcmd, qbody.c_str(), qbody.size());
184
204
 
185
- LCBTRACE_HTTP_START(instance_->settings, nullptr, span_, LCBTRACE_TAG_SERVICE_SEARCH, LCBTRACE_THRESHOLD_SEARCH,
186
- span_);
205
+ span_ = lcb::trace::start_http_span(instance_->settings, this);
187
206
  lcb_cmdhttp_parent_span(htcmd, span_);
188
207
 
189
208
  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;
@@ -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) {