couchbase 4.4.6 → 4.5.1

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 (143) hide show
  1. package/deps/couchbase-cxx-cache/mozilla-ca-bundle.crt +79 -165
  2. package/deps/couchbase-cxx-cache/mozilla-ca-bundle.sha256 +1 -1
  3. package/deps/couchbase-cxx-client/CMakeLists.txt +14 -3
  4. package/deps/couchbase-cxx-client/README.md +2 -2
  5. package/deps/couchbase-cxx-client/cmake/Profiler.cmake +15 -0
  6. package/deps/couchbase-cxx-client/core/app_telemetry_address.cxx +55 -0
  7. package/deps/couchbase-cxx-client/core/app_telemetry_address.hxx +39 -0
  8. package/deps/couchbase-cxx-client/core/app_telemetry_meter.cxx +791 -0
  9. package/deps/couchbase-cxx-client/core/app_telemetry_meter.hxx +200 -0
  10. package/deps/couchbase-cxx-client/core/app_telemetry_reporter.cxx +895 -0
  11. package/deps/couchbase-cxx-client/core/app_telemetry_reporter.hxx +59 -0
  12. package/deps/couchbase-cxx-client/core/bucket.cxx +77 -35
  13. package/deps/couchbase-cxx-client/core/bucket.hxx +17 -10
  14. package/deps/couchbase-cxx-client/core/cluster.cxx +56 -17
  15. package/deps/couchbase-cxx-client/core/cluster_credentials.cxx +27 -0
  16. package/deps/couchbase-cxx-client/core/cluster_credentials.hxx +36 -0
  17. package/deps/couchbase-cxx-client/core/cluster_options.hxx +13 -0
  18. package/deps/couchbase-cxx-client/core/collections_component.cxx +7 -5
  19. package/deps/couchbase-cxx-client/core/http_component.cxx +6 -0
  20. package/deps/couchbase-cxx-client/core/impl/bucket_manager.cxx +2 -0
  21. package/deps/couchbase-cxx-client/core/impl/cluster.cxx +10 -0
  22. package/deps/couchbase-cxx-client/core/impl/collection.cxx +2 -0
  23. package/deps/couchbase-cxx-client/core/impl/error.cxx +22 -6
  24. package/deps/couchbase-cxx-client/core/impl/error.hxx +1 -1
  25. package/deps/couchbase-cxx-client/core/impl/logger.cxx +51 -0
  26. package/deps/couchbase-cxx-client/core/impl/replica_utils.cxx +1 -1
  27. package/deps/couchbase-cxx-client/core/impl/transaction_get_multi_replicas_from_preferred_server_group_spec.cxx +32 -0
  28. package/deps/couchbase-cxx-client/core/impl/transaction_get_multi_spec.cxx +30 -0
  29. package/deps/couchbase-cxx-client/core/impl/transaction_op_error_category.cxx +2 -0
  30. package/deps/couchbase-cxx-client/core/io/config_tracker.cxx +6 -6
  31. package/deps/couchbase-cxx-client/core/io/http_command.hxx +35 -11
  32. package/deps/couchbase-cxx-client/core/io/http_session.cxx +10 -0
  33. package/deps/couchbase-cxx-client/core/io/http_session.hxx +4 -0
  34. package/deps/couchbase-cxx-client/core/io/http_session_manager.hxx +87 -35
  35. package/deps/couchbase-cxx-client/core/io/mcbp_command.hxx +41 -2
  36. package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +52 -19
  37. package/deps/couchbase-cxx-client/core/io/mcbp_session.hxx +3 -0
  38. package/deps/couchbase-cxx-client/core/logger/logger.cxx +46 -0
  39. package/deps/couchbase-cxx-client/core/logger/logger.hxx +41 -1
  40. package/deps/couchbase-cxx-client/core/management/bucket_settings.hxx +1 -0
  41. package/deps/couchbase-cxx-client/core/management/bucket_settings_json.hxx +4 -0
  42. package/deps/couchbase-cxx-client/core/meta/features.hxx +32 -0
  43. package/deps/couchbase-cxx-client/core/operations/document_analytics.cxx +9 -9
  44. package/deps/couchbase-cxx-client/core/operations/document_get_all_replicas.hxx +10 -2
  45. package/deps/couchbase-cxx-client/core/operations/document_lookup_in.cxx +4 -0
  46. package/deps/couchbase-cxx-client/core/operations/document_lookup_in_all_replicas.hxx +14 -2
  47. package/deps/couchbase-cxx-client/core/operations/document_lookup_in_any_replica.hxx +4 -0
  48. package/deps/couchbase-cxx-client/core/operations/document_mutate_in.cxx +4 -0
  49. package/deps/couchbase-cxx-client/core/operations/document_mutate_in.hxx +1 -0
  50. package/deps/couchbase-cxx-client/core/operations/document_query.cxx +12 -10
  51. package/deps/couchbase-cxx-client/core/operations/http_noop.cxx +1 -0
  52. package/deps/couchbase-cxx-client/core/operations/management/bucket_create.cxx +3 -0
  53. package/deps/couchbase-cxx-client/core/operations/management/bucket_update.cxx +3 -0
  54. package/deps/couchbase-cxx-client/core/operations/management/search_index_get_all.cxx +3 -2
  55. package/deps/couchbase-cxx-client/core/origin.cxx +25 -5
  56. package/deps/couchbase-cxx-client/core/origin.hxx +18 -24
  57. package/deps/couchbase-cxx-client/core/platform/random.cc +6 -3
  58. package/deps/couchbase-cxx-client/core/platform/random.h +2 -2
  59. package/deps/couchbase-cxx-client/core/protocol/cmd_mutate_in.hxx +9 -0
  60. package/deps/couchbase-cxx-client/core/timeout_defaults.hxx +4 -0
  61. package/deps/couchbase-cxx-client/core/topology/configuration.cxx +10 -13
  62. package/deps/couchbase-cxx-client/core/topology/configuration.hxx +14 -15
  63. package/deps/couchbase-cxx-client/core/topology/configuration_json.hxx +6 -0
  64. package/deps/couchbase-cxx-client/core/transactions/async_attempt_context.hxx +22 -2
  65. package/deps/couchbase-cxx-client/core/transactions/attempt_context.hxx +25 -7
  66. package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.cxx +723 -245
  67. package/deps/couchbase-cxx-client/core/transactions/attempt_context_impl.hxx +91 -12
  68. package/deps/couchbase-cxx-client/core/transactions/exceptions.cxx +5 -0
  69. package/deps/couchbase-cxx-client/core/transactions/exceptions.hxx +20 -0
  70. package/deps/couchbase-cxx-client/core/transactions/exceptions_fmt.hxx +3 -0
  71. package/deps/couchbase-cxx-client/core/transactions/forward_compat.cxx +71 -6
  72. package/deps/couchbase-cxx-client/core/transactions/forward_compat.hxx +45 -59
  73. package/deps/couchbase-cxx-client/core/transactions/get_multi_orchestrator.cxx +616 -0
  74. package/deps/couchbase-cxx-client/core/transactions/get_multi_orchestrator.hxx +61 -0
  75. package/deps/couchbase-cxx-client/core/transactions/internal/doc_record.cxx +8 -0
  76. package/deps/couchbase-cxx-client/core/transactions/internal/doc_record.hxx +16 -5
  77. package/deps/couchbase-cxx-client/core/transactions/internal/exceptions_internal.hxx +12 -0
  78. package/deps/couchbase-cxx-client/core/transactions/internal/transaction_context.hxx +13 -0
  79. package/deps/couchbase-cxx-client/core/transactions/internal/transaction_fields.hxx +1 -0
  80. package/deps/couchbase-cxx-client/core/transactions/staged_mutation.cxx +277 -96
  81. package/deps/couchbase-cxx-client/core/transactions/staged_mutation.hxx +28 -76
  82. package/deps/couchbase-cxx-client/core/transactions/transaction_context.cxx +33 -0
  83. package/deps/couchbase-cxx-client/core/transactions/transaction_get_multi_mode.hxx +28 -0
  84. package/deps/couchbase-cxx-client/core/transactions/transaction_get_multi_replicas_from_preferred_server_group_mode.hxx +27 -0
  85. package/deps/couchbase-cxx-client/core/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +72 -0
  86. package/deps/couchbase-cxx-client/core/transactions/transaction_get_multi_result.hxx +67 -0
  87. package/deps/couchbase-cxx-client/core/transactions/transaction_links.hxx +10 -0
  88. package/deps/couchbase-cxx-client/core/transactions/transactions.cxx +8 -3
  89. package/deps/couchbase-cxx-client/core/utils/connection_string.cxx +7 -0
  90. package/deps/couchbase-cxx-client/core/utils/connection_string.hxx +1 -0
  91. package/deps/couchbase-cxx-client/core/utils/url_codec.cxx +26 -0
  92. package/deps/couchbase-cxx-client/core/utils/url_codec.hxx +11 -0
  93. package/deps/couchbase-cxx-client/core/websocket_codec.cxx +647 -0
  94. package/deps/couchbase-cxx-client/core/websocket_codec.hxx +77 -0
  95. package/deps/couchbase-cxx-client/couchbase/analytics_options.hxx +70 -6
  96. package/deps/couchbase-cxx-client/couchbase/application_telemetry_options.hxx +124 -0
  97. package/deps/couchbase-cxx-client/couchbase/behavior_options.hxx +9 -0
  98. package/deps/couchbase-cxx-client/couchbase/cluster_options.hxx +17 -0
  99. package/deps/couchbase-cxx-client/couchbase/error_codes.hxx +1 -0
  100. package/deps/couchbase-cxx-client/couchbase/logger.hxx +16 -0
  101. package/deps/couchbase-cxx-client/couchbase/management/bucket_settings.hxx +1 -0
  102. package/deps/couchbase-cxx-client/couchbase/query_options.hxx +70 -6
  103. package/deps/couchbase-cxx-client/couchbase/transactions/async_attempt_context.hxx +29 -5
  104. package/deps/couchbase-cxx-client/couchbase/transactions/attempt_context.hxx +24 -7
  105. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_mode.hxx +47 -0
  106. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_options.hxx +44 -0
  107. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_mode.hxx +46 -0
  108. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_options.hxx +48 -0
  109. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_result.hxx +112 -0
  110. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_replicas_from_preferred_server_group_spec.hxx +47 -0
  111. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_result.hxx +105 -0
  112. package/deps/couchbase-cxx-client/couchbase/transactions/transaction_get_multi_spec.hxx +45 -0
  113. package/dist/analyticsindexmanager.d.ts +1 -0
  114. package/dist/binarycollection.d.ts +1 -0
  115. package/dist/binding.d.ts +82 -38
  116. package/dist/binding.js +14 -7
  117. package/dist/bindingutilities.d.ts +16 -4
  118. package/dist/bindingutilities.js +233 -31
  119. package/dist/cluster.d.ts +39 -0
  120. package/dist/cluster.js +21 -3
  121. package/dist/collection.d.ts +20 -1
  122. package/dist/collection.js +13 -0
  123. package/dist/errorcontexts.d.ts +24 -0
  124. package/dist/errorcontexts.js +12 -6
  125. package/dist/generaltypes.d.ts +16 -0
  126. package/dist/generaltypes.js +18 -1
  127. package/dist/httpexecutor.d.ts +1 -2
  128. package/dist/httpexecutor.js +0 -9
  129. package/dist/streamablepromises.d.ts +25 -7
  130. package/dist/streamablepromises.js +32 -7
  131. package/dist/transactions.d.ts +239 -1
  132. package/dist/transactions.js +316 -2
  133. package/dist/transcoders.d.ts +1 -0
  134. package/dist/utilities.d.ts +1 -0
  135. package/package.json +24 -24
  136. package/src/connection.cpp +34 -4
  137. package/src/constants.cpp +124 -0
  138. package/src/jstocbpp_autogen.hpp +22 -8
  139. package/src/jstocbpp_transactions.hpp +76 -2
  140. package/src/transaction.cpp +101 -0
  141. package/src/transaction.hpp +5 -0
  142. package/tools/gen-bindings-js.js +2 -1
  143. package/tools/gen-bindings-json.py +28 -3
