couchbase 3.7.0 → 3.8.0

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 (286) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/ext/CMakeLists.txt +4 -1
  4. data/ext/cache/extconf_include.rb +4 -3
  5. data/ext/cache/mozilla-ca-bundle.crt +66 -93
  6. data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
  7. data/ext/couchbase/CMakeLists.txt +24 -11
  8. data/ext/couchbase/cmake/APKBUILD.in +17 -1
  9. data/ext/couchbase/cmake/Bundler.cmake +9 -1
  10. data/ext/couchbase/cmake/Cache.cmake +48 -19
  11. data/ext/couchbase/cmake/CompilerOptions.cmake +3 -1
  12. data/ext/couchbase/cmake/OpenSSL.cmake +10 -2
  13. data/ext/couchbase/cmake/Packaging.cmake +48 -8
  14. data/ext/couchbase/cmake/ThirdPartyDependencies.cmake +43 -1
  15. data/ext/couchbase/cmake/build_config.hxx.in +2 -0
  16. data/ext/couchbase/cmake/couchbase-cxx-client.spec.in +18 -0
  17. data/ext/couchbase/cmake/tarball_glob.txt +10 -0
  18. data/ext/couchbase/core/app_telemetry_meter.cxx +1 -0
  19. data/ext/couchbase/core/app_telemetry_reporter.cxx +45 -43
  20. data/ext/couchbase/core/app_telemetry_reporter.hxx +4 -3
  21. data/ext/couchbase/core/bucket.cxx +128 -13
  22. data/ext/couchbase/core/bucket.hxx +12 -2
  23. data/ext/couchbase/core/cluster.cxx +304 -152
  24. data/ext/couchbase/core/cluster.hxx +32 -0
  25. data/ext/couchbase/core/cluster_credentials.cxx +25 -0
  26. data/ext/couchbase/core/cluster_credentials.hxx +5 -0
  27. data/ext/couchbase/core/cluster_label_listener.cxx +72 -0
  28. data/ext/couchbase/core/cluster_label_listener.hxx +46 -0
  29. data/ext/couchbase/core/cluster_options.hxx +4 -0
  30. data/ext/couchbase/core/deprecation_utils.hxx +26 -0
  31. data/ext/couchbase/core/error.hxx +27 -0
  32. data/ext/couchbase/core/free_form_http_request.hxx +0 -2
  33. data/ext/couchbase/core/http_component.cxx +12 -48
  34. data/ext/couchbase/core/impl/analytics.cxx +3 -2
  35. data/ext/couchbase/core/impl/analytics.hxx +2 -1
  36. data/ext/couchbase/core/impl/analytics_index_manager.cxx +249 -137
  37. data/ext/couchbase/core/impl/binary_collection.cxx +134 -58
  38. data/ext/couchbase/core/impl/bucket_manager.cxx +87 -35
  39. data/ext/couchbase/core/impl/collection.cxx +560 -245
  40. data/ext/couchbase/core/impl/collection_manager.cxx +89 -49
  41. data/ext/couchbase/core/impl/dns_srv_tracker.cxx +4 -4
  42. data/ext/couchbase/core/impl/error.cxx +20 -13
  43. data/ext/couchbase/core/impl/error.hxx +15 -10
  44. data/ext/couchbase/core/impl/get_all_replicas.hxx +1 -1
  45. data/ext/couchbase/core/impl/get_any_replica.hxx +2 -1
  46. data/ext/couchbase/core/impl/get_replica.hxx +2 -0
  47. data/ext/couchbase/core/impl/lookup_in_replica.hxx +1 -1
  48. data/ext/couchbase/core/impl/observability_recorder.cxx +161 -0
  49. data/ext/couchbase/core/impl/observability_recorder.hxx +77 -0
  50. data/ext/couchbase/core/impl/observe_seqno.hxx +2 -0
  51. data/ext/couchbase/core/impl/public_bucket.cxx +31 -7
  52. data/ext/couchbase/core/impl/public_cluster.cxx +107 -19
  53. data/ext/couchbase/core/impl/query.cxx +6 -3
  54. data/ext/couchbase/core/impl/query.hxx +3 -1
  55. data/ext/couchbase/core/impl/query_index_manager.cxx +267 -102
  56. data/ext/couchbase/core/impl/scope.cxx +53 -11
  57. data/ext/couchbase/core/impl/search.cxx +8 -4
  58. data/ext/couchbase/core/impl/search.hxx +6 -2
  59. data/ext/couchbase/core/impl/search_index_manager.cxx +131 -41
  60. data/ext/couchbase/core/impl/with_cancellation.hxx +75 -0
  61. data/ext/couchbase/core/io/config_tracker.cxx +9 -9
  62. data/ext/couchbase/core/io/config_tracker.hxx +2 -1
  63. data/ext/couchbase/core/io/http_command.hxx +98 -49
  64. data/ext/couchbase/core/io/http_context.hxx +2 -0
  65. data/ext/couchbase/core/io/http_session.cxx +23 -10
  66. data/ext/couchbase/core/io/http_session.hxx +17 -9
  67. data/ext/couchbase/core/io/http_session_manager.hxx +163 -228
  68. data/ext/couchbase/core/io/http_traits.hxx +0 -7
  69. data/ext/couchbase/core/io/mcbp_command.hxx +123 -44
  70. data/ext/couchbase/core/io/mcbp_session.cxx +251 -26
  71. data/ext/couchbase/core/io/mcbp_session.hxx +9 -1
  72. data/ext/couchbase/core/io/mcbp_traits.hxx +0 -8
  73. data/ext/couchbase/core/io/streams.cxx +3 -3
  74. data/ext/couchbase/core/io/streams.hxx +3 -2
  75. data/ext/couchbase/core/meta/features.hxx +15 -0
  76. data/ext/couchbase/core/meta/version.cxx +13 -0
  77. data/ext/couchbase/core/meta/version.hxx +3 -0
  78. data/ext/couchbase/core/metrics/constants.hxx +23 -0
  79. data/ext/couchbase/core/metrics/logging_meter.cxx +5 -5
  80. data/ext/couchbase/core/metrics/meter_wrapper.cxx +65 -63
  81. data/ext/couchbase/core/metrics/meter_wrapper.hxx +12 -10
  82. data/ext/couchbase/core/operations/document_analytics.hxx +0 -5
  83. data/ext/couchbase/core/operations/document_append.hxx +0 -4
  84. data/ext/couchbase/core/operations/document_decrement.hxx +0 -5
  85. data/ext/couchbase/core/operations/document_exists.hxx +0 -7
  86. data/ext/couchbase/core/operations/document_get.hxx +0 -7
  87. data/ext/couchbase/core/operations/document_get_all_replicas.hxx +77 -27
  88. data/ext/couchbase/core/operations/document_get_and_lock.hxx +0 -9
  89. data/ext/couchbase/core/operations/document_get_and_touch.hxx +0 -9
  90. data/ext/couchbase/core/operations/document_get_any_replica.hxx +83 -2
  91. data/ext/couchbase/core/operations/document_get_projected.hxx +0 -9
  92. data/ext/couchbase/core/operations/document_increment.hxx +0 -5
  93. data/ext/couchbase/core/operations/document_insert.hxx +0 -4
  94. data/ext/couchbase/core/operations/document_lookup_in.hxx +0 -9
  95. data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +46 -4
  96. data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +121 -43
  97. data/ext/couchbase/core/operations/document_mutate_in.hxx +0 -5
  98. data/ext/couchbase/core/operations/document_prepend.hxx +0 -4
  99. data/ext/couchbase/core/operations/document_query.hxx +0 -4
  100. data/ext/couchbase/core/operations/document_remove.hxx +0 -4
  101. data/ext/couchbase/core/operations/document_replace.hxx +0 -4
  102. data/ext/couchbase/core/operations/document_search.hxx +0 -7
  103. data/ext/couchbase/core/operations/document_touch.hxx +0 -7
  104. data/ext/couchbase/core/operations/document_unlock.hxx +0 -6
  105. data/ext/couchbase/core/operations/document_upsert.hxx +0 -4
  106. data/ext/couchbase/core/operations/document_view.cxx +2 -0
  107. data/ext/couchbase/core/operations/document_view.hxx +10 -13
  108. data/ext/couchbase/core/operations/http_noop.hxx +2 -0
  109. data/ext/couchbase/core/operations/management/analytics_dataset_create.hxx +2 -0
  110. data/ext/couchbase/core/operations/management/analytics_dataset_drop.hxx +2 -0
  111. data/ext/couchbase/core/operations/management/analytics_dataset_get_all.hxx +2 -0
  112. data/ext/couchbase/core/operations/management/analytics_dataverse_create.hxx +2 -0
  113. data/ext/couchbase/core/operations/management/analytics_dataverse_drop.hxx +2 -0
  114. data/ext/couchbase/core/operations/management/analytics_get_pending_mutations.hxx +2 -0
  115. data/ext/couchbase/core/operations/management/analytics_index_create.hxx +2 -0
  116. data/ext/couchbase/core/operations/management/analytics_index_drop.hxx +2 -0
  117. data/ext/couchbase/core/operations/management/analytics_index_get_all.hxx +2 -0
  118. data/ext/couchbase/core/operations/management/analytics_link_connect.hxx +2 -0
  119. data/ext/couchbase/core/operations/management/analytics_link_create.hxx +2 -0
  120. data/ext/couchbase/core/operations/management/analytics_link_disconnect.hxx +2 -0
  121. data/ext/couchbase/core/operations/management/analytics_link_drop.hxx +2 -0
  122. data/ext/couchbase/core/operations/management/analytics_link_get_all.hxx +2 -0
  123. data/ext/couchbase/core/operations/management/analytics_link_replace.hxx +2 -0
  124. data/ext/couchbase/core/operations/management/bucket_create.hxx +2 -0
  125. data/ext/couchbase/core/operations/management/bucket_describe.hxx +2 -0
  126. data/ext/couchbase/core/operations/management/bucket_drop.hxx +2 -0
  127. data/ext/couchbase/core/operations/management/bucket_flush.hxx +2 -0
  128. data/ext/couchbase/core/operations/management/bucket_get.hxx +2 -0
  129. data/ext/couchbase/core/operations/management/bucket_get_all.hxx +2 -0
  130. data/ext/couchbase/core/operations/management/bucket_update.hxx +2 -0
  131. data/ext/couchbase/core/operations/management/change_password.hxx +2 -0
  132. data/ext/couchbase/core/operations/management/cluster_describe.hxx +2 -0
  133. data/ext/couchbase/core/operations/management/cluster_developer_preview_enable.hxx +2 -0
  134. data/ext/couchbase/core/operations/management/collection_create.hxx +2 -0
  135. data/ext/couchbase/core/operations/management/collection_drop.hxx +2 -0
  136. data/ext/couchbase/core/operations/management/collection_update.hxx +2 -0
  137. data/ext/couchbase/core/operations/management/collections_manifest_get.hxx +2 -0
  138. data/ext/couchbase/core/operations/management/error_utils.cxx +4 -1
  139. data/ext/couchbase/core/operations/management/eventing_deploy_function.hxx +2 -0
  140. data/ext/couchbase/core/operations/management/eventing_drop_function.hxx +2 -0
  141. data/ext/couchbase/core/operations/management/eventing_get_all_functions.hxx +2 -0
  142. data/ext/couchbase/core/operations/management/eventing_get_function.hxx +2 -0
  143. data/ext/couchbase/core/operations/management/eventing_get_status.hxx +2 -0
  144. data/ext/couchbase/core/operations/management/eventing_pause_function.hxx +2 -0
  145. data/ext/couchbase/core/operations/management/eventing_resume_function.hxx +2 -0
  146. data/ext/couchbase/core/operations/management/eventing_undeploy_function.hxx +2 -0
  147. data/ext/couchbase/core/operations/management/eventing_upsert_function.hxx +2 -0
  148. data/ext/couchbase/core/operations/management/freeform.hxx +2 -0
  149. data/ext/couchbase/core/operations/management/group_drop.hxx +2 -0
  150. data/ext/couchbase/core/operations/management/group_get.hxx +2 -0
  151. data/ext/couchbase/core/operations/management/group_get_all.hxx +2 -0
  152. data/ext/couchbase/core/operations/management/group_upsert.hxx +2 -0
  153. data/ext/couchbase/core/operations/management/query_index_build.hxx +2 -0
  154. data/ext/couchbase/core/operations/management/query_index_build_deferred.hxx +68 -30
  155. data/ext/couchbase/core/operations/management/query_index_create.hxx +2 -0
  156. data/ext/couchbase/core/operations/management/query_index_drop.hxx +2 -0
  157. data/ext/couchbase/core/operations/management/query_index_get_all.hxx +4 -3
  158. data/ext/couchbase/core/operations/management/query_index_get_all_deferred.hxx +2 -1
  159. data/ext/couchbase/core/operations/management/role_get_all.hxx +2 -0
  160. data/ext/couchbase/core/operations/management/scope_create.hxx +2 -0
  161. data/ext/couchbase/core/operations/management/scope_drop.hxx +2 -0
  162. data/ext/couchbase/core/operations/management/scope_get_all.hxx +2 -0
  163. data/ext/couchbase/core/operations/management/search_get_stats.hxx +2 -0
  164. data/ext/couchbase/core/operations/management/search_index_analyze_document.hxx +2 -0
  165. data/ext/couchbase/core/operations/management/search_index_control_ingest.hxx +2 -0
  166. data/ext/couchbase/core/operations/management/search_index_control_plan_freeze.hxx +2 -0
  167. data/ext/couchbase/core/operations/management/search_index_control_query.hxx +2 -0
  168. data/ext/couchbase/core/operations/management/search_index_drop.hxx +2 -0
  169. data/ext/couchbase/core/operations/management/search_index_get.hxx +2 -0
  170. data/ext/couchbase/core/operations/management/search_index_get_all.hxx +2 -0
  171. data/ext/couchbase/core/operations/management/search_index_get_documents_count.hxx +2 -0
  172. data/ext/couchbase/core/operations/management/search_index_get_stats.hxx +2 -0
  173. data/ext/couchbase/core/operations/management/search_index_upsert.hxx +2 -0
  174. data/ext/couchbase/core/operations/management/user_drop.hxx +2 -0
  175. data/ext/couchbase/core/operations/management/user_get.hxx +2 -0
  176. data/ext/couchbase/core/operations/management/user_get_all.hxx +2 -0
  177. data/ext/couchbase/core/operations/management/user_upsert.hxx +2 -0
  178. data/ext/couchbase/core/operations/management/view_index_drop.hxx +2 -0
  179. data/ext/couchbase/core/operations/management/view_index_get.hxx +2 -0
  180. data/ext/couchbase/core/operations/management/view_index_get_all.hxx +2 -0
  181. data/ext/couchbase/core/operations/management/view_index_upsert.hxx +2 -0
  182. data/ext/couchbase/core/operations/operation_traits.hxx +6 -0
  183. data/ext/couchbase/core/operations.hxx +0 -1
  184. data/ext/couchbase/core/operations_fwd.hxx +8 -0
  185. data/ext/couchbase/core/origin.cxx +67 -12
  186. data/ext/couchbase/core/origin.hxx +13 -8
  187. data/ext/couchbase/core/orphan_reporter.cxx +164 -0
  188. data/ext/couchbase/core/orphan_reporter.hxx +65 -0
  189. data/ext/couchbase/core/sasl/CMakeLists.txt +1 -0
  190. data/ext/couchbase/core/sasl/client.cc +6 -0
  191. data/ext/couchbase/core/sasl/mechanism.cc +2 -1
  192. data/ext/couchbase/core/sasl/mechanism.h +2 -1
  193. data/ext/couchbase/core/sasl/oauthbearer/oauthbearer.cc +41 -0
  194. data/ext/couchbase/core/sasl/oauthbearer/oauthbearer.h +47 -0
  195. data/ext/couchbase/core/tls_context_provider.cxx +44 -0
  196. data/ext/couchbase/core/tls_context_provider.hxx +44 -0
  197. data/ext/couchbase/core/tracing/attribute_helpers.hxx +45 -0
  198. data/ext/couchbase/core/tracing/constants.hxx +148 -68
  199. data/ext/couchbase/core/tracing/threshold_logging_options.hxx +0 -3
  200. data/ext/couchbase/core/tracing/threshold_logging_tracer.cxx +122 -170
  201. data/ext/couchbase/core/tracing/tracer_wrapper.cxx +17 -24
  202. data/ext/couchbase/core/tracing/tracer_wrapper.hxx +8 -10
  203. data/ext/couchbase/core/tracing/wrapper_sdk_tracer.cxx +114 -0
  204. data/ext/couchbase/core/tracing/wrapper_sdk_tracer.hxx +85 -0
  205. data/ext/couchbase/core/transactions/attempt_context_impl.cxx +16 -14
  206. data/ext/couchbase/core/transactions/attempt_context_impl.hxx +4 -4
  207. data/ext/couchbase/core/transactions/transactions.cxx +1 -1
  208. data/ext/couchbase/core/transactions/transactions_cleanup.cxx +1 -2
  209. data/ext/couchbase/core/utils/byteswap.hxx +12 -0
  210. data/ext/couchbase/core/utils/concurrent_fixed_priority_queue.hxx +102 -0
  211. data/ext/couchbase/core/utils/connection_string.cxx +2 -0
  212. data/ext/couchbase/couchbase/certificate_authenticator.hxx +1 -0
  213. data/ext/couchbase/couchbase/cluster.hxx +47 -0
  214. data/ext/couchbase/couchbase/cluster_options.hxx +16 -0
  215. data/ext/couchbase/couchbase/collection.hxx +60 -15
  216. data/ext/couchbase/couchbase/error_codes.hxx +48 -48
  217. data/ext/couchbase/couchbase/jwt_authenticator.hxx +52 -0
  218. data/ext/couchbase/couchbase/metrics/meter.hxx +2 -1
  219. data/ext/couchbase/couchbase/metrics/otel_meter.hxx +75 -80
  220. data/ext/couchbase/couchbase/network_options.hxx +19 -0
  221. data/ext/couchbase/couchbase/password_authenticator.hxx +1 -0
  222. data/ext/couchbase/couchbase/tracing/otel_tracer.hxx +15 -17
  223. data/ext/couchbase/couchbase/tracing/request_span.hxx +2 -2
  224. data/ext/couchbase.cxx +4 -0
  225. data/ext/extconf.rb +1 -0
  226. data/ext/rcb_analytics.cxx +157 -47
  227. data/ext/rcb_backend.cxx +118 -71
  228. data/ext/rcb_buckets.cxx +39 -16
  229. data/ext/rcb_collections.cxx +36 -12
  230. data/ext/rcb_crud.cxx +587 -294
  231. data/ext/rcb_hdr_histogram.cxx +219 -0
  232. data/ext/rcb_hdr_histogram.hxx +28 -0
  233. data/ext/rcb_multi.cxx +142 -59
  234. data/ext/rcb_observability.cxx +132 -0
  235. data/ext/rcb_observability.hxx +49 -0
  236. data/ext/rcb_query.cxx +77 -27
  237. data/ext/rcb_search.cxx +92 -31
  238. data/ext/rcb_users.cxx +69 -26
  239. data/ext/rcb_utils.cxx +91 -0
  240. data/ext/rcb_utils.hxx +141 -168
  241. data/ext/rcb_views.cxx +36 -12
  242. data/lib/active_support/cache/couchbase_store.rb +6 -6
  243. data/lib/couchbase/authenticator.rb +14 -0
  244. data/lib/couchbase/binary_collection.rb +37 -22
  245. data/lib/couchbase/bucket.rb +46 -31
  246. data/lib/couchbase/cluster.rb +146 -61
  247. data/lib/couchbase/collection.rb +257 -186
  248. data/lib/couchbase/datastructures/couchbase_list.rb +81 -50
  249. data/lib/couchbase/datastructures/couchbase_map.rb +86 -50
  250. data/lib/couchbase/datastructures/couchbase_queue.rb +64 -38
  251. data/lib/couchbase/datastructures/couchbase_set.rb +57 -41
  252. data/lib/couchbase/deprecations.rb +1 -1
  253. data/lib/couchbase/diagnostics.rb +8 -8
  254. data/lib/couchbase/errors.rb +6 -0
  255. data/lib/couchbase/management/analytics_index_manager.rb +90 -59
  256. data/lib/couchbase/management/bucket_manager.rb +73 -45
  257. data/lib/couchbase/management/collection_manager.rb +86 -43
  258. data/lib/couchbase/management/collection_query_index_manager.rb +56 -33
  259. data/lib/couchbase/management/query_index_manager.rb +88 -36
  260. data/lib/couchbase/management/scope_search_index_manager.rb +119 -52
  261. data/lib/couchbase/management/search_index_manager.rb +401 -178
  262. data/lib/couchbase/management/user_manager.rb +343 -174
  263. data/lib/couchbase/management/view_index_manager.rb +166 -73
  264. data/lib/couchbase/metrics/logging_meter.rb +108 -0
  265. data/lib/couchbase/metrics/logging_value_recorder.rb +50 -0
  266. data/lib/couchbase/metrics/meter.rb +27 -0
  267. data/lib/couchbase/metrics/noop_meter.rb +30 -0
  268. data/lib/couchbase/metrics/noop_value_recorder.rb +27 -0
  269. data/lib/couchbase/metrics/value_recorder.rb +25 -0
  270. data/lib/couchbase/options.rb +69 -3
  271. data/lib/couchbase/protostellar/cluster.rb +3 -0
  272. data/lib/couchbase/scope.rb +62 -48
  273. data/lib/couchbase/search_options.rb +18 -18
  274. data/lib/couchbase/tracing/noop_span.rb +29 -0
  275. data/lib/couchbase/tracing/noop_tracer.rb +29 -0
  276. data/lib/couchbase/tracing/request_span.rb +34 -0
  277. data/lib/couchbase/tracing/request_tracer.rb +28 -0
  278. data/lib/couchbase/tracing/threshold_logging_span.rb +112 -0
  279. data/lib/couchbase/tracing/threshold_logging_tracer.rb +231 -0
  280. data/lib/couchbase/utils/hdr_histogram.rb +55 -0
  281. data/lib/couchbase/utils/observability.rb +257 -0
  282. data/lib/couchbase/utils/observability_constants.rb +200 -0
  283. data/lib/couchbase/utils/stdlib_logger_adapter.rb +1 -3
  284. data/lib/couchbase/version.rb +1 -1
  285. data/lib/couchbase.rb +2 -2
  286. metadata +58 -6
