couchbase 4.2.5 → 4.2.6-dev

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. package/deps/couchbase-cxx-client/CMakeLists.txt +9 -1
  2. package/deps/couchbase-cxx-client/bin/api.rb +234 -0
  3. package/deps/couchbase-cxx-client/bin/create-search-index +18 -135
  4. package/deps/couchbase-cxx-client/bin/init-cluster +17 -139
  5. package/deps/couchbase-cxx-client/bin/load-sample-buckets +54 -0
  6. package/deps/couchbase-cxx-client/core/cluster.hxx +33 -12
  7. package/deps/couchbase-cxx-client/core/cluster_options.hxx +3 -0
  8. package/deps/couchbase-cxx-client/core/crud_component.cxx +51 -22
  9. package/deps/couchbase-cxx-client/core/impl/build_deferred_query_indexes.cxx +115 -50
  10. package/deps/couchbase-cxx-client/core/impl/cluster.cxx +6 -0
  11. package/deps/couchbase-cxx-client/core/impl/create_bucket.cxx +155 -0
  12. package/deps/couchbase-cxx-client/core/impl/create_query_index.cxx +172 -59
  13. package/deps/couchbase-cxx-client/core/impl/dns_srv_tracker.cxx +2 -1
  14. package/deps/couchbase-cxx-client/core/impl/drop_bucket.cxx +66 -0
  15. package/deps/couchbase-cxx-client/core/impl/drop_query_index.cxx +138 -59
  16. package/deps/couchbase-cxx-client/core/impl/flush_bucket.cxx +66 -0
  17. package/deps/couchbase-cxx-client/core/impl/get_all_buckets.cxx +163 -0
  18. package/deps/couchbase-cxx-client/core/impl/get_all_query_indexes.cxx +67 -37
  19. package/deps/couchbase-cxx-client/core/impl/get_bucket.cxx +153 -0
  20. package/deps/couchbase-cxx-client/core/impl/internal_manager_error_context.cxx +113 -0
  21. package/deps/couchbase-cxx-client/core/impl/internal_manager_error_context.hxx +60 -0
  22. package/deps/couchbase-cxx-client/core/impl/key_value_error_category.cxx +2 -4
  23. package/deps/couchbase-cxx-client/core/impl/manager_error_context.cxx +100 -0
  24. package/deps/couchbase-cxx-client/core/impl/query.cxx +1 -0
  25. package/deps/couchbase-cxx-client/core/impl/update_bucket.cxx +130 -0
  26. package/deps/couchbase-cxx-client/core/impl/watch_query_indexes.cxx +53 -29
  27. package/deps/couchbase-cxx-client/core/io/dns_client.cxx +71 -38
  28. package/deps/couchbase-cxx-client/core/io/dns_config.cxx +5 -4
  29. package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +5 -6
  30. package/deps/couchbase-cxx-client/core/meta/features.hxx +6 -0
  31. package/deps/couchbase-cxx-client/core/operations/document_query.cxx +11 -0
  32. package/deps/couchbase-cxx-client/core/operations/document_query.hxx +1 -0
  33. package/deps/couchbase-cxx-client/core/origin.cxx +270 -0
  34. package/deps/couchbase-cxx-client/core/origin.hxx +2 -0
  35. package/deps/couchbase-cxx-client/core/protocol/status.cxx +2 -2
  36. package/deps/couchbase-cxx-client/core/range_scan_options.cxx +3 -27
  37. package/deps/couchbase-cxx-client/core/range_scan_options.hxx +13 -17
  38. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.cxx +367 -170
  39. package/deps/couchbase-cxx-client/core/range_scan_orchestrator.hxx +13 -2
  40. package/deps/couchbase-cxx-client/core/range_scan_orchestrator_options.hxx +5 -3
  41. package/deps/couchbase-cxx-client/core/scan_options.hxx +0 -19
  42. package/deps/couchbase-cxx-client/core/scan_result.cxx +19 -5
  43. package/deps/couchbase-cxx-client/core/scan_result.hxx +5 -2
  44. package/deps/couchbase-cxx-client/core/timeout_defaults.hxx +2 -3
  45. package/deps/couchbase-cxx-client/core/topology/capabilities.hxx +1 -0
  46. package/deps/couchbase-cxx-client/core/topology/capabilities_fmt.hxx +2 -0
  47. package/deps/couchbase-cxx-client/core/topology/collections_manifest_fmt.hxx +1 -1
  48. package/deps/couchbase-cxx-client/core/topology/configuration.hxx +5 -0
  49. package/deps/couchbase-cxx-client/core/topology/configuration_json.hxx +2 -0
  50. package/deps/couchbase-cxx-client/core/utils/connection_string.cxx +4 -0
  51. package/deps/couchbase-cxx-client/couchbase/behavior_options.hxx +19 -2
  52. package/deps/couchbase-cxx-client/couchbase/bucket_manager.hxx +135 -0
  53. package/deps/couchbase-cxx-client/couchbase/build_query_index_options.hxx +0 -30
  54. package/deps/couchbase-cxx-client/couchbase/cluster.hxx +14 -0
  55. package/deps/couchbase-cxx-client/couchbase/collection_query_index_manager.hxx +7 -48
  56. package/deps/couchbase-cxx-client/couchbase/create_bucket_options.hxx +41 -0
  57. package/deps/couchbase-cxx-client/couchbase/create_primary_query_index_options.hxx +0 -29
  58. package/deps/couchbase-cxx-client/couchbase/create_query_index_options.hxx +0 -33
  59. package/deps/couchbase-cxx-client/couchbase/drop_bucket_options.hxx +41 -0
  60. package/deps/couchbase-cxx-client/couchbase/drop_primary_query_index_options.hxx +0 -30
  61. package/deps/couchbase-cxx-client/couchbase/drop_query_index_options.hxx +0 -31
  62. package/deps/couchbase-cxx-client/couchbase/error_codes.hxx +1 -2
  63. package/deps/couchbase-cxx-client/couchbase/flush_bucket_options.hxx +41 -0
  64. package/deps/couchbase-cxx-client/couchbase/get_all_buckets_options.hxx +44 -0
  65. package/deps/couchbase-cxx-client/couchbase/get_all_query_indexes_options.hxx +0 -30
  66. package/deps/couchbase-cxx-client/couchbase/get_bucket_options.hxx +43 -0
  67. package/deps/couchbase-cxx-client/couchbase/management/bucket_settings.hxx +116 -0
  68. package/deps/couchbase-cxx-client/couchbase/manager_error_context.hxx +29 -53
  69. package/deps/couchbase-cxx-client/couchbase/query_index_manager.hxx +16 -83
  70. package/deps/couchbase-cxx-client/couchbase/query_options.hxx +18 -0
  71. package/deps/couchbase-cxx-client/couchbase/security_options.hxx +15 -0
  72. package/deps/couchbase-cxx-client/couchbase/update_bucket_options.hxx +41 -0
  73. package/deps/couchbase-cxx-client/couchbase/watch_query_indexes_options.hxx +0 -31
  74. package/deps/couchbase-cxx-client/docs/cbc-analytics.md +1 -0
  75. package/deps/couchbase-cxx-client/docs/cbc-get.md +1 -0
  76. package/deps/couchbase-cxx-client/docs/cbc-pillowfight.md +1 -0
  77. package/deps/couchbase-cxx-client/docs/cbc-query.md +1 -0
  78. package/deps/couchbase-cxx-client/docs/cbc.md +10 -0
  79. package/deps/couchbase-cxx-client/test/CMakeLists.txt +1 -0
  80. package/deps/couchbase-cxx-client/test/test_integration_collections.cxx +6 -0
  81. package/deps/couchbase-cxx-client/test/test_integration_crud.cxx +5 -0
  82. package/deps/couchbase-cxx-client/test/test_integration_examples.cxx +137 -1
  83. package/deps/couchbase-cxx-client/test/test_integration_management.cxx +709 -266
  84. package/deps/couchbase-cxx-client/test/test_integration_query.cxx +19 -7
  85. package/deps/couchbase-cxx-client/test/test_integration_range_scan.cxx +351 -112
  86. package/deps/couchbase-cxx-client/test/test_integration_search.cxx +10 -1
  87. package/deps/couchbase-cxx-client/test/test_transaction_public_async_api.cxx +13 -12
  88. package/deps/couchbase-cxx-client/test/test_transaction_public_blocking_api.cxx +27 -21
  89. package/deps/couchbase-cxx-client/test/test_unit_query.cxx +75 -0
  90. package/deps/couchbase-cxx-client/test/utils/server_version.hxx +5 -0
  91. package/deps/couchbase-cxx-client/test/utils/wait_until.cxx +29 -10
  92. package/deps/couchbase-cxx-client/test/utils/wait_until.hxx +3 -1
  93. package/deps/couchbase-cxx-client/tools/utils.cxx +4 -1
  94. package/dist/binding.d.ts +21 -16
  95. package/dist/binding.js +1 -4
  96. package/dist/bindingutilities.d.ts +6 -1
  97. package/dist/bindingutilities.js +36 -1
  98. package/dist/collection.d.ts +65 -3
  99. package/dist/collection.js +107 -0
  100. package/dist/crudoptypes.d.ts +34 -0
  101. package/dist/crudoptypes.js +18 -1
  102. package/dist/queryexecutor.js +1 -0
  103. package/dist/querytypes.d.ts +7 -0
  104. package/dist/rangeScan.d.ts +107 -0
  105. package/dist/rangeScan.js +91 -0
  106. package/dist/streamablepromises.d.ts +6 -0
  107. package/dist/streamablepromises.js +25 -1
  108. package/package.json +12 -13
  109. package/src/addondata.hpp +1 -0
  110. package/src/binding.cpp +5 -2
  111. package/src/connection.cpp +108 -2
  112. package/src/connection.hpp +1 -0
  113. package/src/constants.cpp +2 -12
  114. package/src/jstocbpp_autogen.hpp +49 -22
  115. package/src/jstocbpp_basic.hpp +2 -8
  116. package/src/mutationtoken.cpp +13 -0
  117. package/src/scan_iterator.cpp +90 -0
  118. package/src/scan_iterator.hpp +30 -0
  119. package/tools/gen-bindings-json.py +9 -8
  120. package/deps/couchbase-cxx-client/core/impl/collection_query_index_manager.cxx +0 -93
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
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
+ require "timeout"
18
+ require "set"
19
+
20
+ require_relative "api"
21
+
22
+ options = {
23
+ host: ENV.fetch("CB_HOST", ARGV[0] || "127.0.0.1"),
24
+ strict_encryption: ENV.fetch("CB_STRICT_ENCRYPTION", ARGV[1]).to_b,
25
+ username: ENV.fetch("CB_USERNAME", ARGV[2] || "Administrator"),
26
+ password: ENV.fetch("CB_PASSWORD", ARGV[3] || "password"),
27
+ verbose: ENV.fetch("CB_VERBOSE", true).to_b,
28
+ bucket: "travel-sample",
29
+ sample_buckets: Set.new,
30
+ }
31
+ options[:sample_buckets] << "beer-sample" if ENV.fetch("CB_BEER_SAMPLE", false).to_b
32
+ options[:sample_buckets] << "travel-sample" if ENV.fetch("CB_TRAVEL_SAMPLE", false).to_b
33
+ options[:sample_buckets] |= ARGV[4..-1]
34
+ return if options[:sample_buckets].empty?
35
+
36
+ p options: options
37
+
38
+ management_api =
39
+ begin
40
+ API.new(options.merge(port: options[:strict_encryption] ? 18091 : 8091))
41
+ rescue => ex
42
+ puts "#{ex}, sleep for 1 second and retry"
43
+ sleep(1)
44
+ retry
45
+ end
46
+
47
+ expected_counts = {
48
+ "travel-sample" => 30_000,
49
+ "beer-sample" => 7_000,
50
+ }
51
+
52
+ options[:sample_buckets].each do |bucket|
53
+ ensure_sample_bucket_loaded(management_api, expected_counts[bucket], options.merge(bucket: bucket))
54
+ end
@@ -79,6 +79,7 @@ class cluster : public std::enable_shared_from_this<cluster>
79
79
  }