@@ -0,0 +1,59 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2024-Present Couchbase, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
6
+ * except in compliance with the License. You may obtain a copy of the License at
7
+ *
8
+ * https://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software distributed under
11
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
12
+ * ANY KIND, either express or implied. See the License for the specific language governing
13
+ * permissions and limitations under the License.
14
+ */
15
+
16
+ #pragma once
17
+
18
+ #include "config_listener.hxx"
19
+
20
+ #include <memory>
21
+
22
+ namespace asio
23
+ {
24
+ class io_context;
25
+ namespace ssl
26
+ {
27
+ class context;
28
+ } // namespace ssl
29
+ } // namespace asio
30
+
31
+ namespace couchbase::core
32
+ {
33
+ class app_telemetry_reporter_impl;
34
+ class app_telemetry_meter;
35
+ struct cluster_options;
36
+ struct cluster_credentials;
37
+
38
+ class app_telemetry_reporter : public config_listener
39
+ {
40
+ public:
41
+ app_telemetry_reporter() = delete;
42
+ app_telemetry_reporter(app_telemetry_reporter&&) = default;
43
+ app_telemetry_reporter(const app_telemetry_reporter&) = delete;
44
+ auto operator=(app_telemetry_reporter&&) -> app_telemetry_reporter& = default;
45
+ auto operator=(const app_telemetry_reporter&) -> app_telemetry_reporter& = delete;
46
+
47
+ app_telemetry_reporter(std::shared_ptr<app_telemetry_meter> meter,
48
+ const cluster_options& options,
49
+ const cluster_credentials& credentials,
50
+ asio::io_context& ctx,
51
+ asio::ssl::context& tls);
52
+ ~app_telemetry_reporter() override;
53
+ void update_config(topology::configuration config) override;
54
+ void stop();
55
+
56
+ private:
57
+ std::shared_ptr<app_telemetry_reporter_impl> impl_{};
58
+ };
59
+ } // namespace couchbase::core
@@ -18,6 +18,7 @@
18
18
  #include "bucket.hxx"