@@ -17,13 +17,18 @@
17
17
 
18
18
  #include <couchbase/build_config.hxx>
19
19
 
20
+ #define COUCHBASE_CXX_CLIENT_IGNORE_CORE_DEPRECATIONS
20
21
  #include "cluster.hxx"
21
22
 
23
+ #include "core/operations/document_view.hxx"
24
+ #undef COUCHBASE_CXX_CLIENT_IGNORE_CORE_DEPRECATIONS
25
+
22
26
  #include "bucket.hxx"
23
27
  #include "capella_ca.hxx"
24
28
  #include "core/app_telemetry_meter.hxx"
25
29
  #include "core/app_telemetry_reporter.hxx"
26
30
  #include "core/diagnostics.hxx"
31
+ #include "core/error.hxx"
27
32
  #include "core/impl/get_replica.hxx"
28
33
  #include "core/impl/lookup_in_replica.hxx"
29
34
  #include "core/impl/observe_seqno.hxx"
@@ -34,6 +39,7 @@
34
39
  #ifdef COUCHBASE_CXX_CLIENT_COLUMNAR
35
40
  #include "core/io/config_tracker.hxx"
36
41
  #endif
42
+ #include "cluster_label_listener.hxx"
37
43
  #include "core/logger/logger.hxx"
