couchbase 4.2.3 → 4.2.5-dev.1
Sign up to get free protection for your applications and to get access to all the features.
- package/CMakeLists.txt +136 -11
- package/deps/couchbase-cxx-client/CMakeLists.txt +54 -4
- package/deps/couchbase-cxx-client/README.md +1 -0
- package/deps/couchbase-cxx-client/bin/create-search-index +164 -0
- package/deps/couchbase-cxx-client/bin/init-cluster +55 -10
- package/deps/couchbase-cxx-client/bin/run-unit-tests +62 -6
- package/deps/couchbase-cxx-client/bin/travel-sample-index-v6.json +184 -0
- package/deps/couchbase-cxx-client/bin/travel-sample-index.json +188 -0
- package/deps/couchbase-cxx-client/cmake/Documentation.cmake +0 -1
- package/deps/couchbase-cxx-client/cmake/OpenSSL.cmake +98 -3
- package/deps/couchbase-cxx-client/cmake/Testing.cmake +8 -0
- package/deps/couchbase-cxx-client/cmake/build_config.hxx.in +3 -0
- package/deps/couchbase-cxx-client/core/bucket.cxx +183 -152
- package/deps/couchbase-cxx-client/core/bucket.hxx +17 -4
- package/deps/couchbase-cxx-client/core/cluster.hxx +18 -1
- package/deps/couchbase-cxx-client/core/cluster_options.hxx +1 -0
- package/deps/couchbase-cxx-client/core/error_context/key_value.cxx +2 -1
- package/deps/couchbase-cxx-client/core/error_context/key_value.hxx +10 -12
- package/deps/couchbase-cxx-client/core/error_context/search.hxx +1 -1
- package/deps/couchbase-cxx-client/core/impl/analytics.cxx +1 -0
- package/deps/couchbase-cxx-client/core/impl/boolean_field_query.cxx +40 -0
- package/deps/couchbase-cxx-client/core/impl/boolean_query.cxx +62 -0
- package/deps/couchbase-cxx-client/core/impl/cluster.cxx +1 -0
- package/deps/couchbase-cxx-client/core/impl/conjunction_query.cxx +51 -0
- package/deps/couchbase-cxx-client/core/impl/date_range.cxx +89 -0
- package/deps/couchbase-cxx-client/core/impl/date_range_facet.cxx +54 -0
- package/deps/couchbase-cxx-client/core/impl/date_range_facet_result.cxx +64 -0
- package/deps/couchbase-cxx-client/core/impl/date_range_query.cxx +125 -0
- package/deps/couchbase-cxx-client/core/impl/disjunction_query.cxx +51 -0
- package/deps/couchbase-cxx-client/core/impl/encoded_search_facet.hxx +29 -0
- package/deps/couchbase-cxx-client/core/impl/encoded_search_query.hxx +29 -0
- package/deps/couchbase-cxx-client/core/impl/encoded_search_sort.hxx +29 -0
- package/deps/couchbase-cxx-client/core/impl/geo_bounding_box_query.cxx +46 -0
- package/deps/couchbase-cxx-client/core/impl/geo_distance_query.cxx +43 -0
- package/deps/couchbase-cxx-client/core/impl/geo_polygon_query.cxx +46 -0
- package/deps/couchbase-cxx-client/core/impl/internal_date_range_facet_result.cxx +80 -0
- package/deps/couchbase-cxx-client/core/impl/internal_date_range_facet_result.hxx +48 -0
- package/deps/couchbase-cxx-client/core/impl/internal_numeric_range_facet_result.cxx +80 -0
- package/deps/couchbase-cxx-client/core/impl/internal_numeric_range_facet_result.hxx +48 -0
- package/deps/couchbase-cxx-client/core/impl/internal_search_error_context.cxx +141 -0
- package/deps/couchbase-cxx-client/core/impl/internal_search_error_context.hxx +61 -0
- package/deps/couchbase-cxx-client/core/impl/internal_search_meta_data.cxx +60 -0
- package/deps/couchbase-cxx-client/core/impl/internal_search_meta_data.hxx +41 -0
- package/deps/couchbase-cxx-client/core/impl/internal_search_result.cxx +84 -0
- package/deps/couchbase-cxx-client/core/impl/internal_search_result.hxx +43 -0
- package/deps/couchbase-cxx-client/core/impl/internal_search_row.cxx +82 -0
- package/deps/couchbase-cxx-client/core/impl/internal_search_row.hxx +56 -0
- package/deps/couchbase-cxx-client/core/impl/internal_search_row_location.hxx +32 -0
- package/deps/couchbase-cxx-client/core/impl/internal_search_row_locations.cxx +137 -0
- package/deps/couchbase-cxx-client/core/impl/internal_search_row_locations.hxx +45 -0
- package/deps/couchbase-cxx-client/core/impl/internal_term_facet_result.cxx +80 -0
- package/deps/couchbase-cxx-client/core/impl/internal_term_facet_result.hxx +48 -0
- package/deps/couchbase-cxx-client/core/impl/key_value_error_context.cxx +98 -0
- package/deps/couchbase-cxx-client/core/impl/match_all_query.cxx +35 -0
- package/deps/couchbase-cxx-client/core/impl/match_none_query.cxx +35 -0
- package/deps/couchbase-cxx-client/core/impl/match_phrase_query.cxx +43 -0
- package/deps/couchbase-cxx-client/core/impl/match_query.cxx +59 -0
- package/deps/couchbase-cxx-client/core/impl/numeric_range.cxx +49 -0
- package/deps/couchbase-cxx-client/core/impl/numeric_range_facet.cxx +54 -0
- package/deps/couchbase-cxx-client/core/impl/numeric_range_facet_result.cxx +64 -0
- package/deps/couchbase-cxx-client/core/impl/numeric_range_query.cxx +56 -0
- package/deps/couchbase-cxx-client/core/impl/phrase_query.cxx +42 -0
- package/deps/couchbase-cxx-client/core/impl/prefix_query.cxx +40 -0
- package/deps/couchbase-cxx-client/core/impl/query_error_context.cxx +75 -0
- package/deps/couchbase-cxx-client/core/impl/query_string_query.cxx +37 -0
- package/deps/couchbase-cxx-client/core/impl/regexp_query.cxx +40 -0
- package/deps/couchbase-cxx-client/core/impl/search.cxx +191 -0
- package/deps/couchbase-cxx-client/core/impl/search_error_context.cxx +147 -0
- package/deps/couchbase-cxx-client/core/impl/search_meta_data.cxx +46 -0
- package/deps/couchbase-cxx-client/core/impl/search_result.cxx +66 -0
- package/deps/couchbase-cxx-client/core/impl/search_row.cxx +74 -0
- package/deps/couchbase-cxx-client/core/impl/search_row_location.cxx +64 -0
- package/deps/couchbase-cxx-client/core/impl/search_row_locations.cxx +66 -0
- package/deps/couchbase-cxx-client/core/impl/search_sort_field.cxx +104 -0
- package/deps/couchbase-cxx-client/core/impl/search_sort_id.cxx +43 -0
- package/deps/couchbase-cxx-client/core/impl/search_sort_score.cxx +43 -0
- package/deps/couchbase-cxx-client/core/impl/term_facet.cxx +36 -0
- package/deps/couchbase-cxx-client/core/impl/term_facet_result.cxx +64 -0
- package/deps/couchbase-cxx-client/core/impl/term_query.cxx +56 -0
- package/deps/couchbase-cxx-client/core/impl/term_range_query.cxx +57 -0
- package/deps/couchbase-cxx-client/core/impl/wildcard_query.cxx +40 -0
- package/deps/couchbase-cxx-client/core/io/mcbp_command.hxx +9 -2
- package/deps/couchbase-cxx-client/core/io/mcbp_session.cxx +54 -37
- package/deps/couchbase-cxx-client/core/io/mcbp_session.hxx +4 -3
- package/deps/couchbase-cxx-client/core/json_string.hxx +5 -0
- package/deps/couchbase-cxx-client/core/meta/version.cxx +18 -4
- package/deps/couchbase-cxx-client/core/mozilla_ca_bundle.hxx +39 -0
- package/deps/couchbase-cxx-client/core/operations/document_search.cxx +3 -1
- package/deps/couchbase-cxx-client/core/operations/document_search.hxx +1 -1
- package/deps/couchbase-cxx-client/core/protocol/client_request.hxx +11 -2
- package/deps/couchbase-cxx-client/core/protocol/client_response.hxx +1 -0
- package/deps/couchbase-cxx-client/core/utils/connection_string.cxx +59 -46
- package/deps/couchbase-cxx-client/core/utils/connection_string.hxx +1 -0
- package/deps/couchbase-cxx-client/couchbase/analytics_error_context.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/boolean_field_query.hxx +77 -0
- package/deps/couchbase-cxx-client/couchbase/boolean_query.hxx +223 -0
- package/deps/couchbase-cxx-client/couchbase/cluster.hxx +39 -0
- package/deps/couchbase-cxx-client/couchbase/conjunction_query.hxx +88 -0
- package/deps/couchbase-cxx-client/couchbase/date_range.hxx +69 -0
- package/deps/couchbase-cxx-client/couchbase/date_range_facet.hxx +56 -0
- package/deps/couchbase-cxx-client/couchbase/date_range_facet_result.hxx +55 -0
- package/deps/couchbase-cxx-client/couchbase/date_range_query.hxx +265 -0
- package/deps/couchbase-cxx-client/couchbase/disjunction_query.hxx +109 -0
- package/deps/couchbase-cxx-client/couchbase/doc_id_query.hxx +111 -0
- package/deps/couchbase-cxx-client/couchbase/error_context.hxx +17 -8
- package/deps/couchbase-cxx-client/couchbase/fmt/analytics_scan_consistency.hxx +52 -0
- package/deps/couchbase-cxx-client/{core/topology/error_map_fmt.hxx → couchbase/fmt/key_value_error_map_attribute.hxx} +21 -21
- package/deps/couchbase-cxx-client/couchbase/fmt/search_scan_consistency.hxx +49 -0
- package/deps/couchbase-cxx-client/couchbase/geo_bounding_box_query.hxx +107 -0
- package/deps/couchbase-cxx-client/couchbase/geo_distance_query.hxx +109 -0
- package/deps/couchbase-cxx-client/couchbase/geo_point.hxx +32 -0
- package/deps/couchbase-cxx-client/couchbase/geo_polygon_query.hxx +85 -0
- package/deps/couchbase-cxx-client/couchbase/highlight_style.hxx +45 -0
- package/deps/couchbase-cxx-client/couchbase/key_value_error_context.hxx +7 -2
- package/deps/couchbase-cxx-client/couchbase/manager_error_context.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/match_all_query.hxx +43 -0
- package/deps/couchbase-cxx-client/couchbase/match_none_query.hxx +43 -0
- package/deps/couchbase-cxx-client/couchbase/match_operator.hxx +45 -0
- package/deps/couchbase-cxx-client/couchbase/match_phrase_query.hxx +108 -0
- package/deps/couchbase-cxx-client/couchbase/match_query.hxx +163 -0
- package/deps/couchbase-cxx-client/couchbase/numeric_range.hxx +58 -0
- package/deps/couchbase-cxx-client/couchbase/numeric_range_facet.hxx +56 -0
- package/deps/couchbase-cxx-client/couchbase/numeric_range_facet_result.hxx +55 -0
- package/deps/couchbase-cxx-client/couchbase/numeric_range_query.hxx +143 -0
- package/deps/couchbase-cxx-client/couchbase/phrase_query.hxx +93 -0
- package/deps/couchbase-cxx-client/couchbase/prefix_query.hxx +82 -0
- package/deps/couchbase-cxx-client/couchbase/query_error_context.hxx +3 -1
- package/deps/couchbase-cxx-client/couchbase/query_string_query.hxx +72 -0
- package/deps/couchbase-cxx-client/couchbase/regexp_query.hxx +82 -0
- package/deps/couchbase-cxx-client/couchbase/scope.hxx +39 -0
- package/deps/couchbase-cxx-client/couchbase/search_date_range.hxx +68 -0
- package/deps/couchbase-cxx-client/couchbase/search_error_context.hxx +138 -0
- package/deps/couchbase-cxx-client/couchbase/search_facet.hxx +60 -0
- package/deps/couchbase-cxx-client/couchbase/search_facet_result.hxx +50 -0
- package/deps/couchbase-cxx-client/couchbase/search_meta_data.hxx +85 -0
- package/deps/couchbase-cxx-client/couchbase/search_metrics.hxx +127 -0
- package/deps/couchbase-cxx-client/couchbase/search_numeric_range.hxx +69 -0
- package/deps/couchbase-cxx-client/couchbase/search_options.hxx +509 -0
- package/deps/couchbase-cxx-client/couchbase/search_query.hxx +69 -0
- package/deps/couchbase-cxx-client/couchbase/search_result.hxx +77 -0
- package/deps/couchbase-cxx-client/couchbase/search_row.hxx +104 -0
- package/deps/couchbase-cxx-client/couchbase/search_row_location.hxx +55 -0
- package/deps/couchbase-cxx-client/couchbase/search_row_locations.hxx +86 -0
- package/deps/couchbase-cxx-client/couchbase/search_scan_consistency.hxx +34 -0
- package/deps/couchbase-cxx-client/couchbase/search_sort.hxx +58 -0
- package/deps/couchbase-cxx-client/couchbase/search_sort_field.hxx +117 -0
- package/deps/couchbase-cxx-client/couchbase/search_sort_field_missing.hxx +26 -0
- package/deps/couchbase-cxx-client/couchbase/search_sort_field_mode.hxx +27 -0
- package/deps/couchbase-cxx-client/couchbase/search_sort_field_type.hxx +28 -0
- package/deps/couchbase-cxx-client/couchbase/search_sort_id.hxx +60 -0
- package/deps/couchbase-cxx-client/couchbase/search_sort_score.hxx +60 -0
- package/deps/couchbase-cxx-client/couchbase/search_term_range.hxx +51 -0
- package/deps/couchbase-cxx-client/couchbase/security_options.hxx +3 -0
- package/deps/couchbase-cxx-client/couchbase/subdocument_error_context.hxx +4 -2
- package/deps/couchbase-cxx-client/couchbase/term_facet.hxx +48 -0
- package/deps/couchbase-cxx-client/couchbase/term_facet_result.hxx +55 -0
- package/deps/couchbase-cxx-client/couchbase/term_query.hxx +151 -0
- package/deps/couchbase-cxx-client/couchbase/term_range_query.hxx +142 -0
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_options.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_query_options.hxx +2 -1
- package/deps/couchbase-cxx-client/couchbase/transactions/transaction_result.hxx +1 -1
- package/deps/couchbase-cxx-client/couchbase/transactions.hxx +3 -3
- package/deps/couchbase-cxx-client/couchbase/wildcard_query.hxx +83 -0
- package/deps/couchbase-cxx-client/docs/Doxyfile.in +1 -1
- package/deps/couchbase-cxx-client/docs/cbc-analytics.md +2 -2
- package/deps/couchbase-cxx-client/docs/cbc-get.md +3 -2
- package/deps/couchbase-cxx-client/docs/cbc-pillowfight.md +7 -2
- package/deps/couchbase-cxx-client/docs/cbc-query.md +2 -2
- package/deps/couchbase-cxx-client/docs/cbc.md +3 -3
- package/deps/couchbase-cxx-client/docs/cli.hxx +5 -5
- package/deps/couchbase-cxx-client/docs/mainpage.hxx +42 -5
- package/deps/couchbase-cxx-client/test/CMakeLists.txt +1 -0
- package/deps/couchbase-cxx-client/test/test_integration_analytics.cxx +28 -6
- package/deps/couchbase-cxx-client/test/test_integration_collections.cxx +7 -3
- package/deps/couchbase-cxx-client/test/test_integration_connect.cxx +7 -3
- package/deps/couchbase-cxx-client/test/test_integration_crud.cxx +13 -3
- package/deps/couchbase-cxx-client/test/test_integration_diagnostics.cxx +8 -2
- package/deps/couchbase-cxx-client/test/test_integration_durability.cxx +12 -7
- package/deps/couchbase-cxx-client/test/test_integration_examples.cxx +283 -11
- package/deps/couchbase-cxx-client/test/test_integration_management.cxx +140 -88
- package/deps/couchbase-cxx-client/test/test_integration_query.cxx +67 -9
- package/deps/couchbase-cxx-client/test/test_integration_range_scan.cxx +12 -12
- package/deps/couchbase-cxx-client/test/test_integration_read_replica.cxx +48 -11
- package/deps/couchbase-cxx-client/test/test_integration_search.cxx +19 -1
- package/deps/couchbase-cxx-client/test/test_integration_subdoc.cxx +60 -9
- package/deps/couchbase-cxx-client/test/test_integration_tracer.cxx +3 -0
- package/deps/couchbase-cxx-client/test/test_integration_transcoders.cxx +4 -0
- package/deps/couchbase-cxx-client/test/test_transaction_examples.cxx +100 -85
- package/deps/couchbase-cxx-client/test/test_unit_connection_string.cxx +29 -0
- package/deps/couchbase-cxx-client/test/test_unit_search.cxx +427 -0
- package/deps/couchbase-cxx-client/test/utils/integration_test_guard.cxx +2 -1
- package/deps/couchbase-cxx-client/test/utils/logger.cxx +3 -1
- package/deps/couchbase-cxx-client/test/utils/server_version.hxx +31 -15
- package/deps/couchbase-cxx-client/test/utils/test_context.cxx +8 -0
- package/deps/couchbase-cxx-client/tools/get.cxx +9 -8
- package/deps/couchbase-cxx-client/tools/pillowfight.cxx +175 -75
- package/deps/couchbase-cxx-client/tools/version.cxx +4 -2
- package/dist/binding.d.ts +1 -1
- package/dist/binding.js +3 -2
- package/package.json +96 -1
- package/scripts/createPlatformPackages.js +108 -0
- package/scripts/install.js +45 -0
- package/scripts/prebuilds.js +249 -0
- package/scripts/prune.js +124 -0
- package/src/jstocbpp_autogen.hpp +3 -2
@@ -22,7 +22,6 @@
|
|
22
22
|
#include "core/mcbp/codec.hxx"
|
23
23
|
#include "dispatcher.hxx"
|
24
24
|
#include "impl/bootstrap_state_listener.hxx"
|
25
|
-
#include "mcbp/completion_token.hxx"
|
26
25
|
#include "mcbp/operation_queue.hxx"
|
27
26
|
#include "mcbp/queue_request.hxx"
|
28
27
|
#include "mcbp/queue_response.hxx"
|
@@ -41,28 +40,6 @@
|
|
41
40
|
|
42
41
|
namespace couchbase::core
|
43
42
|
{
|
44
|
-
/**
|
45
|
-
* copies nodes from rhs that are not in lhs to output vector
|
46
|
-
*/
|
47
|
-
static void
|
48
|
-
diff_nodes(const std::vector<topology::configuration::node>& lhs,
|
49
|
-
const std::vector<topology::configuration::node>& rhs,
|
50
|
-
std::vector<topology::configuration::node>& output)
|
51
|
-
{
|
52
|
-
for (const auto& re : rhs) {
|
53
|
-
bool known = false;
|
54
|
-
for (const auto& le : lhs) {
|
55
|
-
if (le.hostname == re.hostname && le.services_plain.management.value_or(0) == re.services_plain.management.value_or(0)) {
|
56
|
-
known = true;
|
57
|
-
break;
|
58
|
-
}
|
59
|
-
}
|
60
|
-
if (!known) {
|
61
|
-
output.push_back(re);
|
62
|
-
}
|
63
|
-
}
|
64
|
-
}
|
65
|
-
|
66
43
|
class bucket_impl
|
67
44
|
: public std::enable_shared_from_this<bucket_impl>
|
68
45
|
, public config_listener
|
@@ -303,82 +280,111 @@ class bucket_impl
|
|
303
280
|
return config_->map_key(key, node_index);
|
304
281
|
}
|
305
282
|
|
306
|
-
void
|
283
|
+
void restart_sessions()
|
307
284
|
{
|
308
|
-
|
309
|
-
|
310
|
-
log_prefix_,
|
311
|
-
index,
|
312
|
-
hostname,
|
313
|
-
port);
|
285
|
+
const std::scoped_lock lock(config_mutex_, sessions_mutex_);
|
286
|
+
if (!config_.has_value()) {
|
314
287
|
return;
|
315
288
|
}
|
316
|
-
{
|
317
|
-
std::scoped_lock lock(config_mutex_);
|
318
|
-
if (!config_->has_node(origin_.options().network, service_type::key_value, origin_.options().enable_tls, hostname, port)) {
|
319
|
-
CB_LOG_TRACE(
|
320
|
-
R"({} requested to restart session, but the node has been ejected from current configuration already. idx={}, network={}, address="{}:{}")",
|
321
|
-
log_prefix_,
|
322
|
-
index,
|
323
|
-
origin_.options().network,
|
324
|
-
hostname,
|
325
|
-
port);
|
326
|
-
return;
|
327
|
-
}
|
328
|
-
}
|
329
|
-
couchbase::core::origin origin(origin_.credentials(), hostname, port, origin_.options());
|
330
289
|
|
331
|
-
|
332
|
-
|
333
|
-
|
290
|
+
std::size_t kv_node_index{ 0 };
|
291
|
+
for (std::size_t index = 0; index < config_->nodes.size(); ++index) {
|
292
|
+
const auto& node = config_->nodes[index];
|
334
293
|
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
294
|
+
const auto& hostname = node.hostname_for(origin_.options().network);
|
295
|
+
auto port = node.port_or(origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
|
296
|
+
if (port == 0) {
|
297
|
+
continue;
|
298
|
+
}
|
299
|
+
|
300
|
+
auto ptr = std::find_if(sessions_.begin(), sessions_.end(), [&hostname, &port](const auto& session) {
|
301
|
+
return session.second.bootstrap_hostname() == hostname && session.second.bootstrap_port_number() == port;
|
302
|
+
});
|
303
|
+
if (ptr != sessions_.end()) {
|
304
|
+
|
305
|
+
if (auto found_kv_node_index = ptr->first; found_kv_node_index != kv_node_index) {
|
306
|
+
if (auto current = sessions_.find(kv_node_index); current == sessions_.end()) {
|
307
|
+
CB_LOG_WARNING(R"({} KV node index mismatch: config rev={} states that address="{}:{}" should be at idx={}, )"
|
308
|
+
R"(but it is at idx={} ("{}"). Moving session to idx={}.)",
|
309
|
+
log_prefix_,
|
310
|
+
config_->rev_str(),
|
311
|
+
hostname,
|
312
|
+
port,
|
313
|
+
kv_node_index,
|
314
|
+
found_kv_node_index,
|
315
|
+
ptr->second.id(),
|
316
|
+
kv_node_index);
|
317
|
+
sessions_.insert_or_assign(kv_node_index, std::move(ptr->second));
|
318
|
+
sessions_.erase(ptr);
|
319
|
+
} else {
|
320
|
+
CB_LOG_WARNING(
|
321
|
+
R"({} KV node index mismatch: config rev={} states that address="{}:{}" should be at idx={}, )"
|
322
|
+
R"(but it is at idx={} ("{}"). Slot with idx={} is holds session with address="{}" ("{}"), swapping them.)",
|
323
|
+
log_prefix_,
|
324
|
+
config_->rev_str(),
|
325
|
+
hostname,
|
326
|
+
port,
|
327
|
+
kv_node_index,
|
328
|
+
found_kv_node_index,
|
329
|
+
ptr->second.id(),
|
330
|
+
kv_node_index,
|
331
|
+
current->second.bootstrap_address(),
|
332
|
+
current->second.id());
|
333
|
+
std::swap(current->second, ptr->second);
|
334
|
+
}
|
335
|
+
}
|
336
|
+
++kv_node_index;
|
337
|
+
continue;
|
338
|
+
}
|
339
|
+
couchbase::core::origin origin(origin_.credentials(), hostname, port, origin_.options());
|
340
|
+
io::mcbp_session session = origin_.options().enable_tls
|
341
|
+
? io::mcbp_session(client_id_, ctx_, tls_, origin, state_listener_, name_, known_features_)
|
342
|
+
: io::mcbp_session(client_id_, ctx_, origin, state_listener_, name_, known_features_);
|
343
|
+
CB_LOG_DEBUG(R"({} rev={}, restart idx={}, session="{}", address="{}:{}")",
|
349
344
|
log_prefix_,
|
350
|
-
|
351
|
-
|
345
|
+
config_->rev_str(),
|
346
|
+
node.index,
|
352
347
|
session.id(),
|
353
348
|
hostname,
|
354
349
|
port);
|
350
|
+
session.bootstrap(
|
351
|
+
[self = shared_from_this(), session](std::error_code err, topology::configuration cfg) mutable {
|
352
|
+
if (err) {
|
353
|
+
return self->remove_session(session.id());
|
354
|
+
}
|
355
|
+
self->update_config(std::move(cfg));
|
356
|
+
session.on_configuration_update(self);
|
357
|
+
session.on_stop([id = session.id(), self]() { self->remove_session(id); });
|
358
|
+
self->drain_deferred_queue();
|
359
|
+
},
|
360
|
+
true);
|
361
|
+
sessions_.insert_or_assign(index, std::move(session));
|
362
|
+
++kv_node_index;
|
355
363
|
}
|
364
|
+
}
|
356
365
|
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
});
|
366
|
+
void remove_session(const std::string& id)
|
367
|
+
{
|
368
|
+
bool found{ false };
|
369
|
+
const std::scoped_lock lock(sessions_mutex_);
|
370
|
+
for (auto ptr = sessions_.cbegin(); ptr != sessions_.cend();) {
|
371
|
+
if (ptr->second.id() == id) {
|
372
|
+
CB_LOG_DEBUG(R"({} removed session id="{}", address="{}", bootstrap_address="{}:{}")",
|
373
|
+
log_prefix_,
|
374
|
+
ptr->second.id(),
|
375
|
+
ptr->second.remote_address(),
|
376
|
+
ptr->second.bootstrap_hostname(),
|
377
|
+
ptr->second.bootstrap_port());
|
378
|
+
ptr = sessions_.erase(ptr);
|
379
|
+
found = true;
|
380
|
+
} else {
|
381
|
+
ptr = std::next(ptr);
|
382
|
+
}
|
383
|
+
}
|
376
384
|
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
true);
|
381
|
-
sessions_.insert_or_assign(index, std::move(session));
|
385
|
+
if (found) {
|
386
|
+
asio::post(asio::bind_executor(ctx_, [self = shared_from_this()]() { return self->restart_sessions(); }));
|
387
|
+
}
|
382
388
|
}
|
383
389
|
|
384
390
|
void bootstrap(utils::movable_function<void(std::error_code, topology::configuration)>&& handler)
|
@@ -393,15 +399,11 @@ class bucket_impl
|
|
393
399
|
topology::configuration cfg) mutable {
|
394
400
|
if (ec) {
|
395
401
|
CB_LOG_WARNING(R"({} failed to bootstrap session ec={}, bucket="{}")", new_session.log_prefix(), ec.message(), self->name_);
|
402
|
+
self->remove_session(new_session.id());
|
396
403
|
} else {
|
397
404
|
const std::size_t this_index = new_session.index();
|
398
405
|
new_session.on_configuration_update(self);
|
399
|
-
new_session.on_stop([
|
400
|
-
retry_reason reason) {
|
401
|
-
if (reason == retry_reason::socket_closed_while_in_flight) {
|
402
|
-
self->restart_node(this_index, hostname, port);
|
403
|
-
}
|
404
|
-
});
|
406
|
+
new_session.on_stop([id = new_session.id(), self]() { self->remove_session(id); });
|
405
407
|
|
406
408
|
{
|
407
409
|
std::scoped_lock lock(self->sessions_mutex_);
|
@@ -455,6 +457,9 @@ class bucket_impl
|
|
455
457
|
std::scoped_lock lock(deferred_commands_mutex_);
|
456
458
|
std::swap(deferred_commands_, commands);
|
457
459
|
}
|
460
|
+
if (!commands.empty()) {
|
461
|
+
CB_LOG_TRACE(R"({} draining deferred operation queue, size={})", log_prefix_, commands.size());
|
462
|
+
}
|
458
463
|
while (!commands.empty()) {
|
459
464
|
commands.front()();
|
460
465
|
commands.pop();
|
@@ -489,9 +494,33 @@ class bucket_impl
|
|
489
494
|
}
|
490
495
|
}
|
491
496
|
|
497
|
+
/**
|
498
|
+
* copies nodes from rhs that are not in lhs to output vector
|
499
|
+
*/
|
500
|
+
void diff_nodes(const std::vector<topology::configuration::node>& lhs,
|
501
|
+
const std::vector<topology::configuration::node>& rhs,
|
502
|
+
std::vector<topology::configuration::node>& output)
|
503
|
+
{
|
504
|
+
for (const auto& re : rhs) {
|
505
|
+
bool known = false;
|
506
|
+
const auto& rhost = re.hostname_for(origin_.options().network);
|
507
|
+
const auto rport = re.port_or(origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
|
508
|
+
for (const auto& le : lhs) {
|
509
|
+
const auto& lhost = le.hostname_for(origin_.options().network);
|
510
|
+
const auto lport = le.port_or(origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
|
511
|
+
if (rhost == lhost && rport == lport) {
|
512
|
+
known = true;
|
513
|
+
break;
|
514
|
+
}
|
515
|
+
}
|
516
|
+
if (!known) {
|
517
|
+
output.push_back(re);
|
518
|
+
}
|
519
|
+
}
|
520
|
+
}
|
521
|
+
|
492
522
|
void update_config(topology::configuration config) override
|
493
523
|
{
|
494
|
-
bool forced_config = false;
|
495
524
|
std::vector<topology::configuration::node> added{};
|
496
525
|
std::vector<topology::configuration::node> removed{};
|
497
526
|
{
|
@@ -500,7 +529,6 @@ class bucket_impl
|
|
500
529
|
CB_LOG_DEBUG("{} initialize configuration rev={}", log_prefix_, config.rev_str());
|
501
530
|
} else if (config.force) {
|
502
531
|
CB_LOG_DEBUG("{} forced to accept configuration rev={}", log_prefix_, config.rev_str());
|
503
|
-
forced_config = true;
|
504
532
|
} else if (!config.vbmap) {
|
505
533
|
CB_LOG_DEBUG("{} will not update the configuration old={} -> new={}, because new config does not have partition map",
|
506
534
|
log_prefix_,
|
@@ -533,78 +561,81 @@ class bucket_impl
|
|
533
561
|
std::scoped_lock lock(sessions_mutex_);
|
534
562
|
std::map<size_t, io::mcbp_session> new_sessions{};
|
535
563
|
|
536
|
-
|
537
|
-
std::size_t new_index = config.nodes.size() + 1;
|
538
|
-
for (const auto& node : config.nodes) {
|
539
|
-
if (session.bootstrap_hostname() == node.hostname_for(origin_.options().network) &&
|
540
|
-
session.bootstrap_port() ==
|
541
|
-
std::to_string(
|
542
|
-
node.port_or(origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0))) {
|
543
|
-
new_index = node.index;
|
544
|
-
break;
|
545
|
-
}
|
546
|
-
}
|
547
|
-
if (new_index < config.nodes.size()) {
|
548
|
-
CB_LOG_DEBUG(R"({} rev={}, preserve session="{}", address="{}:{}", index={}->{})",
|
549
|
-
log_prefix_,
|
550
|
-
config.rev_str(),
|
551
|
-
session.id(),
|
552
|
-
session.bootstrap_hostname(),
|
553
|
-
session.bootstrap_port(),
|
554
|
-
index,
|
555
|
-
new_index);
|
556
|
-
new_sessions.insert_or_assign(new_index, std::move(session));
|
557
|
-
} else {
|
558
|
-
CB_LOG_DEBUG(R"({} rev={}, drop session="{}", address="{}:{}", index={})",
|
559
|
-
log_prefix_,
|
560
|
-
config.rev_str(),
|
561
|
-
session.id(),
|
562
|
-
session.bootstrap_hostname(),
|
563
|
-
session.bootstrap_port(),
|
564
|
-
index);
|
565
|
-
asio::post(asio::bind_executor(
|
566
|
-
ctx_, [session = std::move(session)]() mutable { return session.stop(retry_reason::do_not_retry); }));
|
567
|
-
}
|
568
|
-
}
|
569
|
-
|
564
|
+
std::size_t next_index{ 0 };
|
570
565
|
for (const auto& node : config.nodes) {
|
571
|
-
if (new_sessions.find(node.index) != new_sessions.end()) {
|
572
|
-
continue;
|
573
|
-
}
|
574
|
-
|
575
566
|
const auto& hostname = node.hostname_for(origin_.options().network);
|
576
567
|
auto port = node.port_or(origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
|
577
568
|
if (port == 0) {
|
578
569
|
continue;
|
579
570
|
}
|
571
|
+
|
572
|
+
bool reused_session{ false };
|
573
|
+
for (auto it = sessions_.begin(); it != sessions_.end(); ++it) {
|
574
|
+
if (it->second.bootstrap_hostname() == hostname && it->second.bootstrap_port_number() == port) {
|
575
|
+
CB_LOG_DEBUG(R"({} rev={}, preserve session="{}", address="{}:{}", index={}->{})",
|
576
|
+
log_prefix_,
|
577
|
+
config.rev_str(),
|
578
|
+
it->second.id(),
|
579
|
+
it->second.bootstrap_hostname(),
|
580
|
+
it->second.bootstrap_port(),
|
581
|
+
it->first,
|
582
|
+
next_index);
|
583
|
+
new_sessions.insert_or_assign(next_index, std::move(it->second));
|
584
|
+
reused_session = true;
|
585
|
+
++next_index;
|
586
|
+
sessions_.erase(it);
|
587
|
+
break;
|
588
|
+
}
|
589
|
+
}
|
590
|
+
if (reused_session) {
|
591
|
+
continue;
|
592
|
+
}
|
593
|
+
|
580
594
|
couchbase::core::origin origin(origin_.credentials(), hostname, port, origin_.options());
|
581
595
|
io::mcbp_session session = origin_.options().enable_tls
|
582
596
|
? io::mcbp_session(client_id_, ctx_, tls_, origin, state_listener_, name_, known_features_)
|
583
597
|
: io::mcbp_session(client_id_, ctx_, origin, state_listener_, name_, known_features_);
|
584
|
-
CB_LOG_DEBUG(
|
585
|
-
|
598
|
+
CB_LOG_DEBUG(R"({} rev={}, add session="{}", address="{}:{}", index={})",
|
599
|
+
log_prefix_,
|
600
|
+
config.rev_str(),
|
601
|
+
session.id(),
|
602
|
+
hostname,
|
603
|
+
port,
|
604
|
+
node.index);
|
586
605
|
session.bootstrap(
|
587
|
-
[self = shared_from_this(), session,
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
}
|
598
|
-
});
|
599
|
-
self->drain_deferred_queue();
|
600
|
-
} else if (err == errc::common::unambiguous_timeout && forced_config) {
|
601
|
-
self->restart_node(idx, session.bootstrap_hostname(), session.bootstrap_port());
|
606
|
+
[self = shared_from_this(), session, idx = next_index](std::error_code err, topology::configuration cfg) mutable {
|
607
|
+
if (err) {
|
608
|
+
CB_LOG_WARNING(R"({} failed to bootstrap session="{}", address="{}:{}", index={}, ec={})",
|
609
|
+
session.log_prefix(),
|
610
|
+
session.id(),
|
611
|
+
session.bootstrap_hostname(),
|
612
|
+
session.bootstrap_port(),
|
613
|
+
idx,
|
614
|
+
err.message());
|
615
|
+
return self->remove_session(session.id());
|
602
616
|
}
|
617
|
+
self->update_config(std::move(cfg));
|
618
|
+
session.on_configuration_update(self);
|
619
|
+
session.on_stop([id = session.id(), self]() { self->remove_session(id); });
|
620
|
+
self->drain_deferred_queue();
|
603
621
|
},
|
604
622
|
true);
|
605
|
-
new_sessions.insert_or_assign(
|
623
|
+
new_sessions.insert_or_assign(next_index, std::move(session));
|
624
|
+
++next_index;
|
625
|
+
}
|
626
|
+
std::swap(sessions_, new_sessions);
|
627
|
+
|
628
|
+
for (auto it = new_sessions.begin(); it != new_sessions.end(); ++it) {
|
629
|
+
CB_LOG_DEBUG(R"({} rev={}, drop session="{}", address="{}:{}", index={})",
|
630
|
+
log_prefix_,
|
631
|
+
config.rev_str(),
|
632
|
+
it->second.id(),
|
633
|
+
it->second.bootstrap_hostname(),
|
634
|
+
it->second.bootstrap_port(),
|
635
|
+
it->first);
|
636
|
+
asio::post(asio::bind_executor(
|
637
|
+
ctx_, [session = std::move(it->second)]() mutable { return session.stop(retry_reason::do_not_retry); }));
|
606
638
|
}
|
607
|
-
sessions_ = new_sessions;
|
608
639
|
}
|
609
640
|
}
|
610
641
|
|
@@ -83,7 +83,7 @@ class bucket
|
|
83
83
|
auto cmd = std::make_shared<operations::mcbp_command<bucket, Request>>(ctx_, shared_from_this(), request, default_timeout());
|
84
84
|
cmd->start([cmd, handler = std::forward<Handler>(handler)](std::error_code ec, std::optional<io::mcbp_message>&& msg) mutable {
|
85
85
|
using encoded_response_type = typename Request::encoded_response_type;
|
86
|
-
std::uint16_t status_code = msg ? msg->header.status() :
|
86
|
+
std::uint16_t status_code = msg ? msg->header.status() : 0xffffU;
|
87
87
|
auto resp = msg ? encoded_response_type(std::move(*msg)) : encoded_response_type{};
|
88
88
|
auto ctx = make_key_value_error_context(ec, status_code, cmd, resp);
|
89
89
|
handler(cmd->request.make_response(std::move(ctx), std::move(resp)));
|
@@ -107,7 +107,7 @@ class bucket
|
|
107
107
|
auto [partition, server] = map_id(cmd->request.id);
|
108
108
|
if (!server.has_value()) {
|
109
109
|
CB_LOG_TRACE(
|
110
|
-
R"({} unable to map key
|
110
|
+
R"({} unable to map key="{}" to the node, id={}, partition={})", log_prefix(), cmd->request.id, cmd->id_, partition);
|
111
111
|
return io::retry_orchestrator::maybe_retry(
|
112
112
|
cmd->manager_, cmd, retry_reason::node_not_available, errc::common::request_canceled);
|
113
113
|
}
|
@@ -116,19 +116,32 @@ class bucket
|
|
116
116
|
}
|
117
117
|
auto session = find_session_by_index(index);
|
118
118
|
if (!session || !session->has_config()) {
|
119
|
-
CB_LOG_TRACE(R"({} defer operation id={}, session={}, has_config={})",
|
119
|
+
CB_LOG_TRACE(R"({} defer operation id={}, key="{}", partition={}, index={}, session={}, address="{}", has_config={})",
|
120
120
|
log_prefix(),
|
121
121
|
cmd->id_,
|
122
|
+
cmd->request.id,
|
123
|
+
cmd->request.partition,
|
124
|
+
index,
|
122
125
|
session.has_value(),
|
126
|
+
session.has_value() ? session->bootstrap_address() : "",
|
123
127
|
session.has_value() && session->has_config());
|
124
128
|
return defer_command([self = shared_from_this(), cmd]() { self->map_and_send(cmd); });
|
125
129
|
}
|
126
130
|
if (session->is_stopped()) {
|
127
131
|
CB_LOG_TRACE(
|
128
|
-
R"({} the session has been found, but it is stopped, retrying id={},
|
132
|
+
R"({} the session has been found for idx={}, but it is stopped, retrying id={}, key="{}", partition={}, session={}, address="{}")",
|
133
|
+
log_prefix(),
|
134
|
+
index,
|
135
|
+
cmd->id_,
|
136
|
+
cmd->request.id,
|
137
|
+
cmd->request.partition,
|
138
|
+
session->id(),
|
139
|
+
session->bootstrap_address());
|
129
140
|
return io::retry_orchestrator::maybe_retry(
|
130
141
|
cmd->manager_, cmd, retry_reason::node_not_available, errc::common::request_canceled);
|
131
142
|
}
|
143
|
+
cmd->last_dispatched_from_ = session->local_address();
|
144
|
+
cmd->last_dispatched_to_ = session->bootstrap_address();
|
132
145
|
cmd->send_to(session.value());
|
133
146
|
}
|
134
147
|
|
@@ -33,6 +33,7 @@
|
|
33
33
|
#include "diagnostics.hxx"
|
34
34
|
#include "dispatcher.hxx"
|
35
35
|
#include "impl/dns_srv_tracker.hxx"
|
36
|
+
#include "mozilla_ca_bundle.hxx"
|
36
37
|
#include "operations.hxx"
|
37
38
|
#include "origin.hxx"
|
38
39
|
|
@@ -394,6 +395,21 @@ class cluster : public std::enable_shared_from_this<cluster>
|
|
394
395
|
CB_LOG_WARNING("[{}]: unable to load default CAs: {}", id_, ec.message());
|
395
396
|
// we don't consider this fatal and try to continue without it
|
396
397
|
}
|
398
|
+
|
399
|
+
if (const auto certificates = default_ca::mozilla_ca_certs();
|
400
|
+
!origin_.options().disable_mozilla_ca_certificates && !certificates.empty()) {
|
401
|
+
CB_LOG_DEBUG("[{}]: loading {} CA certificates from Mozilla bundle. Update date: \"{}\", SHA256: \"{}\"",
|
402
|
+
id_,
|
403
|
+
certificates.size(),
|
404
|
+
default_ca::mozilla_ca_certs_date(),
|
405
|
+
default_ca::mozilla_ca_certs_sha256());
|
406
|
+
for (const auto& cert : certificates) {
|
407
|
+
tls_.add_certificate_authority(asio::const_buffer(cert.body.data(), cert.body.size()), ec);
|
408
|
+
if (ec) {
|
409
|
+
CB_LOG_WARNING("[{}]: unable to load CA \"{}\" from Mozilla bundle: {}", id_, cert.authority, ec.message());
|
410
|
+
}
|
411
|
+
}
|
412
|
+
}
|
397
413
|
} else { // trust certificate is explicitly specified
|
398
414
|
std::error_code ec{};
|
399
415
|
// load only the explicit certificate
|
@@ -430,6 +446,7 @@ class cluster : public std::enable_shared_from_this<cluster>
|
|
430
446
|
return close([ec, handler = std::forward<Handler>(handler)]() mutable { return handler(ec); });
|
431
447
|
}
|
432
448
|
}
|
449
|
+
|
433
450
|
session_ = io::mcbp_session(id_, ctx_, tls_, origin_, dns_srv_tracker_);
|
434
451
|
} else {
|
435
452
|
session_ = io::mcbp_session(id_, ctx_, origin_, dns_srv_tracker_);
|
@@ -466,7 +483,7 @@ class cluster : public std::enable_shared_from_this<cluster>
|
|
466
483
|
}
|
467
484
|
self->session_manager_->set_configuration(config, self->origin_.options());
|
468
485
|
self->session_->on_configuration_update(self->session_manager_);
|
469
|
-
self->session_->on_stop([self](
|
486
|
+
self->session_->on_stop([self]() {
|
470
487
|
if (self->session_) {
|
471
488
|
self->session_.reset();
|
472
489
|
}
|
@@ -24,7 +24,7 @@ key_value_error_context
|
|
24
24
|
make_key_value_error_context(std::error_code ec, const document_id& id)
|
25
25
|
{
|
26
26
|
return {
|
27
|
-
ec, {}, {}, 0, {}, id.key(), id.bucket(), id.scope(), id.collection(), 0, {}, {}, {}, {},
|
27
|
+
{}, ec, {}, {}, 0, {}, id.key(), id.bucket(), id.scope(), id.collection(), 0, {}, {}, {}, {},
|
28
28
|
};
|
29
29
|
}
|
30
30
|
|
@@ -36,6 +36,7 @@ make_subdocument_error_context(const key_value_error_context& ctx,
|
|
36
36
|
bool deleted)
|
37
37
|
{
|
38
38
|
return {
|
39
|
+
ctx.operation_id(),
|
39
40
|
ec,
|
40
41
|
ctx.last_dispatched_to(),
|
41
42
|
ctx.last_dispatched_from(),
|
@@ -43,23 +43,21 @@ make_key_value_error_context(std::error_code ec, std::uint16_t status_code, cons
|
|
43
43
|
const auto& scope = command->request.id.scope();
|
44
44
|
const auto& bucket = command->request.id.bucket();
|
45
45
|
std::uint32_t opaque = (ec && response.opaque() == 0) ? command->request.opaque : response.opaque();
|
46
|
-
|
47
|
-
auto retry_attempts = command->request.retries.retry_attempts();
|
48
|
-
auto retry_reasons = command->request.retries.retry_reasons();
|
49
|
-
std::optional<std::string> last_dispatched_from{};
|
50
|
-
std::optional<std::string> last_dispatched_to{};
|
46
|
+
std::optional<key_value_status_code> status{};
|
51
47
|
std::optional<key_value_error_map_info> error_map_info{};
|
52
|
-
if (
|
53
|
-
|
54
|
-
|
55
|
-
if (status_code) {
|
48
|
+
if (status_code != 0xffffU) {
|
49
|
+
status = response.status();
|
50
|
+
if (command->session_ && status_code > 0) {
|
56
51
|
error_map_info = command->session_->decode_error_code(status_code);
|
57
52
|
}
|
58
53
|
}
|
54
|
+
auto retry_attempts = command->request.retries.retry_attempts();
|
55
|
+
auto retry_reasons = command->request.retries.retry_reasons();
|
59
56
|
|
60
|
-
return {
|
61
|
-
|
62
|
-
|
57
|
+
return { command->id_,
|
58
|
+
ec,
|
59
|
+
command->last_dispatched_to_,
|
60
|
+
command->last_dispatched_from_,
|
63
61
|
retry_attempts,
|
64
62
|
std::move(retry_reasons),
|
65
63
|
key,
|
@@ -0,0 +1,40 @@
|
|
1
|
+
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
2
|
+
/*
|
3
|
+
* Copyright 2023-Present 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 "encoded_search_query.hxx"
|
19
|
+
|
20
|
+
#include <couchbase/boolean_field_query.hxx>
|
21
|
+
|
22
|
+
namespace couchbase
|
23
|
+
{
|
24
|
+
auto
|
25
|
+
boolean_field_query::encode() const -> encoded_search_query
|
26
|
+
{
|
27
|
+
encoded_search_query built;
|
28
|
+
|
29
|
+
built.query = tao::json::empty_object;
|
30
|
+
if (boost_) {
|
31
|
+
built.query["boost"] = boost_.value();
|
32
|
+
}
|
33
|
+
built.query["bool"] = bool_;
|
34
|
+
if (field_) {
|
35
|
+
built.query["field"] = field_.value();
|
36
|
+
}
|
37
|
+
|
38
|
+
return built;
|
39
|
+
}
|
40
|
+
} // namespace couchbase
|