19
19
 
20
20
  #include "collection_id_cache_entry.hxx"
21
+ #include "core/app_telemetry_meter.hxx"
21
22
  #include "core/config_listener.hxx"
22
23
  #include "core/document_id.hxx"
23
24
  #include "core/error_context/key_value_error_map_info.hxx"
@@ -84,6 +85,7 @@ public:
84
85
  couchbase::core::origin origin,
85
86
  std::shared_ptr<tracing::tracer_wrapper> tracer,
86
87
  std::shared_ptr<metrics::meter_wrapper> meter,
88
+ std::shared_ptr<core::app_telemetry_meter> app_telemetry,
87
89
  std::vector<protocol::hello_feature> known_features,
88
90
  std::shared_ptr<impl::bootstrap_state_listener> state_listener,
89
91
  asio::io_context& ctx,
@@ -94,6 +96,7 @@ public:
94
96
  , origin_{ std::move(origin) }
95
97
  , tracer_{ std::move(tracer) }
96
98
  , meter_{ std::move(meter) }
99
+ , app_telemetry_meter_{ std::move(app_telemetry) }
97
100
  , known_features_{ std::move(known_features) }
98
101
  , state_listener_{ std::move(state_listener) }
99
102
  , codec_{ { known_features_.begin(), known_features_.end() } }