38
44
  #include "core/management/analytics_link_azure_blob_external.hxx"
39
45
  #include "core/management/analytics_link_couchbase_remote.hxx"
@@ -67,7 +73,6 @@
67
73
  #include "core/operations/document_touch.hxx"
68
74
  #include "core/operations/document_unlock.hxx"
69
75
  #include "core/operations/document_upsert.hxx"
70
- #include "core/operations/document_view.hxx"
71
76
  #include "core/operations/http_noop.hxx"
72
77
  #include "core/operations/management/analytics_dataset_create.hxx"
73
78
  #include "core/operations/management/analytics_dataset_drop.hxx"
@@ -141,6 +146,7 @@
141
146
  #include "core/operations/management/view_index_get.hxx"
142
147
  #include "core/operations/management/view_index_get_all.hxx"
143
148
  #include "core/operations/management/view_index_upsert.hxx"
149
+ #include "core/orphan_reporter.hxx"
144
150
  #include "core/platform/uuid.h"
145
151
  #include "core/protocol/hello_feature.hxx"
146
152
  #include "core/service_type.hxx"
@@ -157,6 +163,7 @@
157
163
  #include "mozilla_ca_bundle.hxx"
158
164
  #include "ping_collector.hxx"
159
165
  #include "ping_reporter.hxx"