80
80
 
81
81
  origin_ = std::move(origin);
82
+ CB_LOG_DEBUG(R"(open cluster, id: "{}", core version: "{}", {})", id_, couchbase::core::meta::sdk_semver(), origin_.to_json());
82
83
  // ignore the enable_tracing flag if a tracer was passed in
83
84
  if (nullptr != origin_.options().tracer) {
84
85
  tracer_ = origin_.options().tracer;
@@ -111,10 +112,7 @@ class cluster : public std::enable_shared_from_this<cluster>
111
112
  return self->dns_srv_tracker_->get_srv_nodes(
112
113
  [self, hostname = std::move(hostname), handler = std::forward<Handler>(handler)](origin::node_list nodes,
113
114
  std::error_code ec) mutable {
114
- if (ec) {
115
- return self->close([ec, handler = std::forward<Handler>(handler)]() mutable { handler(ec); });
116
- }
117
- if (!nodes.empty()) {
115
+ if (!ec && !nodes.empty()) {
118
116
  self->origin_.set_nodes(std::move(nodes));
119
117
  CB_LOG_INFO("replace list of bootstrap nodes with addresses from DNS SRV of \"{}\": [{}]",
120
118
  hostname,
@@ -339,8 +337,8 @@ class cluster : public std::enable_shared_from_this<cluster>
339
337
  void do_open(Handler&& handler)
340
338
  {
341
339
  // Warn users if they attempt to use Capella without TLS being enabled.
340
+ bool has_capella_host = false;
342
341
  {
343
- bool has_capella_host = false;
344
342
  bool has_non_capella_host = false;
345
343
  static std::string suffix = "cloud.couchbase.com";
346
344
  for (const auto& node : origin_.get_hostnames()) {
@@ -359,6 +357,7 @@ class cluster : public std::enable_shared_from_this<cluster>
359
357
 
360
358
  if (origin_.options().enable_tls /* TLS is enabled */
361
359
  && origin_.options().trust_certificate.empty() /* No CA certificate (or other SDK-specific trust source) is specified */
360
+ && origin_.options().trust_certificate_value.empty() /* and certificate value has not been specified */
362
361
  && origin_.options().tls_verify != tls_verify_mode::none /* The user did not disable all TLS verification */
363
362
  && has_non_capella_host /* The connection string has a hostname that does NOT end in ".cloud.couchbase.com" */) {
364
363
  CB_LOG_WARNING("[{}] When TLS is enabled, the cluster options must specify certificate(s) to trust or ensure that they are "
@@ -368,7 +367,17 @@ class cluster : public std::enable_shared_from_this<cluster>
368
367
  }
369
368
 
370
369
  if (origin_.options().enable_tls) {
371
- tls_.set_options(asio::ssl::context::default_workarounds | asio::ssl::context::no_sslv2 | asio::ssl::context::no_sslv3);
370
+ long tls_options = asio::ssl::context::default_workarounds | // various bug workarounds that should be rather harmless
371
+ asio::ssl::context::no_sslv2 | // published: 1995, deprecated: 2011
372
+ asio::ssl::context::no_sslv3; // published: 1996, deprecated: 2015
373
+ if (origin_.options().tls_disable_deprecated_protocols) {
374
+ tls_options |= asio::ssl::context::no_tlsv1 | // published: 1999, deprecated: 2021
375
+ asio::ssl::context::no_tlsv1_1; // published: 2006, deprecated: 2021
376
+ }
377
+ if (origin_.options().tls_disable_v1_2 || has_capella_host) {
378
+ tls_options |= asio::ssl::context::no_tlsv1_2; // published: 2008, still in use
379
+ }
380
+ tls_.set_options(tls_options);
372
381
  switch (origin_.options().tls_verify) {
373
382
  case tls_verify_mode::none:
374
383
  tls_.set_verify_mode(asio::ssl::verify_none);
@@ -378,7 +387,8 @@ class cluster : public std::enable_shared_from_this<cluster>
378
387
  tls_.set_verify_mode(asio::ssl::verify_peer);
379
388
  break;
380
389
  }
381
- if (origin_.options().trust_certificate.empty()) { // trust certificate is not explicitly specified
390
+ if (origin_.options().trust_certificate.empty() &&
391
+ origin_.options().trust_certificate_value.empty()) { // trust certificate is not explicitly specified
382
392
  CB_LOG_DEBUG(R"([{}]: use default CA for TLS verify)", id_);
383
393
  std::error_code ec{};
384
394
 
@@ -414,11 +424,22 @@ class cluster : public std::enable_shared_from_this<cluster>
414
424
  std::error_code ec{};
415
425
  // load only the explicit certificate
416
426
  // system and default capella certificates are not loaded
417
- CB_LOG_DEBUG(R"([{}]: use TLS verify file: "{}")", id_, origin_.options().trust_certificate);
418
- tls_.load_verify_file(origin_.options().trust_certificate, ec);
419
- if (ec) {
420
- CB_LOG_ERROR("[{}]: unable to load verify file \"{}\": {}", id_, origin_.options().trust_certificate, ec.message());
421
- return close([ec, handler = std::forward<Handler>(handler)]() mutable { return handler(ec); });
427
+ if (!origin_.options().trust_certificate_value.empty()) {
428
+ CB_LOG_DEBUG(R"([{}]: use TLS certificate passed through via options object)", id_);
429
+ tls_.add_certificate_authority(asio::const_buffer(origin_.options().trust_certificate_value.data(),
430
+ origin_.options().trust_certificate_value.size()),
431
+ ec);
432
+ if (ec) {
433
+ CB_LOG_WARNING("[{}]: unable to load CA passed via options object: {}", id_, ec.message());
434
+ }
435
+ }
436
+ if (!origin_.options().trust_certificate.empty()) {
437
+ CB_LOG_DEBUG(R"([{}]: use TLS verify file: "{}")", id_, origin_.options().trust_certificate);
438
+ tls_.load_verify_file(origin_.options().trust_certificate, ec);
439
+ if (ec) {
440
+ CB_LOG_ERROR("[{}]: unable to load verify file \"{}\": {}", id_, origin_.options().trust_certificate, ec.message());
441
+ return close([ec, handler = std::forward<Handler>(handler)]() mutable { return handler(ec); });
442
+ }
422
443
  }
423
444
  }
424
445
  #ifdef COUCHBASE_CXX_CLIENT_TLS_KEY_LOG_FILE
@@ -50,7 +50,10 @@ struct cluster_options {
50
50
  std::chrono::milliseconds management_timeout = timeout_defaults::management_timeout;
51
51
 
52
52
  bool enable_tls{ false };
53
+ bool tls_disable_deprecated_protocols{ true };
54
+ bool tls_disable_v1_2{ false };
53
55
  std::string trust_certificate{};
56
+ std::string trust_certificate_value{};
54
57
  bool enable_mutation_tokens{ true };
55
58
  bool enable_tcp_keep_alive{ true };
56
59
  io::ip_protocol use_ip_protocol{ io::ip_protocol::any };
@@ -1,6 +1,6 @@
1
1
  /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
2
  /*
3
- * Copyright 2020-2021 Couchbase, Inc.
3
+ * Copyright 2020-2023 Couchbase, Inc.
4
4
  *
5
5
  * Licensed under the Apache License, Version 2.0 (the "License");
6
6
  * you may not use this file except in compliance with the License.
@@ -39,6 +39,8 @@
39
39
 
40
40
  #include <tl/expected.hpp>
41
41
 
42
+ #include <random>
43
+
42
44
  namespace couchbase::core
43
45
  {
44
46
  static std::pair<std::vector<std::byte>, std::error_code>
@@ -53,17 +55,40 @@ serialize_range_scan_create_options(const range_scan_create_options& options)
53
55
  body["collection"] = fmt::format("{:x}", options.collection_id);
54
56
  }
55
57
 
56
- if (std::holds_alternative<range_scan>(options.scan_type)) {
57
- const auto& range = std::get<range_scan>(options.scan_type);
58
+ if (std::holds_alternative<range_scan>(options.scan_type) || std::holds_alternative<prefix_scan>(options.scan_type)) {
59
+ const auto& range = (std::holds_alternative<range_scan>(options.scan_type))
60
+ ? std::get<range_scan>(options.scan_type)
61
+ : std::get<prefix_scan>(options.scan_type).to_range_scan();
62
+
63
+ const auto& from = range.from.value_or(scan_term{ "" });
64
+ const auto& to = range.to.value_or(scan_term{ "\xf4\x8f\xfb\xfb" });
65
+
58
66
  body["range"] = {
59
- { range.start_.exclusive ? "excl_start" : "start", base64::encode(range.start_.id) },
60
- { range.end_.exclusive ? "excl_end" : "end", base64::encode(range.end_.id) },
67
+ { from.exclusive ? "excl_start" : "start", base64::encode(from.term) },
68
+ { to.exclusive ? "excl_end" : "end", base64::encode(to.term) },
61
69
  };
62
70
  } else if (std::holds_alternative<sampling_scan>(options.scan_type)) {
63
71
  const auto& sampling = std::get<sampling_scan>(options.scan_type);
72
+
73
+ // The limit in sampling scan is required to be greater than 0
74
+ if (sampling.limit <= 0) {
75
+ return { {}, errc::common::invalid_argument };
76
+ }
77
+
78
+ std::uint64_t seed{};
79
+ if (sampling.seed.has_value()) {
80
+ seed = sampling.seed.value();
81
+ } else {
82
+ // Generate random uint64 as seed
83
+ std::random_device rd;
84
+ std::mt19937_64 gen(rd());
85
+ std::uniform_int_distribution<std::uint64_t> dis;
86
+ seed = dis(gen);
87
+ }
88
+
64
89
  body["sampling"] = {
65
90
  { "samples", sampling.limit },
66
- { "seed", sampling.seed.value_or(0) },
91
+ { "seed", seed },
67
92
  };
68
93
  } else {
69
94
  return { {}, errc::common::invalid_argument };
@@ -75,7 +100,7 @@ serialize_range_scan_create_options(const range_scan_create_options& options)
75
100
  { "vb_uuid", std::to_string(snapshot.vbucket_uuid) },
76
101
  { "seqno", snapshot.sequence_number },
77
102
  { "timeout_ms",
78
- (options.timeout == std::chrono::milliseconds::zero()) ? timeout_defaults::range_scan_timeout.count()
103
+ (options.timeout == std::chrono::milliseconds::zero()) ? timeout_defaults::key_value_scan_timeout.count()
79
104
  : options.timeout.count() },
80
105
  };
81
106
  if (snapshot.sequence_number_exists) {
@@ -98,7 +123,7 @@ parse_range_scan_keys(gsl::span<std::byte> data, range_scan_item_callback&& item
98
123
  if (remaining.size() < key_length) {
99
124
  return errc::network::protocol_error;
100
125
  }
101
- item_callback(range_scan_item{ { remaining.begin(), remaining.begin() + static_cast<std::ptrdiff_t>(key_length) } });
126
+ item_callback(range_scan_item{ { reinterpret_cast<const char*>(remaining.data()), key_length } });
102
127
  if (remaining.size() == key_length) {
103
128
  return {};
104
129
  }
@@ -130,13 +155,13 @@ parse_range_scan_documents(gsl::span<std::byte> data, range_scan_item_callback&&
130
155
  body.datatype = data[24];
131
156
  data = gsl::make_span(data.data() + header_offset, data.size() - header_offset);
132
157
 
133
- std::vector<std::byte> key{};
158
+ std::string key{};
134
159
  {
135
160
  auto [key_length, remaining] = utils::decode_unsigned_leb128<std::size_t>(data, core::utils::leb_128_no_throw{});
136
161
  if (remaining.size() < key_length) {
137
162
  return errc::network::protocol_error;
138
163
  }
139
- key = { remaining.begin(), remaining.begin() + static_cast<std::ptrdiff_t>(key_length) };
164
+ key = { reinterpret_cast<const char*>(remaining.data()), key_length };
140
165
  data = gsl::make_span(remaining.data() + key_length, remaining.size() - key_length);
141
166
  }
142
167
 
@@ -242,19 +267,10 @@ class crud_component_impl
242
267
  if (error) {
243
268
  return cb({}, error);
244
269
  }
245
- bool ids_only;
246
- switch (response->extras_.size()) {
247
- case 4:
248
- ids_only = mcbp::big_endian::read_uint32(response->extras_, 0) == 0;
249
- break;
250
-
251
- case 0:
252
- ids_only = options.ids_only; // support servers before MB-54267. TODO: remove after server GA
253
- break;
254
-
255
- default:
256
- return cb({}, errc::network::protocol_error);
270
+ if (response->extras_.size() != 4) {
271
+ return cb({}, errc::network::protocol_error);
257
272
  }
273
+ bool ids_only = mcbp::big_endian::read_uint32(response->extras_, 0) == 0;
258
274
 
259
275
  if (auto ec = parse_range_scan_data(response->value_, std::move(item_cb), ids_only); ec) {
260
276
  return cb({}, ec);
@@ -276,6 +292,19 @@ class crud_component_impl
276
292
 
277
293
  req->persistent_ = true;
278
294
  req->vbucket_ = vbucket_id;
295
+
296
+ if (options.timeout != std::chrono::milliseconds::zero()) {
297
+ auto timer = std::make_shared<asio::steady_timer>(io_);
298
+ timer->expires_after(options.timeout);
299
+ timer->async_wait([req](auto error) {
300
+ if (error == asio::error::operation_aborted) {
301
+ return;
302
+ }
303
+ req->cancel(couchbase::errc::common::unambiguous_timeout);
304
+ });
305
+ req->set_deadline(timer);
306
+ }
307
+
279
308
  mcbp::buffer_writer buf{ scan_uuid.size() + sizeof(std::uint32_t) * 3 };
280
309
  buf.write(scan_uuid);
281
310
  buf.write_uint32(options.batch_item_limit);
@@ -20,44 +20,116 @@
20
20
 
21
21
  #include "core/cluster.hxx"
22
22
  #include "core/operations/management/query_index_build.hxx"
23
- #include "core/operations/management/query_index_get_all_deferred.hxx"
24
- #include "core/utils/json.hxx"
23
+ #include "core/operations/management/query_index_build_deferred.hxx"
25
24
 
26
- namespace couchbase::core::impl
25
+ namespace couchbase
27
26
  {
28
27
  template<typename Response>
29
28
  static manager_error_context
30
29
  build_context(Response& resp)
31
30
  {
32
- return { resp.ctx.ec,
33
- resp.ctx.last_dispatched_to,
34
- resp.ctx.last_dispatched_from,
35
- resp.ctx.retry_attempts,
36
- std::move(resp.ctx.retry_reasons),
37
- std::move(resp.ctx.client_context_id),
38
- resp.ctx.http_status,
39
- std::move(resp.ctx.http_body),
40
- std::move(resp.ctx.path) };
31
+ return manager_error_context(internal_manager_error_context{ resp.ctx.ec,
32
+ resp.ctx.last_dispatched_to,
33
+ resp.ctx.last_dispatched_from,
34
+ resp.ctx.retry_attempts,
35
+ std::move(resp.ctx.retry_reasons),
36
+ std::move(resp.ctx.client_context_id),
37
+ resp.ctx.http_status,
38
+ std::move(resp.ctx.http_body),
39
+ std::move(resp.ctx.path) });
41
40
  }
41
+
42
+ static core::operations::management::query_index_build_request
43
+ build_build_index_request(std::string bucket_name,
44
+ core::operations::management::query_index_get_all_deferred_response list_resp,
45
+ const build_query_index_options::built& options)
46
+ {
47
+ core::operations::management::query_index_build_request request{
48
+ std::move(bucket_name), {}, {}, {}, std::move(list_resp.index_names), {}, options.timeout
49
+ };
50
+ return request;
51
+ }
52
+
53
+ static core::operations::management::query_index_get_all_deferred_request
54
+ build_get_all_request(std::string bucket_name, const build_query_index_options::built& options)
55
+ {
56
+ core::operations::management::query_index_get_all_deferred_request request{ std::move(bucket_name), {}, {}, {}, {}, options.timeout };
57
+ return request;
58
+ }
59
+
60
+ static core::operations::management::query_index_build_request
61
+ build_build_index_request(std::string bucket_name,
62
+ std::string scope_name,
63
+ std::string collection_name,
64
+ core::operations::management::query_index_get_all_deferred_response list_resp,
65
+ const build_query_index_options::built& options)
66
+ {
67
+ core::operations::management::query_index_build_request request{ "",
68
+ "",
69
+ std::move(collection_name),
70
+ core::query_context{ std::move(bucket_name), std::move(scope_name) },
71
+ std::move(list_resp.index_names),
72
+ {},
73
+ options.timeout };
74
+ return request;
75
+ }
76
+
77
+ static core::operations::management::query_index_get_all_deferred_request
78
+ build_get_all_request(std::string bucket_name,
79
+ std::string scope_name,
80
+ std::string collection_name,
81
+ const build_query_index_options::built& options)
82
+ {
83
+ core::operations::management::query_index_get_all_deferred_request request{
84
+ "", "", std::move(collection_name), core::query_context{ std::move(bucket_name), std::move(scope_name) }, {}, options.timeout
85
+ };
86
+ return request;
87
+ }
88
+
42
89
  void
43
- initiate_build_deferred_indexes(std::shared_ptr<couchbase::core::cluster> core,
44
- std::string bucket_name,
45
- build_query_index_options::built options,
46
- query_context query_ctx,
47
- std::string collection_name,
48
- build_deferred_query_indexes_handler&& handler)
90
+ query_index_manager::build_deferred_indexes(std::string bucket_name,
91
+ const couchbase::build_query_index_options& options,
92
+ couchbase::build_deferred_query_indexes_handler&& handler) const
93
+ {
94
+
95
+ auto get_all_request = build_get_all_request(bucket_name, options.build());
96
+ core_->execute(std::move(get_all_request),
97
+ [handler = std::move(handler), this, bucket_name, options](
98
+ core::operations::management::query_index_get_all_deferred_response resp1) mutable {
99
+ auto list_resp = std::move(resp1);
100
+ if (list_resp.ctx.ec) {
101
+ return handler(build_context(list_resp));
102
+ }
103
+ if (list_resp.index_names.empty()) {
104
+ return handler(build_context(list_resp));
105
+ }
106
+ auto build_request = build_build_index_request(std::move(bucket_name), list_resp, options.build());
107
+ core_->execute(
108
+ std::move(build_request),
109
+ [handler = std::move(handler)](core::operations::management::query_index_build_response resp2) mutable {
110
+ auto build_resp = std::move(resp2);
111
+ return handler(build_context(build_resp));
112
+ });
113
+ });
114
+ }
115
+
116
+ auto
117
+ query_index_manager::build_deferred_indexes(std::string bucket_name, const couchbase::build_query_index_options& options) const
118
+ -> std::future<manager_error_context>
49
119
  {
50
- core->execute(
51
- operations::management::query_index_get_all_deferred_request{
52
- bucket_name,
53
- "",
54
- collection_name,
55
- query_ctx,
56
- {},
57
- options.timeout,
58
- },
59
- [core, bucket_name, collection_name, options = std::move(options), query_ctx, handler = std::move(handler)](
60
- operations::management::query_index_get_all_deferred_response resp1) mutable {
120
+ auto barrier = std::make_shared<std::promise<manager_error_context>>();
121
+ build_deferred_indexes(std::move(bucket_name), options, [barrier](auto ctx) mutable { barrier->set_value(std::move(ctx)); });
122
+ return barrier->get_future();
123
+ }
124
+
125
+ void
126
+ collection_query_index_manager::build_deferred_indexes(const build_query_index_options& options,
127
+ build_deferred_query_indexes_handler&& handler) const
128
+ {
129
+ auto get_all_request = build_get_all_request(bucket_name_, scope_name_, collection_name_, options.build());
130
+ core_->execute(
131
+ std::move(get_all_request),
132
+ [handler = std::move(handler), this, options](core::operations::management::query_index_get_all_deferred_response resp1) mutable {
61
133
  auto list_resp = std::move(resp1);
62
134
  if (list_resp.ctx.ec) {
63
135
  return handler(build_context(list_resp));
@@ -65,28 +137,21 @@ initiate_build_deferred_indexes(std::shared_ptr<couchbase::core::cluster> core,
65
137
  if (list_resp.index_names.empty()) {
66
138
  return handler(build_context(list_resp));
67
139
  }
68
- core->execute(
69
- operations::management::query_index_build_request{
70
- std::move(bucket_name),
71
- "",
72
- collection_name,
73
- query_ctx,
74
- std::move(list_resp.index_names),
75
- {},
76
- options.timeout,
77
- },
78
- [handler = std::move(handler)](operations::management::query_index_build_response resp2) {
79
- auto build_resp = std::move(resp2);
80
- return handler(build_context(build_resp));
81
- });
140
+ auto build_request = build_build_index_request(bucket_name_, scope_name_, collection_name_, list_resp, options.build());
141
+ core_->execute(std::move(build_request),
142
+ [handler = std::move(handler)](core::operations::management::query_index_build_response resp2) mutable {
143
+ auto build_resp = std::move(resp2);
144
+ return handler(build_context(build_resp));
145
+ });
82
146
  });
83
147
  }
84
- void
85
- initiate_build_deferred_indexes(std::shared_ptr<couchbase::core::cluster> core,
86
- std::string bucket_name,
87
- build_query_index_options::built options,
88
- build_deferred_query_indexes_handler&& handler)
148
+
149
+ auto
150
+ collection_query_index_manager::build_deferred_indexes(const couchbase::build_query_index_options& options) const
151
+ -> std::future<manager_error_context>
89
152
  {
90
- return initiate_build_deferred_indexes(core, std::move(bucket_name), options, {}, "", std::move(handler));
153
+ auto barrier = std::make_shared<std::promise<manager_error_context>>();
154
+ build_deferred_indexes(options, [barrier](auto ctx) mutable { barrier->set_value(std::move(ctx)); });
155
+ return barrier->get_future();
91
156
  }
92
- } // namespace couchbase::core::impl
157
+ } // namespace couchbase
@@ -82,6 +82,9 @@ options_to_origin(const std::string& connection_string, const couchbase::cluster
82
82
  if (opts.security.trust_certificate.has_value()) {
83
83
  user_options.trust_certificate = opts.security.trust_certificate.value();
84
84
  }
85
+ if (opts.security.trust_certificate_value.has_value()) {
86
+ user_options.trust_certificate_value = opts.security.trust_certificate_value.value();
87
+ }
85
88
  switch (opts.security.tls_verify) {
86
89
  case couchbase::tls_verify_mode::none:
87
90
  user_options.tls_verify = core::tls_verify_mode::none;
@@ -91,6 +94,8 @@ options_to_origin(const std::string& connection_string, const couchbase::cluster
91
94
  break;
92
95
  }
93
96
  user_options.disable_mozilla_ca_certificates = opts.security.disable_mozilla_ca_certificates;
97
+ user_options.tls_disable_deprecated_protocols = opts.security.disable_deprecated_protocols;
98
+ user_options.tls_disable_v1_2 = opts.security.disable_tls_v1_2;
94
99
  }
95
100
 
96
101
  if (opts.dns.nameserver) {
@@ -103,6 +108,7 @@ options_to_origin(const std::string& connection_string, const couchbase::cluster
103
108
  user_options.enable_mutation_tokens = opts.behavior.enable_mutation_tokens;
104
109
  user_options.enable_unordered_execution = opts.behavior.enable_unordered_execution;
105
110
  user_options.user_agent_extra = opts.behavior.user_agent_extra;
111
+ user_options.network = opts.behavior.network;
106
112
 
107
113
  user_options.enable_tcp_keep_alive = opts.network.enable_tcp_keep_alive;
108
114
  user_options.tcp_keep_alive_interval = opts.network.tcp_keep_alive_interval;