@@ -201,7 +204,10 @@ public:
201
204
  return errc::network::bucket_closed;
202
205
  }
203
206
  if (!configured_) {
204
- return defer_command([self = shared_from_this(), req]() {
207
+ return defer_command([self = shared_from_this(), req](std::error_code ec) {
208
+ if (ec == errc::common::request_canceled) {
209
+ return req->cancel(ec);
210
+ }
205
211
  self->direct_dispatch(req);
206
212
  });
207
213
  }
@@ -210,7 +216,10 @@ public:
210
216
 
211
217
  auto session = route_request(req);
212
218
  if (!session || !session->has_config()) {
213
- return defer_command([self = shared_from_this(), req]() mutable {
219
+ return defer_command([self = shared_from_this(), req](std::error_code ec) mutable {
220
+ if (ec == errc::common::request_canceled) {
221
+ return req->cancel(ec);
222
+ }
214
223
  self->direct_dispatch(std::move(req));
215
224
  });
216
225
  }
@@ -241,7 +250,10 @@ public:
241
250
 
242
251
  auto session = route_request(req);
243
252
  if (!session || !session->has_config()) {
244
- return defer_command([self = shared_from_this(), req]() {
253
+ return defer_command([self = shared_from_this(), req](std::error_code ec) {
254
+ if (ec == errc::common::request_canceled) {
255
+ return req->cancel(ec);
256
+ }
245
257
  self->direct_dispatch(req);
246
258
  });
247
259
  }
@@ -417,9 +429,16 @@ public:
417
429
  origin_.credentials(), hostname, port, origin_.options());
418
430
  io::mcbp_session session =
419
431
  origin_.options().enable_tls
420
- ? io::mcbp_session(
421
- client_id_, ctx_, tls_, origin, state_listener_, name_, known_features_)
422
- : io::mcbp_session(client_id_, ctx_, origin, state_listener_, name_, known_features_);
432
+ ? io::mcbp_session(client_id_,
433
+ node.node_uuid,
434
+ ctx_,
435
+ tls_,
436
+ origin,
437
+ state_listener_,
438
+ name_,
439
+ known_features_)
440
+ : io::mcbp_session(
441
+ client_id_, node.node_uuid, ctx_, origin, state_listener_, name_, known_features_);
423
442
  CB_LOG_DEBUG(R"({} rev={}, restart idx={}, session="{}", address="{}:{}")",
424
443
  log_prefix_,
425
444
  config_->rev_str(),
@@ -438,7 +457,7 @@ public:
438
457
  session.on_stop([id = session.id(), self]() {
439
458
  self->remove_session(id);
440
459
  });
441
- self->drain_deferred_queue();
460
+ self->drain_deferred_queue({});
442
461
  },
443
462
  true);
444
463
  sessions_.insert_or_assign(index, std::move(session));
@@ -479,8 +498,9 @@ public:
479
498
  }
480
499
  io::mcbp_session new_session =
481
500
  origin_.options().enable_tls
482
- ? io::mcbp_session(client_id_, ctx_, tls_, origin_, state_listener_, name_, known_features_)
483
- : io::mcbp_session(client_id_, ctx_, origin_, state_listener_, name_, known_features_);
501
+ ? io::mcbp_session(
502
+ client_id_, {}, ctx_, tls_, origin_, state_listener_, name_, known_features_)
503
+ : io::mcbp_session(client_id_, {}, ctx_, origin_, state_listener_, name_, known_features_);
484
504
  new_session.bootstrap([self = shared_from_this(), new_session, h = std::move(handler)](
485
505
  std::error_code ec, topology::configuration cfg) mutable {
486
506
  if (ec) {
@@ -501,7 +521,7 @@ public:
501
521
  self->sessions_.insert_or_assign(this_index, std::move(new_session));
502
522
  }
503
523
  self->update_config(cfg);
504
- self->drain_deferred_queue();
524
+ self->drain_deferred_queue({});
505
525
  self->poll_config({});
506
526
  }
507
527
  asio::post(
@@ -530,26 +550,27 @@ public:
530
550
  return handler(errc::network::configuration_not_available, nullptr);
531
551
  }
532
552
  const std::scoped_lock lock(deferred_commands_mutex_);
533
- deferred_commands_.emplace([self = shared_from_this(), handler = std::move(handler)]() mutable {
534
- if (self->closed_ || !self->configured_) {
535
- return handler(errc::network::configuration_not_available, nullptr);
536
- }
553
+ deferred_commands_.emplace(
554
+ [self = shared_from_this(), handler = std::move(handler)](std::error_code ec) mutable {
555
+ if (ec == errc::common::request_canceled || self->closed_ || !self->configured_) {
556
+ return handler(errc::network::configuration_not_available, nullptr);
557
+ }
537
558
 
538
- std::shared_ptr<topology::configuration> config{};
539
- {
540
- const std::scoped_lock config_lock(self->config_mutex_);
541
- config = self->config_;
542
- }
543
- if (config) {
544
- return handler({}, std::move(config));
545
- }
546
- return handler(errc::network::configuration_not_available, nullptr);
547
- });
559
+ std::shared_ptr<topology::configuration> config{};
560
+ {
561
+ const std::scoped_lock config_lock(self->config_mutex_);
562
+ config = self->config_;
563
+ }
564
+ if (config) {
565
+ return handler({}, config);
566
+ }
567
+ return handler(errc::network::configuration_not_available, nullptr);
568
+ });
548
569
  }
549
570
 
550
- void drain_deferred_queue()
571
+ void drain_deferred_queue(std::error_code ec)
551
572
  {
552
- std::queue<utils::movable_function<void()>> commands{};
573
+ std::queue<utils::movable_function<void(std::error_code)>> commands{};
553
574
  {
554
575
  const std::scoped_lock lock(deferred_commands_mutex_);
555
576
  std::swap(deferred_commands_, commands);
@@ -559,7 +580,7 @@ public:
559
580
  R"({} draining deferred operation queue, size={})", log_prefix_, commands.size());
560
581
  }
561
582
  while (!commands.empty()) {
562
- commands.front()();
583
+ commands.front()(ec);
563
584
  commands.pop();
564
585
  }
565
586
  }
@@ -629,7 +650,7 @@ public:
629
650
 
630
651
  heartbeat_timer_.cancel();
631
652
 
632
- drain_deferred_queue();
653
+ drain_deferred_queue(errc::common::request_canceled);
633
654
 
634
655
  if (state_listener_ != nullptr) {
635
656
  state_listener_->unregister_config_listener(shared_from_this());
@@ -793,9 +814,16 @@ public:
793
814
  origin_.credentials(), hostname, port, origin_.options());
794
815
  io::mcbp_session session =
795
816
  origin_.options().enable_tls
796
- ? io::mcbp_session(
797
- client_id_, ctx_, tls_, origin, state_listener_, name_, known_features_)
798
- : io::mcbp_session(client_id_, ctx_, origin, state_listener_, name_, known_features_);
817
+ ? io::mcbp_session(client_id_,
818
+ node.node_uuid,
819
+ ctx_,
820
+ tls_,
821
+ origin,
822
+ state_listener_,
823
+ name_,
824
+ known_features_)
825
+ : io::mcbp_session(
826
+ client_id_, node.node_uuid, ctx_, origin, state_listener_, name_, known_features_);
799
827
  CB_LOG_DEBUG(R"({} rev={}, add session="{}", address="{}:{}", index={})",
800
828
  log_prefix_,
801
829
  config.rev_str(),
@@ -822,7 +850,7 @@ public:
822
850
  session.on_stop([id = session.id(), self]() {
823
851
  self->remove_session(id);
824
852
  });
825
- self->drain_deferred_queue();
853
+ self->drain_deferred_queue({});
826
854
  },
827
855
  true);
828
856
  new_sessions.insert_or_assign(next_index, std::move(session));
@@ -901,6 +929,11 @@ public:
901
929
  return meter_;
902
930
  }