166
+ #include "tls_context_provider.hxx"
160
167
 
161
168
  #include <couchbase/codec/tao_json_serializer.hxx>
162
169
  #include <couchbase/error_codes.hxx>
@@ -294,7 +301,7 @@ public:
294
301
  explicit cluster_impl(asio::io_context& ctx)
295
302
  : ctx_(ctx)
296
303
  , work_(asio::make_work_guard(ctx_))
297
- , session_manager_(std::make_shared<io::http_session_manager>(id_, ctx_, tls_))
304
+ , session_manager_(std::make_shared<io::http_session_manager>(id_, ctx_, tls_, origin_))
298
305
  , retry_backoff_(ctx_)
299
306
  {
300
307
  }
@@ -302,7 +309,7 @@ public:
302
309
  explicit cluster_impl(asio::io_context& ctx)
303
310
  : ctx_(ctx)
304
311
  , work_(asio::make_work_guard(ctx_))
305
- , session_manager_(std::make_shared<io::http_session_manager>(id_, ctx_, tls_))
312
+ , session_manager_(std::make_shared<io::http_session_manager>(id_, ctx_, tls_, origin_))
306
313
  {
307
314
  }
308
315
  #endif
@@ -312,7 +319,7 @@ public:
312
319
  return ctx_;
313
320
  }
314
321
 
