couchbase 3.2.0 → 3.2.4

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 (175) hide show
  1. package/README.md +24 -18
  2. package/binding.gyp +88 -85
  3. package/deps/lcb/CMakeLists.txt +1 -1
  4. package/deps/lcb/CONTRIBUTING.md +1 -1
  5. package/deps/lcb/README.markdown +2 -2
  6. package/deps/lcb/RELEASE_NOTES.markdown +99 -14
  7. package/deps/lcb/cmake/Modules/GetVersionInfo.cmake +1 -1
  8. package/deps/lcb/contrib/cbsasl/src/scram-sha/scram_utils.cc +22 -26
  9. package/deps/lcb/contrib/lcb-jsoncpp/lcb-jsoncpp.cpp +20 -7
  10. package/deps/lcb/doc/Doxyfile +1 -1
  11. package/deps/lcb/example/CMakeLists.txt +4 -4
  12. package/deps/lcb/example/libuvdirect/main.c +39 -12
  13. package/deps/lcb/example/minimal/durability.cc +149 -0
  14. package/deps/lcb/example/minimal/query.c +11 -9
  15. package/deps/lcb/gyp_config/common/libcouchbase/configuration.h +3 -3
  16. package/deps/lcb/gyp_config/linux/arm64/config.h +243 -0
  17. package/deps/lcb/include/libcouchbase/couchbase.h +80 -5
  18. package/deps/lcb/include/libcouchbase/error.h +2 -0
  19. package/deps/lcb/include/libcouchbase/ixmgmt.h +15 -10
  20. package/deps/lcb/include/libcouchbase/tracing.h +2 -2
  21. package/deps/lcb/include/memcached/protocol_binary.h +21 -0
  22. package/deps/lcb/libcouchbase.gyp +347 -349
  23. package/deps/lcb/packaging/deb/control +1 -1
  24. package/deps/lcb/src/analytics/analytics_handle.cc +13 -5
  25. package/deps/lcb/src/analytics/analytics_handle.hh +29 -0
  26. package/deps/lcb/src/bootstrap.cc +6 -3
  27. package/deps/lcb/src/capi/cmd_analytics.cc +12 -1
  28. package/deps/lcb/src/capi/cmd_analytics.hh +30 -0
  29. package/deps/lcb/src/capi/cmd_counter.hh +23 -0
  30. package/deps/lcb/src/capi/cmd_exists.hh +24 -1
  31. package/deps/lcb/src/capi/cmd_get.hh +22 -0
  32. package/deps/lcb/src/capi/cmd_get_replica.hh +23 -0
  33. package/deps/lcb/src/capi/cmd_http.hh +7 -0
  34. package/deps/lcb/src/capi/cmd_query.cc +11 -1
  35. package/deps/lcb/src/capi/cmd_query.hh +31 -0
  36. package/deps/lcb/src/capi/cmd_remove.hh +23 -0
  37. package/deps/lcb/src/capi/cmd_search.cc +6 -0
  38. package/deps/lcb/src/capi/cmd_search.hh +23 -0
  39. package/deps/lcb/src/capi/cmd_store.hh +33 -21
  40. package/deps/lcb/src/capi/cmd_subdoc.hh +35 -0
  41. package/deps/lcb/src/capi/cmd_touch.hh +23 -0
  42. package/deps/lcb/src/capi/cmd_unlock.hh +23 -0
  43. package/deps/lcb/src/capi/cmd_view.hh +6 -0
  44. package/deps/lcb/src/capi/collection_qualifier.hh +2 -2
  45. package/deps/lcb/src/cntl.cc +45 -11
  46. package/deps/lcb/src/crypto.cc +2 -2
  47. package/deps/lcb/src/dns-srv.cc +5 -3
  48. package/deps/lcb/src/errmap.cc +5 -9
  49. package/deps/lcb/src/errmap.h +7 -3
  50. package/deps/lcb/src/handler.cc +24 -18
  51. package/deps/lcb/src/hostlist.h +2 -2
  52. package/deps/lcb/src/http/http-priv.h +2 -2
  53. package/deps/lcb/src/http/http.cc +5 -2
  54. package/deps/lcb/src/instance.cc +20 -11
  55. package/deps/lcb/src/internal.h +9 -0
  56. package/deps/lcb/src/lcbio/connect.cc +14 -2
  57. package/deps/lcb/src/lcbio/connect.h +2 -2
  58. package/deps/lcb/src/lcbio/ctx.cc +4 -2
  59. package/deps/lcb/src/lcbio/ioutils.cc +9 -10
  60. package/deps/lcb/src/lcbio/manager.cc +1 -1
  61. package/deps/lcb/src/mcserver/mcserver.cc +9 -6
  62. package/deps/lcb/src/mcserver/negotiate.cc +39 -17
  63. package/deps/lcb/src/n1ql/ixmgmt.cc +1 -2
  64. package/deps/lcb/src/n1ql/query_handle.cc +41 -19
  65. package/deps/lcb/src/n1ql/query_handle.hh +28 -1
  66. package/deps/lcb/src/operations/counter.cc +18 -5
  67. package/deps/lcb/src/operations/exists.cc +25 -4
  68. package/deps/lcb/src/operations/get.cc +39 -19
  69. package/deps/lcb/src/operations/get_replica.cc +28 -8
  70. package/deps/lcb/src/operations/observe.cc +1 -1
  71. package/deps/lcb/src/operations/ping.cc +8 -8
  72. package/deps/lcb/src/operations/pktfwd.cc +2 -1
  73. package/deps/lcb/src/operations/remove.cc +39 -22
  74. package/deps/lcb/src/operations/store.cc +18 -5
  75. package/deps/lcb/src/operations/subdoc.cc +18 -6
  76. package/deps/lcb/src/operations/touch.cc +34 -16
  77. package/deps/lcb/src/operations/unlock.cc +24 -5
  78. package/deps/lcb/src/packetutils.h +3 -2
  79. package/deps/lcb/src/retryq.cc +24 -5
  80. package/deps/lcb/src/search/search.cc +1 -0
  81. package/deps/lcb/src/search/search_handle.cc +30 -8
  82. package/deps/lcb/src/search/search_handle.hh +29 -0
  83. package/deps/lcb/src/settings.cc +1 -1
  84. package/deps/lcb/src/ssl/ssl_common.c +6 -7
  85. package/deps/lcb/src/tracing/span.cc +47 -14
  86. package/deps/lcb/src/tracing/tracer.cc +11 -2
  87. package/deps/lcb/src/tracing/tracing-internal.h +105 -93
  88. package/deps/lcb/src/utilities.cc +43 -0
  89. package/deps/lcb/src/utilities.h +53 -0
  90. package/deps/lcb/src/vbucket/vbucket.c +34 -33
  91. package/deps/lcb/src/views/view_handle.cc +13 -5
  92. package/deps/lcb/src/views/view_handle.hh +29 -0
  93. package/deps/lcb/tests/CMakeLists.txt +21 -0
  94. package/deps/lcb/tests/basic/t_ctlcodes.cc +24 -3
  95. package/deps/lcb/tests/basic/t_jsparse.cc +8 -0
  96. package/deps/lcb/tests/basic/t_n1qlstrings.cc +73 -0
  97. package/deps/lcb/tests/iotests/mock-environment.cc +30 -1
  98. package/deps/lcb/tests/iotests/mock-environment.h +49 -0
  99. package/deps/lcb/tests/iotests/mock-unit-test.cc +104 -6
  100. package/deps/lcb/tests/iotests/mock-unit-test.h +34 -0
  101. package/deps/lcb/tests/iotests/t_collections.cc +1 -1
  102. package/deps/lcb/tests/iotests/t_confmon.cc +4 -2
  103. package/deps/lcb/tests/iotests/t_get.cc +109 -7
  104. package/deps/lcb/tests/iotests/t_http.cc +9 -4
  105. package/deps/lcb/tests/iotests/t_lock.cc +18 -0
  106. package/deps/lcb/tests/iotests/t_mutate.cc +157 -63
  107. package/deps/lcb/tests/iotests/t_n1ql.cc +330 -33
  108. package/deps/lcb/tests/iotests/t_views.cc +1 -0
  109. package/deps/lcb/tests/iotests/testutil.cc +168 -0
  110. package/deps/lcb/tests/iotests/testutil.h +116 -0
  111. package/deps/lcb/tests/mocksupport/procutil.c +32 -28
  112. package/deps/lcb/tests/mocksupport/server.c +0 -1
  113. package/deps/lcb/tests/mocksupport/timeout.c +2 -2
  114. package/deps/lcb/tools/cbc.cc +7 -0
  115. package/dist/analyticsindexmanager.js +512 -524
  116. package/dist/binding.d.ts +3 -0
  117. package/dist/bindingutilities.js +4 -0
  118. package/dist/bucket.js +1 -1
  119. package/dist/bucketmanager.d.ts +31 -1
  120. package/dist/bucketmanager.js +194 -186
  121. package/dist/cluster.d.ts +7 -0
  122. package/dist/cluster.js +48 -38
  123. package/dist/collection.js +11 -17
  124. package/dist/collectionmanager.js +181 -197
  125. package/dist/connection.d.ts +3 -1
  126. package/dist/connection.js +27 -16
  127. package/dist/couchbase.d.ts +1 -0
  128. package/dist/couchbase.js +3 -13
  129. package/dist/datastructures.js +239 -310
  130. package/dist/diagnosticsexecutor.js +70 -85
  131. package/dist/errors.d.ts +70 -0
  132. package/dist/errors.js +96 -2
  133. package/dist/eventingfunctionmanager.d.ts +804 -0
  134. package/dist/eventingfunctionmanager.js +993 -0
  135. package/dist/httpexecutor.d.ts +2 -1
  136. package/dist/httpexecutor.js +30 -37
  137. package/dist/queryindexmanager.js +240 -266
  138. package/dist/scope.js +10 -4
  139. package/dist/sdspecs.d.ts +1 -1
  140. package/dist/searchexecutor.js +3 -0
  141. package/dist/searchindexmanager.js +240 -271
  142. package/dist/searchquery.d.ts +17 -0
  143. package/dist/searchquery.js +22 -1
  144. package/dist/searchtypes.d.ts +7 -2
  145. package/dist/searchtypes.js +2 -2
  146. package/dist/usermanager.js +251 -264
  147. package/dist/utilities.d.ts +2 -0
  148. package/dist/utilities.js +7 -2
  149. package/dist/viewexecutor.js +1 -1
  150. package/dist/viewindexmanager.js +131 -150
  151. package/package.json +1 -1
  152. package/src/addondata.cpp +58 -0
  153. package/src/addondata.h +40 -0
  154. package/src/binding.cpp +3 -1
  155. package/src/cas.h +2 -2
  156. package/src/connection.cpp +25 -178
  157. package/src/connection.h +8 -65
  158. package/src/connection_ops.cpp +57 -34
  159. package/src/constants.cpp +3 -0
  160. package/src/instance.cpp +235 -0
  161. package/src/instance.h +102 -0
  162. package/src/{connection_callbacks.cpp → instance_callbacks.cpp} +34 -34
  163. package/src/logger.cpp +11 -1
  164. package/src/logger.h +3 -0
  165. package/src/metrics.cpp +10 -0
  166. package/src/metrics.h +3 -0
  167. package/src/mutationtoken.h +2 -2
  168. package/src/opbuilder.h +13 -15
  169. package/src/respreader.cpp +1 -0
  170. package/src/respreader.h +6 -4
  171. package/src/tracespan.h +11 -11
  172. package/src/tracing.cpp +11 -0
  173. package/src/tracing.h +3 -0
  174. package/src/valueparser.h +5 -0
  175. package/deps/lcb/example/observe/durability.c +0 -110