903
931
 
932
+ [[nodiscard]] auto app_telemetry_meter() const -> std::shared_ptr<core::app_telemetry_meter>
933
+ {
934
+ return app_telemetry_meter_;
935
+ }
936
+
904
937
  void export_diag_info(diag::diagnostics_result& res) const
905
938
  {
906
939
  std::map<size_t, io::mcbp_session> sessions;
@@ -937,7 +970,7 @@ public:
937
970
  config_listeners_.emplace_back(std::move(handler));
938
971
  }
939
972
 
940
- auto defer_command(utils::movable_function<void()> command) -> std::error_code
973
+ auto defer_command(utils::movable_function<void(std::error_code)> command) -> std::error_code
941
974
  {
942
975
  const std::scoped_lock lock_for_deferred_commands(deferred_commands_mutex_);
943
976
  deferred_commands_.emplace(std::move(command));
@@ -951,6 +984,7 @@ private:
951
984
  const origin origin_;
952
985
  const std::shared_ptr<tracing::tracer_wrapper> tracer_;
953
986
  const std::shared_ptr<metrics::meter_wrapper> meter_;
987
+ const std::shared_ptr<core::app_telemetry_meter> app_telemetry_meter_;
954
988
  const std::vector<protocol::hello_feature> known_features_;
955
989
  const std::shared_ptr<impl::bootstrap_state_listener> state_listener_;
956
990
  mcbp::codec codec_;
@@ -971,7 +1005,7 @@ private:
971
1005
  std::vector<std::shared_ptr<config_listener>> config_listeners_{};
972
1006
  std::mutex config_listeners_mutex_{};
973
1007
 
974
- std::queue<utils::movable_function<void()>> deferred_commands_{};
1008
+ std::queue<utils::movable_function<void(std::error_code)>> deferred_commands_{};
975
1009
  std::mutex deferred_commands_mutex_{};
976
1010
 
977
1011
  std::map<size_t, io::mcbp_session> sessions_{};
@@ -984,6 +1018,7 @@ bucket::bucket(std::string client_id,
984
1018
  asio::ssl::context& tls,
985
1019
  std::shared_ptr<tracing::tracer_wrapper> tracer,
986
1020
  std::shared_ptr<metrics::meter_wrapper> meter,
1021
+ std::shared_ptr<core::app_telemetry_meter> app_telemetry_meter,
987
1022
  std::string name,
988
1023
  couchbase::core::origin origin,
989
1024
  std::vector<protocol::hello_feature> known_features,
@@ -995,6 +1030,7 @@ bucket::bucket(std::string client_id,
995
1030
  std::move(origin),
996
1031
  std::move(tracer),
997
1032
  std::move(meter),
1033
+ std::move(app_telemetry_meter),
998
1034
  std::move(known_features),
999
1035
  std::move(state_listener),
1000
1036
  ctx,
@@ -1062,6 +1098,12 @@ bucket::meter() const -> std::shared_ptr<metrics::meter_wrapper>
1062
1098
  return impl_->meter();
1063
1099
  }
1064
1100
 
1101
+ auto
1102
+ bucket::app_telemetry_meter() const -> std::shared_ptr<core::app_telemetry_meter>
1103
+ {
1104
+ return impl_->app_telemetry_meter();
1105
+ }
1106
+
1065
1107
  auto
1066
1108
  bucket::default_retry_strategy() const -> std::shared_ptr<couchbase::retry_strategy>
1067
1109
  {
@@ -1101,7 +1143,7 @@ bucket::is_configured() const -> bool
1101
1143
  }
1102
1144
 
1103
1145
  void
1104
- bucket::defer_command(utils::movable_function<void()> command)
1146
+ bucket::defer_command(utils::movable_function<void(std::error_code)> command)
1105
1147
  {
1106
1148
  impl_->defer_command(std::move(command));
1107
1149
  }
@@ -31,9 +31,7 @@
31
31
  #include <utility>
32
32
  #include <vector>
33
33
 
34
- namespace couchbase
35
- {
36
- namespace core
34
+ namespace couchbase::core
37
35
  {
38
36
  namespace mcbp
39
37
  {
@@ -57,6 +55,8 @@ namespace impl
57
55
  class bootstrap_state_listener;
58
56
  } // namespace impl
59
57
 
58
+ class app_telemetry_meter;
59
+
60
60
  class bucket_impl;
61
61
  struct origin;
62
62
 
@@ -70,6 +70,7 @@ public:
70
70
  asio::ssl::context& tls,
71
71
  std::shared_ptr<tracing::tracer_wrapper> tracer,
72
72
  std::shared_ptr<metrics::meter_wrapper> meter,
73
+ std::shared_ptr<core::app_telemetry_meter> app_telemetry_meter,
73
74
  std::string name,
74
75
  couchbase::core::origin origin,
75
76
  std::vector<protocol::hello_feature> known_features,
@@ -95,7 +96,10 @@ public:
95
96
  if (is_configured()) {
96
97
  return map_and_send(cmd);
97
98
  }
98
- return defer_command([self = shared_from_this(), cmd]() {
99
+ return defer_command([self = shared_from_this(), cmd](std::error_code ec) {
100
+ if (ec == errc::common::request_canceled) {
101
+ return cmd->cancel(retry_reason::do_not_retry);
102
+ }
99
103
  self->map_and_send(cmd);
100
104
  });
101
105
  }
@@ -137,7 +141,10 @@ public:
137
141
  session.has_value() ? session->bootstrap_address() : "",
138
142
  session.has_value() && session->has_config(),
139
143
  config_rev());
140
- return defer_command([self = shared_from_this(), cmd]() {
144
+ return defer_command([self = shared_from_this(), cmd](std::error_code ec) {
145
+ if (ec == errc::common::request_canceled) {
146
+ return cmd->cancel(retry_reason::do_not_retry);
147
+ }
141
148
  self->map_and_send(cmd);
142
149
  });
143
150
  }
@@ -197,19 +204,20 @@ public:
197
204
  void export_diag_info(diag::diagnostics_result& res) const;
198
205
  void ping(const std::shared_ptr<diag::ping_collector>& collector,
199
206
  std::optional<std::chrono::milliseconds> timeout);
200
- void defer_command(utils::movable_function<void()> command);
207
+ void defer_command(utils::movable_function<void(std::error_code)> command);
201
208
 
202
209
  [[nodiscard]] auto name() const -> const std::string&;
203
210
  [[nodiscard]] auto log_prefix() const -> const std::string&;
204
211
  [[nodiscard]] auto tracer() const -> std::shared_ptr<tracing::tracer_wrapper>;
205
212
  [[nodiscard]] auto meter() const -> std::shared_ptr<metrics::meter_wrapper>;
213
+ [[nodiscard]] auto app_telemetry_meter() const -> std::shared_ptr<app_telemetry_meter>;
206
214
  [[nodiscard]] auto default_retry_strategy() const -> std::shared_ptr<couchbase::retry_strategy>;
207
215
  [[nodiscard]] auto is_closed() const -> bool;
208
216
  [[nodiscard]] auto is_configured() const -> bool;
209
217
 
210
218
  auto direct_dispatch(std::shared_ptr<mcbp::queue_request> req) -> std::error_code;
211
- auto direct_re_queue(const std::shared_ptr<mcbp::queue_request>& req,
212
- bool is_retry) -> std::error_code;
219
+ auto direct_re_queue(const std::shared_ptr<mcbp::queue_request>& req, bool is_retry)
220
+ -> std::error_code;
213
221
 
214
222
  private:
215
223
  [[nodiscard]] auto default_timeout() const -> std::chrono::milliseconds;
@@ -223,5 +231,4 @@ private:
223
231
  asio::io_context& ctx_;
224
232
  std::shared_ptr<bucket_impl> impl_;
225
233
  };
226
- } // namespace core
227
- } // namespace couchbase
234
+ } // namespace couchbase::core
@@ -21,6 +21,8 @@
21
21
 
22
22
  #include "bucket.hxx"
23
23
  #include "capella_ca.hxx"
24
+ #include "core/app_telemetry_meter.hxx"
25
+ #include "core/app_telemetry_reporter.hxx"
24
26
  #include "core/diagnostics.hxx"
25
27
  #include "core/impl/get_replica.hxx"
26
28
  #include "core/impl/lookup_in_replica.hxx"
@@ -348,9 +350,10 @@ public:
348
350
  }