315
- void configure_tls_options(bool has_capella_host)
322
+ void configure_tls_options(bool has_capella_host, const std::shared_ptr<asio::ssl::context>& ctx)
316
323
  {
317
324
  asio::ssl::context::options tls_options =
318
325
  asio::ssl::context::default_workarounds | // various bug workarounds that should be rather
@@ -326,19 +333,19 @@ public:
326
333
  if (origin_.options().tls_disable_v1_2 || has_capella_host) {
327
334
  tls_options |= asio::ssl::context::no_tlsv1_2; // published: 2008, still in use
328
335
  }
329
- tls_.set_options(tls_options);
336
+ ctx->set_options(tls_options);
330
337
  switch (origin_.options().tls_verify) {
331
338
  case tls_verify_mode::none:
332
- tls_.set_verify_mode(asio::ssl::verify_none);
339
+ ctx->set_verify_mode(asio::ssl::verify_none);
333
340
  break;
334
341
 
335
342
  case tls_verify_mode::peer:
336
- tls_.set_verify_mode(asio::ssl::verify_peer);
343
+ ctx->set_verify_mode(asio::ssl::verify_peer);
337
344
  break;
338
345
  }
339
346
 
340
347
  #ifdef COUCHBASE_CXX_CLIENT_TLS_KEY_LOG_FILE
341
- SSL_CTX_set_keylog_callback(tls_.native_handle(), [](const SSL* /* ssl */, const char* line) {
348
+ SSL_CTX_set_keylog_callback(ctx->native_handle(), [](const SSL* /* ssl */, const char* line) {
342
349
  std::ofstream keylog(COUCHBASE_CXX_CLIENT_TLS_KEY_LOG_FILE,
343
350
  std::ios::out | std::ios::app | std::ios::binary);
344
351
  keylog << std::string_view(line) << std::endl;
@@ -351,6 +358,101 @@ public:
351
358
  #endif
352
359
  }
353
360
 
361
+ auto configure_tls_context(const std::shared_ptr<asio::ssl::context>& ctx) -> std::error_code
362
+ {
363
+ configure_tls_options(has_capella_host(), ctx);
364
+
365
+ if (origin_.options().trust_certificate.empty() &&
366
+ origin_.options().trust_certificate_value.empty()) {
367
+ // trust certificate is not explicitly specified
368
+ CB_LOG_DEBUG(R"([{}]: use default CA for TLS verify)", id_);
369
+ std::error_code ec{};
370
+
371
+ ctx->set_default_verify_paths(ec);
372
+ if (ec) {
373
+ CB_LOG_WARNING(R"([{}]: failed to load system CAs: {})", id_, ec.message());
374
+ }
375
+
376
+ ctx->add_certificate_authority(
377
+ asio::const_buffer(couchbase::core::default_ca::capellaCaCert,
378
+ strlen(couchbase::core::default_ca::capellaCaCert)),
379
+ ec);
380
+
381
+ if (ec) {
382
+ CB_LOG_WARNING("[{}]: unable to load default CAs: {}", id_, ec.message());
383
+ // we don't consider this fatal and try to continue without it
384
+ }
385
+
386
+ if (const auto certificates = default_ca::mozilla_ca_certs();
387
+ !origin_.options().disable_mozilla_ca_certificates && !certificates.empty()) {
388
+ CB_LOG_DEBUG("[{}]: loading {} CA certificates from Mozilla bundle. Update date: \"{}\", "
389
+ "SHA256: \"{}\"",
390
+ id_,
391
+ certificates.size(),
392
+ default_ca::mozilla_ca_certs_date(),
393
+ default_ca::mozilla_ca_certs_sha256());
394
+ for (const auto& cert : certificates) {
395
+ ctx->add_certificate_authority(asio::const_buffer(cert.body.data(), cert.body.size()),
396
+ ec);
397
+ if (ec) {
398
+ CB_LOG_WARNING("[{}]: unable to load CA \"{}\" from Mozilla bundle: {}",
399
+ id_,
400
+ cert.authority,
401
+ ec.message());
402
+ }
403
+ }
404
+ }
405
+ } else { // trust certificate is explicitly specified
406
+ std::error_code ec{};
407
+ // load only the explicit certificate
408
+ // system and default capella certificates are not loaded
409
+ if (!origin_.options().trust_certificate_value.empty()) {
410
+ CB_LOG_DEBUG(R"([{}]: use TLS certificate passed through via options object)", id_);
411
+ ctx->add_certificate_authority(
412
+ asio::const_buffer(origin_.options().trust_certificate_value.data(),
413
+ origin_.options().trust_certificate_value.size()),
414
+ ec);
415
+ if (ec) {
416
+ CB_LOG_WARNING(
417
+ "[{}]: unable to load CA passed via options object: {}", id_, ec.message());
418
+ }
419
+ }
420
+ if (!origin_.options().trust_certificate.empty()) {
421
+ CB_LOG_DEBUG(
422
+ R"([{}]: use TLS verify file: "{}")", id_, origin_.options().trust_certificate);
423
+ ctx->load_verify_file(origin_.options().trust_certificate, ec);
424
+ if (ec) {
425
+ CB_LOG_ERROR("[{}]: unable to load verify file \"{}\": {}",
426
+ id_,
427
+ origin_.options().trust_certificate,
428
+ ec.message());
429
+ return ec;
430
+ }
431
+ }
432
+ }
433
+ if (origin_.credentials().uses_certificate()) {
434
+ std::error_code ec{};
435
+ CB_LOG_DEBUG(R"([{}]: use TLS certificate chain: "{}")", id_, origin_.certificate_path());
436
+ ctx->use_certificate_chain_file(origin_.certificate_path(), ec);
437
+ if (ec) {
438
+ CB_LOG_ERROR("[{}]: unable to load certificate chain \"{}\": {}",
439
+ id_,
440
+ origin_.certificate_path(),
441
+ ec.message());
442
+ return ec;
443
+ }
444
+ CB_LOG_DEBUG(R"([{}]: use TLS private key: "{}")", id_, origin_.key_path());
445
+ ctx->use_private_key_file(origin_.key_path(), asio::ssl::context::file_format::pem, ec);
446
+ if (ec) {
447
+ CB_LOG_ERROR(
448
+ "[{}]: unable to load private key \"{}\": {}", id_, origin_.key_path(), ec.message());
449
+
450
+ return ec;
451
+ }
452
+ }
453
+ return {};
454
+ }
455
+
354
456
  void open(couchbase::core::origin origin,
355
457
  utils::movable_function<void(std::error_code)>&& handler)
356
458
  {
@@ -468,6 +570,7 @@ public:
468
570
  tls_,
469
571
  tracer_,
470
572
  meter_,
573
+ orphan_reporter_,
471
574
  app_telemetry_meter_,
472
575
  bucket_name,
473
576
  origin,
@@ -476,8 +579,7 @@ public:
476
579
  buckets_.try_emplace(bucket_name, b);
477
580
 
478
581
  // Register the tracer & the meter for config updates to track Cluster name & UUID
479
- b->on_configuration_update(tracer_);
480
- b->on_configuration_update(meter_);
582
+ b->on_configuration_update(cluster_label_listener_);
481
583
  b->on_configuration_update(app_telemetry_reporter_);
482
584
  }
483
585
  }
@@ -519,6 +621,50 @@ public:
519
621
  return handler({});
520
622
  }
521
623
 
624
+ auto update_credentials(const cluster_credentials& auth) -> core::error
625
+ {
626
+ if (stopped_) {
627
+ return { errc::network::cluster_closed, {} };
628
+ }
629
+
630
+ auto old_credentials = origin_.credentials();
631
+
632
+ if (!old_credentials.is_same_type(auth)) {
633
+ return { errc::common::invalid_argument,
634
+ "Cannot change authenticator type when updating credentials" };
635
+ }
636
+
637
+ origin_.update_credentials(auth);
638
+
639
+ // Separately update bucket and mcbp sessions as they have their own copies of the origin
640
+ for_each_bucket([&auth](const std::shared_ptr<bucket>& bucket) {
641
+ bucket->update_credentials(auth);
642
+ });
643
+ for_each_mcbp_session([&auth](auto& session) {
644
+ session.update_credentials(auth);
645
+ });
646
+
647
+ if (auth.requires_tls()) {
648
+ // Recreate and atomically swap the TLS context, existing sessions should continue to use the
649
+ // old one.
650
+ const auto new_ctx = std::make_shared<asio::ssl::context>(asio::ssl::context::tls_client);
651
+ auto ec = configure_tls_context(new_ctx);
652
+ if (ec) {
653
+ // Revert origin's credentials as these will not be synced to the active TLS context
654
+ origin_.update_credentials(old_credentials);
655
+ return { ec, {} };
656
+ }
657
+ tls_.set_ctx(new_ctx);
658
+ }
659
+
660
+ if (auth.uses_jwt()) {
661
+ for_each_mcbp_session([](auto& session) {
662
+ session.reauthenticate();
663
+ });
664
+ }
665
+ return {};
666
+ }
667
+
522
668
  auto origin() const -> std::pair<std::error_code, couchbase::core::origin>
523
669
  {
524
670
  if (stopped_) {
@@ -578,8 +724,7 @@ public:
578
724
  if constexpr (operations::is_compound_operation_v<Request>) {
579
725
  return request.execute(shared_from_this(), std::forward<Handler>(handler));
580
726
  } else {
581
- return session_manager_->execute(
582
- std::move(request), std::forward<Handler>(handler), origin_.credentials());
727
+ return session_manager_->execute(std::move(request), std::forward<Handler>(handler));
583
728
  }
584
729
  }
585
730
 
@@ -632,6 +777,19 @@ public:
632
777
  return bucket->second;
633
778
  }
634
779
 
780
+ void for_each_mcbp_session(utils::movable_function<void(io::mcbp_session&)> handler)
781
+ {
782
+ if (session_) {
783
+ handler(session_.value());
784
+ }
785
+
786
+ for_each_bucket([&handler](const std::shared_ptr<bucket>& bucket) {
787
+ bucket->for_each_session([&handler](io::mcbp_session& session) {
788
+ handler(session);
789
+ });
790
+ });
791
+ }
792
+
635
793
  void for_each_bucket(utils::movable_function<void(std::shared_ptr<bucket>)> handler)
636
794
  {
637
795
  std::vector<std::shared_ptr<bucket>> buckets{};
@@ -658,19 +816,8 @@ public:
658
816
  }
659
817
 
660
818
  // Warn users if they attempt to use Capella without TLS being enabled.
661
- bool has_capella_host = false;
662
819
  {
663
- bool has_non_capella_host = false;
664
- static const std::string suffix = "cloud.couchbase.com";
665
- for (const auto& node : origin_.get_hostnames()) {
666
- if (auto pos = node.find(suffix);
667
- pos != std::string::npos && pos + suffix.size() == node.size()) {
668
- has_capella_host = true;
669
- } else {
670
- has_non_capella_host = true;
671
- }
672
- }
673
-
820
+ auto has_capella_host = this->has_capella_host();
674
821
  if (has_capella_host && !origin_.options().enable_tls) {
675
822
  CB_LOG_WARNING("[{}]: TLS is required when connecting to Couchbase Capella. Please enable "
676
823
  "TLS by prefixing "
@@ -684,7 +831,7 @@ public:
684
831
  && origin_.options().trust_certificate_value.empty() /* and certificate value has not been specified */
685
832
  && origin_.options().tls_verify != tls_verify_mode::none /* The user did not disable all TLS verification */
686
833
  &&
687
- has_non_capella_host /* The connection string has a hostname that does NOT end in ".cloud.couchbase.com" */) {
834
+ !has_capella_host /* The connection string has a hostname that does NOT end in ".cloud.couchbase.com" */) {
688
835
  CB_LOG_WARNING("[{}] When TLS is enabled, the cluster options must specify certificate(s) "
689
836
  "to trust or ensure that they are "
690
837
  "available in system CA store. (Unless connecting to cloud.couchbase.com.)",
@@ -693,113 +840,16 @@ public:
693
840
  }
694
841
 
695
842
  if (origin_.options().enable_tls) {
696
- configure_tls_options(has_capella_host);
697
-
698
- if (origin_.options().trust_certificate.empty() &&
699
- origin_.options()
700
- .trust_certificate_value.empty()) { // trust certificate is not explicitly specified
701
- CB_LOG_DEBUG(R"([{}]: use default CA for TLS verify)", id_);
702
- std::error_code ec{};
703
-
704
- // load system certificates
705
- tls_.set_default_verify_paths(ec);
706
- if (ec) {
707
- CB_LOG_WARNING(R"([{}]: failed to load system CAs: {})", id_, ec.message());
708
- }
709
-
710
- // add the Capella Root CA in addition to system CAs
711
- tls_.add_certificate_authority(
712
- asio::const_buffer(couchbase::core::default_ca::capellaCaCert,
713
- strlen(couchbase::core::default_ca::capellaCaCert)),
714
- ec);
715
- if (ec) {
716
- CB_LOG_WARNING("[{}]: unable to load default CAs: {}", id_, ec.message());
717
- // we don't consider this fatal and try to continue without it
718
- }
719
-
720
- if (const auto certificates = default_ca::mozilla_ca_certs();
721
- !origin_.options().disable_mozilla_ca_certificates && !certificates.empty()) {
722
- CB_LOG_DEBUG("[{}]: loading {} CA certificates from Mozilla bundle. Update date: \"{}\", "
723
- "SHA256: \"{}\"",
724
- id_,
725
- certificates.size(),
726
- default_ca::mozilla_ca_certs_date(),
727
- default_ca::mozilla_ca_certs_sha256());
728
- for (const auto& cert : certificates) {
729
- tls_.add_certificate_authority(asio::const_buffer(cert.body.data(), cert.body.size()),
730
- ec);
731
- if (ec) {
732
- CB_LOG_WARNING("[{}]: unable to load CA \"{}\" from Mozilla bundle: {}",
733
- id_,
734
- cert.authority,
735
- ec.message());
736
- }
737
- }
738
- }
739
- } else { // trust certificate is explicitly specified
740
- std::error_code ec{};
741
- // load only the explicit certificate
742
- // system and default capella certificates are not loaded
743
- if (!origin_.options().trust_certificate_value.empty()) {
744
- CB_LOG_DEBUG(R"([{}]: use TLS certificate passed through via options object)", id_);
745
- tls_.add_certificate_authority(
746
- asio::const_buffer(origin_.options().trust_certificate_value.data(),
747
- origin_.options().trust_certificate_value.size()),
748
- ec);
749
- if (ec) {
750
- CB_LOG_WARNING(
751
- "[{}]: unable to load CA passed via options object: {}", id_, ec.message());
752
- }
753
- }
754
- if (!origin_.options().trust_certificate.empty()) {
755
- CB_LOG_DEBUG(
756
- R"([{}]: use TLS verify file: "{}")", id_, origin_.options().trust_certificate);
757
- tls_.load_verify_file(origin_.options().trust_certificate, ec);
758
- if (ec) {
759
- CB_LOG_ERROR("[{}]: unable to load verify file \"{}\": {}",
760
- id_,
761
- origin_.options().trust_certificate,
762
- ec.message());
763
- #ifdef __clang_analyzer__
764
- // TODO(CXXCBC-549): clang-tidy-19 reports potential memory leak here
765
- [[clang::suppress]]
766
- #endif
767
- return close([ec, handler = std::move(handler)]() mutable {
768
- return handler(ec);
769
- });
770
- }
771
- }
772
- }
773
- if (origin_.credentials().uses_certificate()) {
774
- std::error_code ec{};
775
- CB_LOG_DEBUG(R"([{}]: use TLS certificate chain: "{}")", id_, origin_.certificate_path());
776
- tls_.use_certificate_chain_file(origin_.certificate_path(), ec);
777
- if (ec) {
778
- CB_LOG_ERROR("[{}]: unable to load certificate chain \"{}\": {}",
779
- id_,
780
- origin_.certificate_path(),
781
- ec.message());
782
- #ifdef __clang_analyzer__
783
- // TODO(CXXCBC-549): clang-tidy-19 reports potential memory leak here
784
- [[clang::suppress]]
785
- #endif
786
- return close([ec, handler = std::move(handler)]() mutable {
787
- return handler(ec);
788
- });
789
- }
790
- CB_LOG_DEBUG(R"([{}]: use TLS private key: "{}")", id_, origin_.key_path());
791
- tls_.use_private_key_file(origin_.key_path(), asio::ssl::context::file_format::pem, ec);
792
- if (ec) {
793
- CB_LOG_ERROR(
794
- "[{}]: unable to load private key \"{}\": {}", id_, origin_.key_path(), ec.message());
843
+ const auto ctx = tls_.get_ctx();
844
+ auto ec = configure_tls_context(ctx);
845
+ if (ec) {
795
846
  #ifdef __clang_analyzer__
796
- // TODO(CXXCBC-549): clang-tidy-19 reports potential memory leak here
797
- [[clang::suppress]]
847
+ // TODO(CXXCBC-549): clang-tidy-19 reports potential memory leak here
848
+ [[clang::suppress]]
798
849
  #endif
799
- return close([ec, handler = std::move(handler)]() mutable {
800
- return handler(ec);
801
- });
802
- }
850
+ return close([ec, handler = std::move(handler)]() mutable {
851
+ return handler(ec);
852
+ });
803
853
  }
804
854
  session_ = io::mcbp_session(id_, {}, ctx_, tls_, origin_, dns_srv_tracker_);
805
855
  } else {
@@ -833,7 +883,9 @@ public:
833
883
  self->session_manager_->set_configuration(config, self->origin_.options());
834
884
  self->session_->on_configuration_update(self->session_manager_);
835
885
  self->session_->on_configuration_update(self->app_telemetry_reporter_);
886
+ self->session_->on_configuration_update(self->cluster_label_listener_);
836
887
  self->app_telemetry_reporter_->update_config(config);
888
+ self->cluster_label_listener_->update_config(config);
837
889
  self->session_->on_stop([self]() {
838
890
  if (self->session_) {
839
891
  self->session_.reset();
@@ -859,11 +911,12 @@ public:
859
911
  // TODO(JC): retries on more failures? Right now only retry if load_verify_file() fails...
860
912
 
861
913
  // Disables TLS v1.2 which should be okay cloud/columnar default.
862
- configure_tls_options(true);
914
+ auto ctx = tls_.get_ctx();
915
+ configure_tls_options(true, ctx);
863
916
  if (origin_.options().security_options.trust_only_capella) {
864
917
  std::error_code ec{};
865
918
  CB_LOG_DEBUG(R"([{}]: use Capella CA for TLS verify)", id_);
866
- tls_.add_certificate_authority(
919
+ ctx->add_certificate_authority(
867
920
  asio::const_buffer(couchbase::core::default_ca::capellaCaCert,
868
921
  strlen(couchbase::core::default_ca::capellaCaCert)),
869
922
  ec);
@@ -889,7 +942,7 @@ public:
889
942
  // system and default capella certificates are not loaded
890
943
  if (!origin_.options().trust_certificate_value.empty()) {
891
944
  CB_LOG_DEBUG(R"([{}]: use TLS certificate passed through via options object)", id_);
892
- tls_.add_certificate_authority(
945
+ ctx->add_certificate_authority(
893
946
  asio::const_buffer(origin_.options().trust_certificate_value.data(),
894
947
  origin_.options().trust_certificate_value.size()),
895
948
  ec);
@@ -901,7 +954,7 @@ public:
901
954
  if (!origin_.options().trust_certificate.empty()) {
902
955
  CB_LOG_DEBUG(
903
956
  R"([{}]: use TLS verify file: "{}")", id_, origin_.options().trust_certificate);
904
- tls_.load_verify_file(origin_.options().trust_certificate, ec);
957
+ ctx->load_verify_file(origin_.options().trust_certificate, ec);
905
958
  if (ec) {
906
959
  CB_LOG_ERROR("[{}]: unable to load verify file \"{}\": {}",
907
960
  id_,
@@ -920,7 +973,7 @@ public:
920
973
  CB_LOG_DEBUG(R"([{}]: use default CA for TLS verify)", id_);
921
974
  std::error_code ec{};
922
975
  // load system certificates
923
- tls_.set_default_verify_paths(ec);
976
+ ctx->set_default_verify_paths(ec);
924
977
  if (ec) {
925
978
  CB_LOG_WARNING(R"([{}]: failed to load system CAs: {})", id_, ec.message());
926
979
  }
@@ -930,7 +983,7 @@ public:
930
983
  id_,
931
984
  origin_.options().security_options.trust_only_certificates.size());
932
985
  for (const auto& cert : origin_.options().security_options.trust_only_certificates) {
933
- tls_.add_certificate_authority(asio::const_buffer(cert.data(), cert.size()), ec);
986
+ ctx->add_certificate_authority(asio::const_buffer(cert.data(), cert.size()), ec);
934
987
  if (ec) {
935
988
  CB_LOG_WARNING("[{}]: unable to load CA: {}", id_, ec.message());
936
989
  }
@@ -1098,8 +1151,7 @@ public:
1098
1151
  bucket->ping(collector, timeout);
1099
1152
  });
1100
1153
  }
1101
- cluster->session_manager_->ping(
1102
- services, timeout, collector, cluster->origin_.credentials());
1154
+ cluster->session_manager_->ping(services, timeout, collector);
1103
1155
  }
1104
1156
  }));
1105
1157
  }
@@ -1155,22 +1207,25 @@ public:
1155
1207
  for (const auto& [_, bucket] : buckets) {
1156
1208
  bucket->close();
1157
1209
  }
1158
- if (auto session_manager = std::move(self->session_manager_); session_manager) {
1210
+ if (const auto session_manager = std::move(self->session_manager_); session_manager) {
1159
1211
  session_manager->close();
1160
1212
  }
1161
1213
  self->work_.reset();
1162
- if (auto tracer = std::move(self->tracer_); tracer) {
1214
+ if (const auto tracer = std::move(self->tracer_); tracer) {
1163
1215
  tracer->stop();
1164
1216
  }
1165
- if (auto meter = std::move(self->meter_); meter) {
1217
+ if (const auto meter = std::move(self->meter_); meter) {
1166
1218
  meter->stop();
1167
1219
  }
1168
- if (auto meter = std::move(self->app_telemetry_meter_); meter) {
1220
+ if (const auto meter = std::move(self->app_telemetry_meter_); meter) {
1169
1221
  meter->disable();
1170
1222
  }
1171
- if (auto reporter = std::move(self->app_telemetry_reporter_); reporter) {
1223
+ if (const auto reporter = std::move(self->app_telemetry_reporter_); reporter) {
1172
1224
  reporter->stop();
1173
1225
  }
1226
+ if (const auto orphan_reporter = std::move(self->orphan_reporter_); orphan_reporter) {
1227
+ orphan_reporter->stop();
1228
+ }
1174
1229
  handler();
1175
1230
  }));
1176
1231
  }
@@ -1233,31 +1288,50 @@ public:
1233
1288
  return { {}, session_manager_ };
1234
1289
  }
1235
1290
 
1291
+ auto tracer() const -> const std::shared_ptr<tracing::tracer_wrapper>&
1292
+ {
1293
+ return tracer_;
1294
+ }
1295
+
1296
+ auto meter() const -> const std::shared_ptr<metrics::meter_wrapper>&
1297
+ {
1298
+ return meter_;
1299
+ }
1300
+
1301
+ auto cluster_label_listener() -> const std::shared_ptr<cluster_label_listener>&
1302
+ {
1303
+ return cluster_label_listener_;
1304
+ }
1305
+
1236
1306
  private:
1237
1307
  void setup_observability()
1238
1308
  {
1239
1309
  // ignore the enable_tracing flag if a tracer was passed in
1240
1310
  if (nullptr != origin_.options().tracer) {
1241
- tracer_ = tracing::tracer_wrapper::create(origin_.options().tracer);
1311
+ tracer_ = tracing::tracer_wrapper::create(origin_.options().tracer, cluster_label_listener_);
1242
1312
  } else {
1243
1313
  if (origin_.options().enable_tracing) {
1244
1314
  tracer_ =
1245
1315
  tracing::tracer_wrapper::create(std::make_shared<tracing::threshold_logging_tracer>(
1246
- ctx_, origin_.options().tracing_options));
1316
+ ctx_, origin_.options().tracing_options),
1317
+ cluster_label_listener_);
1247
1318
  } else {
1248
- tracer_ = tracing::tracer_wrapper::create(std::make_shared<tracing::noop_tracer>());
1319
+ tracer_ = tracing::tracer_wrapper::create(std::make_shared<tracing::noop_tracer>(),
1320
+ cluster_label_listener_);
1249
1321
  }
1250
1322
  }
1251
1323
  tracer_->start();
1252
1324
  // ignore the metrics options if a meter was passed in.
1253
1325
  if (nullptr != origin_.options().meter) {
1254
- meter_ = metrics::meter_wrapper::create(origin_.options().meter);
1326
+ meter_ = metrics::meter_wrapper::create(origin_.options().meter, cluster_label_listener_);
1255
1327
  } else {
1256
1328
  if (origin_.options().enable_metrics) {
1257
1329
  meter_ = metrics::meter_wrapper::create(
1258
- std::make_shared<metrics::logging_meter>(ctx_, origin_.options().metrics_options));
1330
+ std::make_shared<metrics::logging_meter>(ctx_, origin_.options().metrics_options),
1331
+ cluster_label_listener_);
1259
1332
  } else {
1260
- meter_ = metrics::meter_wrapper::create(std::make_shared<metrics::noop_meter>());
1333
+ meter_ = metrics::meter_wrapper::create(std::make_shared<metrics::noop_meter>(),
1334
+ cluster_label_listener_);
1261
1335
  }
1262
1336
  }
1263
1337
  meter_->start();
@@ -1267,14 +1341,32 @@ private:
1267
1341
 
1268
1342
  app_telemetry_meter_->update_agent(origin_.options().user_agent_extra);
1269
1343
  session_manager_->set_app_telemetry_meter(app_telemetry_meter_);
1270
- app_telemetry_reporter_ = std::make_shared<app_telemetry_reporter>(
1271
- app_telemetry_meter_, origin_.options(), origin_.credentials(), ctx_, tls_);
1344
+ app_telemetry_reporter_ =
1345
+ std::make_shared<app_telemetry_reporter>(app_telemetry_meter_, origin_, ctx_, tls_);
1346
+
1347
+ if (origin_.options().enable_orphan_reporting) {
1348
+ orphan_reporter_ = std::make_shared<orphan_reporter>(ctx_, origin_.options().orphan_options);
1349
+ orphan_reporter_->start();
1350
+ }
1351
+ }
1352
+
1353
+ auto has_capella_host() const -> bool
1354
+ {
1355
+ bool has_capella_host = false;
1356
+ static const std::string suffix = "cloud.couchbase.com";
1357
+ for (const auto& node : origin_.get_hostnames()) {
1358
+ if (auto pos = node.find(suffix);
1359
+ pos != std::string::npos && pos + suffix.size() == node.size()) {
1360
+ has_capella_host = true;
1361
+ }
1362
+ }
1363
+ return has_capella_host;
1272
1364
  }
1273
1365
 
1274
1366
  std::string id_{ uuid::to_string(uuid::random()) };
1275
1367
  asio::io_context& ctx_;
1276
1368
  asio::executor_work_guard<asio::io_context::executor_type> work_;
1277
- asio::ssl::context tls_{ asio::ssl::context::tls_client };
1369
+ tls_context_provider tls_{};
1278
1370
  std::shared_ptr<io::http_session_manager> session_manager_;
1279
1371
  std::shared_ptr<app_telemetry_reporter> app_telemetry_reporter_{};
1280
1372
  std::optional<io::mcbp_session> session_{};
@@ -1282,8 +1374,12 @@ private:
1282
1374
  std::mutex buckets_mutex_{};
1283
1375
  std::map<std::string, std::shared_ptr<bucket>> buckets_{};
1284
1376
  couchbase::core::origin origin_{};
1377
+ std::shared_ptr<class cluster_label_listener> cluster_label_listener_{
1378
+ std::make_shared<class cluster_label_listener>()
1379
+ };
1285
1380
  std::shared_ptr<tracing::tracer_wrapper> tracer_{ nullptr };
1286
1381
  std::shared_ptr<metrics::meter_wrapper> meter_{ nullptr };
1382
+ std::shared_ptr<orphan_reporter> orphan_reporter_{ nullptr };
1287
1383
  std::atomic_bool stopped_{ false };
1288
1384
  std::shared_ptr<core::app_telemetry_meter> app_telemetry_meter_{
1289
1385
  std::make_shared<core::app_telemetry_meter>()
@@ -1417,6 +1513,15 @@ cluster::origin() const -> std::pair<std::error_code, couchbase::core::origin>
1417
1513
  return { errc::network::cluster_closed, {} };
1418
1514
  }
1419
1515
 
1516
+ auto
1517
+ cluster::update_credentials(const core::cluster_credentials& auth) const -> core::error
1518
+ {
1519
+ if (impl_) {
1520
+ return impl_->update_credentials(auth);
1521
+ }
1522
+ return { errc::network::cluster_closed, {} };
1523
+ }
1524
+
1420
1525
  auto
1421
1526
  cluster::io_context() const -> asio::io_context&
1422
1527
  {
@@ -2376,6 +2481,34 @@ cluster::execute(impl::lookup_in_replica_request request,
2376
2481
  return impl_->execute(std::move(request), std::move(handler));
2377
2482
  }
2378
2483
 
2484
+ void
2485
+ cluster::execute(operations::lookup_in_replica_request_with_cancellation request,
2486
+ utils::movable_function<void(impl::lookup_in_replica_response)>&& handler) const
2487
+ {
2488
+ return impl_->execute(std::move(request), std::move(handler));
2489
+ }
2490
+
2491
+ void
2492
+ cluster::execute(operations::lookup_in_request_with_cancellation request,
2493
+ utils::movable_function<void(operations::lookup_in_response)>&& handler) const
2494
+ {
2495
+ return impl_->execute(std::move(request), std::move(handler));
2496
+ }
2497
+
2498
+ void
2499
+ cluster::execute(operations::get_replica_request_with_cancellation request,
2500
+ utils::movable_function<void(impl::get_replica_response)>&& handler) const
2501
+ {
2502
+ return impl_->execute(std::move(request), std::move(handler));
2503
+ }
2504
+
2505
+ void
2506
+ cluster::execute(operations::get_request_with_cancellation request,
2507
+ utils::movable_function<void(operations::get_response)>&& handler) const
2508
+ {
2509
+ return impl_->execute(std::move(request), std::move(handler));
2510
+ }
2511
+
2379
2512
  auto
2380
2513
  cluster::http_session_manager() const
2381
2514
  -> std::pair<std::error_code, std::shared_ptr<io::http_session_manager>>
@@ -2391,4 +2524,23 @@ cluster::to_string() const -> std::string
2391
2524
  impl_ ? static_cast<const void*>(impl_.get()) : "(none)",
2392
2525
  impl_ ? std::to_string(impl_.use_count()) : "(none)");
2393
2526
  }
2527
+
2528
+ auto
2529
+ cluster::tracer() const -> const std::shared_ptr<tracing::tracer_wrapper>&
2530
+ {
2531
+ return impl_->tracer();
2532
+ }
2533
+
2534
+ auto
2535
+ cluster::meter() const -> const std::shared_ptr<metrics::meter_wrapper>&
2536
+ {
2537
+ return impl_->meter();
2538
+ }
2539
+
2540
+ auto
2541
+ cluster::cluster_label_listener() const -> const std::shared_ptr<core::cluster_label_listener>&
2542
+ {
2543
+ return impl_->cluster_label_listener();
2544
+ }
2545
+
2394
2546
  } // namespace couchbase::core