@@ -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;
@@ -175,12 +195,14 @@ lcb_SEARCH_HANDLE_::lcb_SEARCH_HANDLE_(lcb_INSTANCE *instance, void *cookie, con
175
195
  root["ctl"]["timeout"] = timeout / 1000; /* us -> ms */
176
196
  }
177
197
  lcb_cmdhttp_timeout(htcmd, timeout);
198
+ if (cmd->want_impersonation()) {
199
+ htcmd->set_header("cb-on-behalf-of", cmd->impostor());
200
+ }
178
201
 
179
202
  std::string qbody(Json::FastWriter().write(root));
180
203
  lcb_cmdhttp_body(htcmd, qbody.c_str(), qbody.size());
181
204
 
182
- LCBTRACE_HTTP_START(instance_->settings, nullptr, span_, LCBTRACE_TAG_SERVICE_SEARCH, LCBTRACE_THRESHOLD_SEARCH,
183
- span_);
205
+ span_ = lcb::trace::start_http_span(instance_->settings, this);
184
206
  lcb_cmdhttp_parent_span(htcmd, span_);
185
207
 
186
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
@@ -52,7 +52,7 @@ void lcb_default_settings(lcb_settings *settings)
52
52
  settings->compress_min_size = LCB_DEFAULT_COMPRESS_MIN_SIZE;