349
351
 
350
352
  origin_ = std::move(origin);
351
- CB_LOG_DEBUG(R"(open cluster, id: "{}", core version: "{}", {})",
353
+ CB_LOG_DEBUG(R"(open cluster, id: "{}", core version: "{}", connection string: {}, {})",
352
354
  id_,
353
355
  couchbase::core::meta::sdk_semver(),
356
+ origin_.connection_string(),
354
357
  origin_.to_json());
355
358
  setup_observability();
356
359
  if (origin_.options().enable_dns_srv) {
@@ -444,13 +447,22 @@ public:
444
447
  }
445
448
  }
446
449
 
447
- b = std::make_shared<bucket>(
448
- id_, ctx_, tls_, tracer_, meter_, bucket_name, origin, known_features, dns_srv_tracker_);
450
+ b = std::make_shared<bucket>(id_,
451
+ ctx_,
452
+ tls_,
453
+ tracer_,
454
+ meter_,
455
+ app_telemetry_meter_,
456
+ bucket_name,
457
+ origin,
458
+ known_features,
459
+ dns_srv_tracker_);
449
460
  buckets_.try_emplace(bucket_name, b);
450
461
 
451
462
  // Register the tracer & the meter for config updates to track Cluster name & UUID
452
463
  b->on_configuration_update(tracer_);
453
464
  b->on_configuration_update(meter_);
465
+ b->on_configuration_update(app_telemetry_reporter_);
454
466
  }
455
467
  }
456
468
  if (b == nullptr) {
@@ -766,9 +778,9 @@ public:
766
778
  });
767
779
  }
768
780
  }
769
- session_ = io::mcbp_session(id_, ctx_, tls_, origin_, dns_srv_tracker_);
781
+ session_ = io::mcbp_session(id_, {}, ctx_, tls_, origin_, dns_srv_tracker_);
770
782
  } else {
771
- session_ = io::mcbp_session(id_, ctx_, origin_, dns_srv_tracker_);
783
+ session_ = io::mcbp_session(id_, {}, ctx_, origin_, dns_srv_tracker_);
772
784
  }
773
785
  session_->bootstrap([self = shared_from_this(), handler = std::move(handler)](
774
786
  std::error_code ec, const topology::configuration& config) mutable {
@@ -793,8 +805,12 @@ public:
793
805
  self->origin_.options().network,
794
806
  utils::join_strings(self->origin_.get_nodes(), ","));
795
807
  }
808
+ // FIXME(SA): fix the session manager to receive initial configuration and cluster-wide
809
+ // session to poll for updates like the bucket does. Or just subscribe before the bootstrap.
796
810
  self->session_manager_->set_configuration(config, self->origin_.options());
797
811
  self->session_->on_configuration_update(self->session_manager_);
812
+ self->session_->on_configuration_update(self->app_telemetry_reporter_);
813
+ self->app_telemetry_reporter_->update_config(config);
798
814
  self->session_->on_stop([self]() {
799
815
  if (self->session_) {
800
816
  self->session_.reset();
@@ -972,6 +988,8 @@ public:
972
988
  } else {
973
989
  self->session_manager_->set_configuration(cfg, options);
974
990
  self->config_tracker_->on_configuration_update(self->session_manager_);
991
+ self->config_tracker_->on_configuration_update(self->app_telemetry_reporter_);
992
+ self->app_telemetry_reporter_->update_config(cfg);
975
993
  self->config_tracker_->register_state_listener();
976
994
  }
977
995
  });
@@ -1092,9 +1110,8 @@ public:
1092
1110
  stopped_ = true;