53
53
  settings->compress_min_ratio = (float)LCB_DEFAULT_COMPRESS_MIN_RATIO;
54
54
  settings->allocator_factory = rdb_bigalloc_new;
55
- settings->detailed_neterr = 0;
55
+ settings->detailed_neterr = 1;
56
56
  settings->refresh_on_hterr = 1;
57
57
  settings->sched_implicit_flush = 1;
58
58
  settings->fetch_mutation_tokens = 1;
@@ -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) {
@@ -618,7 +651,7 @@ void Span::add_tag(const char *name, int copy_key, const char *value, size_t val
618
651
  val->t = TAGVAL_STRING;
619
652
  val->key.need_free = copy_key;
620
653
  if (copy_key) {
621
- val->key.p = strdup(name);
654
+ val->key.p = lcb_strdup(name);
622
655
  } else {
623
656
  val->key.p = (char *)name;
624
657
  }
@@ -649,7 +682,7 @@ void Span::add_tag(const char *name, int copy, uint64_t value)
649
682
  val->t = TAGVAL_UINT64;
650
683
  val->key.need_free = copy;
651
684
  if (copy) {
652
- val->key.p = strdup(name);
685
+ val->key.p = lcb_strdup(name);
653
686
  } else {
654
687
  val->key.p = (char *)name;
655
688
  }
@@ -667,7 +700,7 @@ void Span::add_tag(const char *name, int copy, double value)
667
700
  val->t = TAGVAL_DOUBLE;
668
701
  val->key.need_free = copy;
669
702
  if (copy) {
670
- val->key.p = strdup(name);
703
+ val->key.p = lcb_strdup(name);
671
704
  } else {
672
705
  val->key.p = (char *)name;
673
706
  }
@@ -685,7 +718,7 @@ void Span::add_tag(const char *name, int copy, bool value)
685
718
  val->t = TAGVAL_BOOL;
686
719
  val->key.need_free = copy;
687
720
  if (copy) {
688
- val->key.p = strdup(name);
721
+ val->key.p = lcb_strdup(name);
689
722
  } else {
690
723
  val->key.p = (char *)name;
691
724
  }
@@ -29,7 +29,16 @@ LIBCOUCHBASE_API lcbtrace_TRACER *lcbtrace_new(lcb_INSTANCE *instance, uint64_t
29
29
  return (new ThresholdLoggingTracer(instance))->wrap();
30
30
  case LCBTRACE_F_EXTERNAL: {
31
31
  lcbtrace_TRACER *retval = new lcbtrace_TRACER;
32
+ retval->version = 0;
32
33
  retval->flags = LCBTRACE_F_EXTERNAL;
34
+ retval->cookie = nullptr;
35
+ retval->destructor = nullptr;
36
+ retval->v.v0.report = nullptr;
37
+ retval->v.v1.start_span = nullptr;
38
+ retval->v.v1.end_span = nullptr;
39
+ retval->v.v1.destroy_span = nullptr;
40
+ retval->v.v1.add_tag_string = nullptr;
41
+ retval->v.v1.add_tag_uint64 = nullptr;
33
42
  return retval;
34
43
  }
35
44
  default:
@@ -86,8 +95,8 @@ void lcb_set_tracer(lcb_INSTANCE *instance, lcbtrace_TRACER *tracer)
86
95
  void lcbtrace_span_add_host_and_port(lcbtrace_SPAN *span, lcbio_CONNINFO *info)
87
96
  {
88
97
  if (span) {
89
- lcbtrace_span_add_tag_str_nocopy(span, LCBTRACE_TAG_LOCAL_ADDRESS, info->ep_local2.host);
90
- lcbtrace_span_add_tag_str_nocopy(span, LCBTRACE_TAG_LOCAL_PORT, info->ep_local2.port);
98
+ lcbtrace_span_add_tag_str_nocopy(span, LCBTRACE_TAG_LOCAL_ADDRESS, info->ep_local.host);
99
+ lcbtrace_span_add_tag_str_nocopy(span, LCBTRACE_TAG_LOCAL_PORT, info->ep_local.port);
91
100
  lcbtrace_span_add_tag_str_nocopy(span, LCBTRACE_TAG_PEER_ADDRESS, info->ep_remote.host);
92
101
  lcbtrace_span_add_tag_str_nocopy(span, LCBTRACE_TAG_PEER_PORT, info->ep_remote.port);
93
102
  }
@@ -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 */
@@ -15,6 +15,12 @@
15
15
  * limitations under the License.
16
16
  */
17
17
 
18
+ #ifndef NOMINMAX
19
+ #define NOMINMAX
20
+ #endif
21
+
22
+ #include <limits>
23
+
18
24
  #include "internal.h"
19
25
 
20
26
  /**
@@ -171,3 +177,40 @@ const char *lcb_get_tmpdir(void)
171
177
  }
172
178
  #endif
173
179
  }
180
+
181
+ LCB_INTERNAL_API
182
+ char *lcb_strdup(const char *str)
183
+ {
184
+ size_t len;
185
+ char *copy;
186
+
187
+ len = strlen(str) + 1;
188
+ copy = static_cast<char *>(malloc(len));
189
+ if (copy == nullptr) {
190
+ return nullptr;
191
+ }
192
+ memcpy(copy, str, len);
193
+
194
+ return copy;
195
+ }
196
+
197
+ lcb_STATUS lcb::flexible_framing_extras::encode_impersonate_user(const std::string &username,
198
+ std::vector<std::uint8_t> &flexible_framing_extras)
199
+ {
200
+ auto username_len = username.size();
201
+ if (username_len > std::numeric_limits<std::uint8_t>::max() + 0xfU) {
202
+ return LCB_ERR_INVALID_ARGUMENT;
203
+ }
204
+ std::uint8_t frame_id = 0x04;
205
+ if (username_len < 15) {
206
+ auto frame_size = static_cast<std::uint8_t>(username_len);
207
+ flexible_framing_extras.emplace_back(frame_id << 4U | frame_size);
208
+ } else {
209
+ flexible_framing_extras.emplace_back(frame_id << 4U | 0xfU);
210
+ flexible_framing_extras.emplace_back(username_len - 0xfU);
211
+ }
212
+ for (const auto byte : username) {
213
+ flexible_framing_extras.emplace_back(byte);
214
+ }
215
+ return LCB_SUCCESS;
216
+ }