1093
1111
  asio::post(asio::bind_executor(
1094
1112
  ctx_, [self = shared_from_this(), handler = std::move(handler)]() mutable {
1095
- if (self->session_) {
1096
- self->session_->stop(retry_reason::do_not_retry);
1097
- self->session_.reset();
1113
+ if (auto session = std::move(self->session_); session) {
1114
+ session->stop(retry_reason::do_not_retry);
1098
1115
  }
1099
1116
  #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
1100
1117
  if (self->config_tracker_) {
@@ -1104,19 +1121,31 @@ public:
1104
1121
  }
1105
1122
  self->retry_backoff_.cancel();
1106
1123
  #endif
1107
- self->for_each_bucket([](const auto& bucket) {
1124
+
1125
+ std::map<std::string, std::shared_ptr<bucket>> buckets{};
1126
+ {
1127
+ const std::scoped_lock lock(self->buckets_mutex_);
1128
+ buckets = std::move(self->buckets_);
1129
+ }
1130
+ for (const auto& [_, bucket] : buckets) {
1108
1131
  bucket->close();
1109
- });
1110
- self->session_manager_->close();
1132
+ }
1133
+ if (auto session_manager = std::move(self->session_manager_); session_manager) {
1134
+ session_manager->close();
1135
+ }
1111
1136
  self->work_.reset();
1112
- if (self->tracer_) {
1113
- self->tracer_->stop();
1137
+ if (auto tracer = std::move(self->tracer_); tracer) {
1138
+ tracer->stop();
1139
+ }
1140
+ if (auto meter = std::move(self->meter_); meter) {
1141
+ meter->stop();
1142
+ }
1143
+ if (auto meter = std::move(self->app_telemetry_meter_); meter) {
1144
+ meter->disable();
1114
1145
  }
1115
- self->tracer_.reset();
1116
- if (self->meter_) {
1117
- self->meter_->stop();
1146
+ if (auto reporter = std::move(self->app_telemetry_reporter_); reporter) {
1147
+ reporter->stop();
1118
1148
  }
1119
- self->meter_.reset();
1120
1149
  handler();
1121
1150
  }));
1122
1151
  }
@@ -1210,6 +1239,11 @@ private:
1210
1239
 
1211
1240
  session_manager_->set_tracer(tracer_);
1212
1241
  session_manager_->set_meter(meter_);
1242
+
1243
+ app_telemetry_meter_->update_agent(origin_.options().user_agent_extra);
1244
+ session_manager_->set_app_telemetry_meter(app_telemetry_meter_);
1245
+ app_telemetry_reporter_ = std::make_shared<app_telemetry_reporter>(
1246
+ app_telemetry_meter_, origin_.options(), origin_.credentials(), ctx_, tls_);
1213
1247
  }
1214
1248
 
1215
1249
  std::string id_{ uuid::to_string(uuid::random()) };
@@ -1217,6 +1251,7 @@ private:
1217
1251
  asio::executor_work_guard<asio::io_context::executor_type> work_;
1218
1252
  asio::ssl::context tls_{ asio::ssl::context::tls_client };
1219
1253
  std::shared_ptr<io::http_session_manager> session_manager_;
1254
+ std::shared_ptr<app_telemetry_reporter> app_telemetry_reporter_{};
1220
1255
  std::optional<io::mcbp_session> session_{};
1221
1256
  std::shared_ptr<impl::dns_srv_tracker> dns_srv_tracker_{};
1222
1257
  std::mutex buckets_mutex_{};
@@ -1225,6 +1260,10 @@ private:
1225
1260
  std::shared_ptr<tracing::tracer_wrapper> tracer_{ nullptr };
1226
1261
  std::shared_ptr<metrics::meter_wrapper> meter_{ nullptr };
1227
1262
  std::atomic_bool stopped_{ false };
1263
+ std::shared_ptr<core::app_telemetry_meter> app_telemetry_meter_{
1264
+ std::make_shared<core::app_telemetry_meter>()
1265
+ };
1266
+
1228
1267
  #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
1229
1268
  std::shared_ptr<couchbase::core::io::cluster_config_tracker> config_tracker_{};
1230
1269
  asio::steady_timer retry_backoff_;
@@ -0,0 +1,27 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020-2021 Couchbase, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #include "cluster_credentials.hxx"
19
+
20
+ namespace couchbase::core
21
+ {
22
+ auto
23
+ cluster_credentials::uses_certificate() const -> bool
24
+ {
25
+ return !certificate_path.empty();
26
+ }
27
+ } // namespace couchbase::core
@@ -0,0 +1,36 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020-2021 Couchbase, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #pragma once
19
+
20
+ #include <optional>
21
+ #include <string>
22
+ #include <vector>
23
+
24
+ namespace couchbase::core
25
+ {
26
+ struct cluster_credentials {
27
+ std::string username{};
28
+ std::string password{};
29
+ std::string certificate_path{};
30
+ std::string key_path{};
31
+ std::optional<std::vector<std::string>> allowed_sasl_mechanisms{};
32
+
33
+ [[nodiscard]] auto uses_certificate() const -> bool;
34
+ };
35
+
36
+ } // namespace couchbase::core
@@ -95,6 +95,19 @@ public:
95
95
  bool dump_configuration{ false };
96
96
  bool disable_mozilla_ca_certificates{ false };
97
97
  couchbase::core::columnar::security_options security_options{};
98
+
99
+ bool enable_app_telemetry{ true };
100
+ std::string app_telemetry_endpoint{};
101
+ std::chrono::milliseconds app_telemetry_ping_interval{
102
+ timeout_defaults::app_telemetry_ping_interval
103
+ };
104
+ std::chrono::milliseconds app_telemetry_ping_timeout{
105
+ timeout_defaults::app_telemetry_ping_timeout
106
+ };
107
+ std::chrono::milliseconds app_telemetry_backoff_interval{
108
+ timeout_defaults::app_telemetry_backoff_interval
109
+ };
110
+ bool preserve_bootstrap_nodes_order{ false };
98
111
  };
99
112
 
100
113
  } // namespace couchbase::core