couchbase 3.4.2 → 3.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/ext/couchbase/CMakeLists.txt +71 -7
- data/ext/couchbase/cmake/Documentation.cmake +0 -1
- data/ext/couchbase/cmake/OpenSSL.cmake +98 -3
- data/ext/couchbase/cmake/Testing.cmake +12 -4
- data/ext/couchbase/cmake/build_config.hxx.in +3 -0
- data/ext/couchbase/core/bucket.cxx +183 -151
- data/ext/couchbase/core/bucket.hxx +23 -1
- data/ext/couchbase/core/cluster.hxx +51 -13
- data/ext/couchbase/core/cluster_options.cxx +2 -2
- data/ext/couchbase/core/cluster_options.hxx +7 -6
- data/ext/couchbase/core/cluster_options_fwd.hxx +26 -0
- data/ext/couchbase/core/config_profile.hxx +1 -54
- data/ext/couchbase/core/config_profiles.cxx +79 -0
- data/ext/couchbase/core/config_profiles.hxx +56 -0
- data/ext/couchbase/core/crud_component.cxx +51 -22
- data/ext/couchbase/core/error_context/key_value.cxx +2 -1
- data/ext/couchbase/core/error_context/key_value.hxx +10 -12
- data/ext/couchbase/core/error_context/search.hxx +1 -1
- data/ext/couchbase/core/impl/analytics.cxx +1 -0
- data/ext/couchbase/core/impl/boolean_field_query.cxx +40 -0
- data/ext/couchbase/core/impl/boolean_query.cxx +62 -0
- data/ext/couchbase/core/impl/build_deferred_query_indexes.cxx +115 -50
- data/ext/couchbase/core/impl/cluster.cxx +8 -0
- data/ext/couchbase/core/impl/conjunction_query.cxx +51 -0
- data/ext/couchbase/core/impl/create_bucket.cxx +155 -0
- data/ext/couchbase/core/impl/create_query_index.cxx +172 -59
- data/ext/couchbase/core/impl/date_range.cxx +89 -0
- data/ext/couchbase/core/impl/date_range_facet.cxx +54 -0
- data/ext/couchbase/core/impl/date_range_facet_result.cxx +64 -0
- data/ext/couchbase/core/impl/date_range_query.cxx +125 -0
- data/ext/couchbase/core/impl/disjunction_query.cxx +51 -0
- data/ext/couchbase/core/impl/dns_srv_tracker.cxx +2 -1
- data/ext/couchbase/core/impl/drop_bucket.cxx +66 -0
- data/ext/couchbase/core/impl/drop_query_index.cxx +138 -59
- data/ext/couchbase/core/impl/encoded_search_facet.hxx +29 -0
- data/ext/couchbase/core/impl/encoded_search_query.hxx +29 -0
- data/ext/couchbase/core/impl/encoded_search_sort.hxx +29 -0
- data/ext/couchbase/core/impl/flush_bucket.cxx +66 -0
- data/ext/couchbase/core/impl/geo_bounding_box_query.cxx +46 -0
- data/ext/couchbase/core/impl/geo_distance_query.cxx +43 -0
- data/ext/couchbase/core/impl/geo_polygon_query.cxx +46 -0
- data/ext/couchbase/core/impl/get_all_buckets.cxx +163 -0
- data/ext/couchbase/core/impl/get_all_query_indexes.cxx +67 -37
- data/ext/couchbase/core/impl/get_bucket.cxx +153 -0
- data/ext/couchbase/core/impl/internal_date_range_facet_result.cxx +80 -0
- data/ext/couchbase/core/impl/internal_date_range_facet_result.hxx +48 -0
- data/ext/couchbase/core/impl/internal_manager_error_context.cxx +113 -0
- data/ext/couchbase/core/impl/internal_manager_error_context.hxx +60 -0
- data/ext/couchbase/core/impl/internal_numeric_range_facet_result.cxx +80 -0
- data/ext/couchbase/core/impl/internal_numeric_range_facet_result.hxx +48 -0
- data/ext/couchbase/core/impl/internal_search_error_context.cxx +141 -0
- data/ext/couchbase/core/impl/internal_search_error_context.hxx +61 -0
- data/ext/couchbase/core/impl/internal_search_meta_data.cxx +60 -0
- data/ext/couchbase/core/impl/internal_search_meta_data.hxx +41 -0
- data/ext/couchbase/core/impl/internal_search_result.cxx +84 -0
- data/ext/couchbase/core/impl/internal_search_result.hxx +43 -0
- data/ext/couchbase/core/impl/internal_search_row.cxx +82 -0
- data/ext/couchbase/core/impl/internal_search_row.hxx +56 -0
- data/ext/couchbase/core/impl/internal_search_row_location.hxx +32 -0
- data/ext/couchbase/core/impl/internal_search_row_locations.cxx +137 -0
- data/ext/couchbase/core/impl/internal_search_row_locations.hxx +45 -0
- data/ext/couchbase/core/impl/internal_term_facet_result.cxx +80 -0
- data/ext/couchbase/core/impl/internal_term_facet_result.hxx +48 -0
- data/ext/couchbase/core/impl/key_value_error_category.cxx +2 -4
- data/ext/couchbase/core/impl/key_value_error_context.cxx +98 -0
- data/ext/couchbase/core/impl/lookup_in.cxx +1 -0
- data/ext/couchbase/core/impl/lookup_in_all_replicas.cxx +176 -0
- data/ext/couchbase/core/impl/lookup_in_all_replicas.hxx +80 -0
- data/ext/couchbase/core/impl/lookup_in_any_replica.cxx +167 -0
- data/ext/couchbase/core/impl/lookup_in_any_replica.hxx +75 -0
- data/ext/couchbase/core/impl/lookup_in_replica.cxx +97 -0
- data/ext/couchbase/core/impl/lookup_in_replica.hxx +67 -0
- data/ext/couchbase/core/impl/manager_error_context.cxx +100 -0
- data/ext/couchbase/core/impl/match_all_query.cxx +35 -0
- data/ext/couchbase/core/impl/match_none_query.cxx +35 -0
- data/ext/couchbase/core/impl/match_phrase_query.cxx +43 -0
- data/ext/couchbase/core/impl/match_query.cxx +59 -0
- data/ext/couchbase/core/impl/numeric_range.cxx +49 -0
- data/ext/couchbase/core/impl/numeric_range_facet.cxx +54 -0
- data/ext/couchbase/core/impl/numeric_range_facet_result.cxx +64 -0
- data/ext/couchbase/core/impl/numeric_range_query.cxx +56 -0
- data/ext/couchbase/core/impl/phrase_query.cxx +42 -0
- data/ext/couchbase/core/impl/prefix_query.cxx +40 -0
- data/ext/couchbase/core/impl/query.cxx +1 -0
- data/ext/couchbase/core/impl/query_error_context.cxx +75 -0
- data/ext/couchbase/core/impl/query_string_query.cxx +37 -0
- data/ext/couchbase/core/impl/regexp_query.cxx +40 -0
- data/ext/couchbase/core/impl/search.cxx +191 -0
- data/ext/couchbase/core/impl/search_error_context.cxx +147 -0
- data/ext/couchbase/core/impl/search_meta_data.cxx +46 -0
- data/ext/couchbase/core/impl/search_result.cxx +66 -0
- data/ext/couchbase/core/impl/search_row.cxx +74 -0
- data/ext/couchbase/core/impl/search_row_location.cxx +64 -0
- data/ext/couchbase/core/impl/search_row_locations.cxx +66 -0
- data/ext/couchbase/core/impl/search_sort_field.cxx +104 -0
- data/ext/couchbase/core/impl/search_sort_id.cxx +43 -0
- data/ext/couchbase/core/impl/search_sort_score.cxx +43 -0
- data/ext/couchbase/core/impl/term_facet.cxx +36 -0
- data/ext/couchbase/core/impl/term_facet_result.cxx +64 -0
- data/ext/couchbase/core/impl/term_query.cxx +56 -0
- data/ext/couchbase/core/impl/term_range_query.cxx +57 -0
- data/ext/couchbase/core/impl/update_bucket.cxx +130 -0
- data/ext/couchbase/core/impl/watch_query_indexes.cxx +53 -29
- data/ext/couchbase/core/impl/wildcard_query.cxx +40 -0
- data/ext/couchbase/core/io/dns_client.cxx +111 -40
- data/ext/couchbase/core/io/dns_config.cxx +5 -4
- data/ext/couchbase/core/io/http_context.hxx +1 -1
- data/ext/couchbase/core/io/http_session.hxx +34 -1
- data/ext/couchbase/core/io/http_session_manager.hxx +5 -3
- data/ext/couchbase/core/io/mcbp_command.hxx +9 -2
- data/ext/couchbase/core/io/mcbp_session.cxx +106 -42
- data/ext/couchbase/core/io/mcbp_session.hxx +4 -3
- data/ext/couchbase/core/io/retry_orchestrator.hxx +3 -2
- data/ext/couchbase/core/json_string.hxx +5 -0
- data/ext/couchbase/core/logger/custom_rotating_file_sink.cxx +1 -1
- data/ext/couchbase/core/logger/logger.cxx +80 -20
- data/ext/couchbase/core/logger/logger.hxx +31 -0
- data/ext/couchbase/core/meta/features.hxx +25 -0
- data/ext/couchbase/core/meta/version.cxx +18 -4
- data/ext/couchbase/core/mozilla_ca_bundle.hxx +39 -0
- data/ext/couchbase/core/operations/document_analytics.cxx +1 -0
- data/ext/couchbase/core/operations/document_analytics.hxx +1 -0
- data/ext/couchbase/core/operations/document_append.hxx +1 -1
- data/ext/couchbase/core/operations/document_decrement.hxx +1 -1
- data/ext/couchbase/core/operations/document_exists.hxx +1 -1
- data/ext/couchbase/core/operations/document_get.hxx +1 -1
- data/ext/couchbase/core/operations/document_get_and_lock.hxx +1 -1
- data/ext/couchbase/core/operations/document_get_and_touch.hxx +1 -1
- data/ext/couchbase/core/operations/document_get_projected.hxx +1 -1
- data/ext/couchbase/core/operations/document_increment.hxx +1 -1
- data/ext/couchbase/core/operations/document_insert.hxx +1 -1
- data/ext/couchbase/core/operations/document_lookup_in.hxx +1 -1
- data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +192 -0
- data/ext/couchbase/core/operations/document_lookup_in_any_replica.hxx +188 -0
- data/ext/couchbase/core/operations/document_mutate_in.hxx +1 -1
- data/ext/couchbase/core/operations/document_prepend.hxx +1 -1
- data/ext/couchbase/core/operations/document_query.cxx +13 -0
- data/ext/couchbase/core/operations/document_query.hxx +7 -0
- data/ext/couchbase/core/operations/document_remove.hxx +1 -1
- data/ext/couchbase/core/operations/document_replace.hxx +1 -1
- data/ext/couchbase/core/operations/document_search.cxx +4 -1
- data/ext/couchbase/core/operations/document_search.hxx +2 -1
- data/ext/couchbase/core/operations/document_touch.hxx +1 -1
- data/ext/couchbase/core/operations/document_unlock.hxx +1 -1
- data/ext/couchbase/core/operations/document_upsert.hxx +1 -1
- data/ext/couchbase/core/operations/document_view.hxx +1 -0
- data/ext/couchbase/core/operations.hxx +2 -0
- data/ext/couchbase/core/origin.cxx +270 -0
- data/ext/couchbase/core/origin.hxx +2 -0
- data/ext/couchbase/core/protocol/client_request.hxx +11 -2
- data/ext/couchbase/core/protocol/client_response.hxx +1 -0
- data/ext/couchbase/core/protocol/cmd_hello.hxx +1 -0
- data/ext/couchbase/core/protocol/cmd_lookup_in_replica.cxx +107 -0
- data/ext/couchbase/core/protocol/cmd_lookup_in_replica.hxx +137 -0
- data/ext/couchbase/core/protocol/hello_feature.hxx +6 -0
- data/ext/couchbase/core/protocol/hello_feature_fmt.hxx +3 -0
- data/ext/couchbase/core/protocol/status.cxx +2 -2
- data/ext/couchbase/core/public_fwd.hxx +21 -0
- data/ext/couchbase/core/range_scan_options.cxx +3 -27
- data/ext/couchbase/core/range_scan_options.hxx +13 -17
- data/ext/couchbase/core/range_scan_orchestrator.cxx +388 -170
- data/ext/couchbase/core/range_scan_orchestrator.hxx +13 -2
- data/ext/couchbase/core/range_scan_orchestrator_options.hxx +5 -3
- data/ext/couchbase/core/scan_options.hxx +0 -19
- data/ext/couchbase/core/scan_result.cxx +19 -5
- data/ext/couchbase/core/scan_result.hxx +5 -2
- data/ext/couchbase/core/timeout_defaults.hxx +2 -3
- data/ext/couchbase/core/tls_verify_mode.hxx +26 -0
- data/ext/couchbase/core/topology/capabilities.hxx +3 -0
- data/ext/couchbase/core/topology/capabilities_fmt.hxx +8 -0
- data/ext/couchbase/core/topology/collections_manifest_fmt.hxx +1 -1
- data/ext/couchbase/core/topology/configuration.cxx +15 -2
- data/ext/couchbase/core/topology/configuration.hxx +20 -1
- data/ext/couchbase/core/topology/configuration_json.hxx +6 -1
- data/ext/couchbase/core/transactions/attempt_context_testing_hooks.cxx +93 -0
- data/ext/couchbase/core/transactions/attempt_context_testing_hooks.hxx +48 -75
- data/ext/couchbase/core/transactions/cleanup_testing_hooks.cxx +52 -0
- data/ext/couchbase/core/transactions/cleanup_testing_hooks.hxx +17 -31
- data/ext/couchbase/core/transactions/exceptions.hxx +12 -9
- data/ext/couchbase/core/utils/connection_string.cxx +75 -43
- data/ext/couchbase/core/utils/connection_string.hxx +1 -0
- data/ext/couchbase/core/utils/json.cxx +4 -1
- data/ext/couchbase/couchbase/analytics_error_context.hxx +1 -1
- data/ext/couchbase/couchbase/behavior_options.hxx +27 -1
- data/ext/couchbase/couchbase/boolean_field_query.hxx +77 -0
- data/ext/couchbase/couchbase/boolean_query.hxx +223 -0
- data/ext/couchbase/couchbase/bucket_manager.hxx +135 -0
- data/ext/couchbase/couchbase/build_query_index_options.hxx +0 -30
- data/ext/couchbase/couchbase/cluster.hxx +56 -1
- data/ext/couchbase/couchbase/collection.hxx +111 -0
- data/ext/couchbase/couchbase/collection_query_index_manager.hxx +7 -48
- data/ext/couchbase/couchbase/conjunction_query.hxx +88 -0
- data/ext/couchbase/couchbase/create_bucket_options.hxx +41 -0
- data/ext/couchbase/couchbase/create_primary_query_index_options.hxx +0 -29
- data/ext/couchbase/couchbase/create_query_index_options.hxx +0 -33
- data/ext/couchbase/couchbase/date_range.hxx +69 -0
- data/ext/couchbase/couchbase/date_range_facet.hxx +56 -0
- data/ext/couchbase/couchbase/date_range_facet_result.hxx +55 -0
- data/ext/couchbase/couchbase/date_range_query.hxx +265 -0
- data/ext/couchbase/couchbase/disjunction_query.hxx +109 -0
- data/ext/couchbase/couchbase/doc_id_query.hxx +111 -0
- data/ext/couchbase/couchbase/drop_bucket_options.hxx +41 -0
- data/ext/couchbase/couchbase/drop_primary_query_index_options.hxx +0 -30
- data/ext/couchbase/couchbase/drop_query_index_options.hxx +0 -31
- data/ext/couchbase/couchbase/error_codes.hxx +1 -2
- data/ext/couchbase/couchbase/error_context.hxx +17 -8
- data/ext/couchbase/couchbase/flush_bucket_options.hxx +41 -0
- data/ext/couchbase/couchbase/fmt/analytics_scan_consistency.hxx +52 -0
- data/ext/couchbase/{core/topology/error_map_fmt.hxx → couchbase/fmt/key_value_error_map_attribute.hxx} +21 -21
- data/ext/couchbase/couchbase/fmt/search_scan_consistency.hxx +49 -0
- data/ext/couchbase/couchbase/geo_bounding_box_query.hxx +107 -0
- data/ext/couchbase/couchbase/geo_distance_query.hxx +109 -0
- data/ext/couchbase/couchbase/geo_point.hxx +32 -0
- data/ext/couchbase/couchbase/geo_polygon_query.hxx +85 -0
- data/ext/couchbase/couchbase/get_all_buckets_options.hxx +44 -0
- data/ext/couchbase/couchbase/get_all_query_indexes_options.hxx +0 -30
- data/ext/couchbase/couchbase/get_and_lock_options.hxx +2 -2
- data/ext/couchbase/couchbase/get_and_touch_options.hxx +2 -2
- data/ext/couchbase/couchbase/get_bucket_options.hxx +43 -0
- data/ext/couchbase/couchbase/get_options.hxx +2 -2
- data/ext/couchbase/couchbase/highlight_style.hxx +45 -0
- data/ext/couchbase/couchbase/insert_options.hxx +3 -3
- data/ext/couchbase/couchbase/key_value_error_context.hxx +7 -2
- data/ext/couchbase/couchbase/lookup_in_all_replicas_options.hxx +109 -0
- data/ext/couchbase/couchbase/lookup_in_any_replica_options.hxx +101 -0
- data/ext/couchbase/couchbase/lookup_in_options.hxx +2 -2
- data/ext/couchbase/couchbase/lookup_in_replica_result.hxx +74 -0
- data/ext/couchbase/couchbase/lookup_in_result.hxx +26 -0
- data/ext/couchbase/couchbase/management/bucket_settings.hxx +116 -0
- data/ext/couchbase/couchbase/manager_error_context.hxx +29 -53
- data/ext/couchbase/couchbase/match_all_query.hxx +43 -0
- data/ext/couchbase/couchbase/match_none_query.hxx +43 -0
- data/ext/couchbase/couchbase/match_operator.hxx +45 -0
- data/ext/couchbase/couchbase/match_phrase_query.hxx +108 -0
- data/ext/couchbase/couchbase/match_query.hxx +163 -0
- data/ext/couchbase/couchbase/mutate_in_options.hxx +2 -2
- data/ext/couchbase/couchbase/numeric_range.hxx +58 -0
- data/ext/couchbase/couchbase/numeric_range_facet.hxx +56 -0
- data/ext/couchbase/couchbase/numeric_range_facet_result.hxx +55 -0
- data/ext/couchbase/couchbase/numeric_range_query.hxx +143 -0
- data/ext/couchbase/couchbase/phrase_query.hxx +93 -0
- data/ext/couchbase/couchbase/prefix_query.hxx +82 -0
- data/ext/couchbase/couchbase/query_error_context.hxx +3 -1
- data/ext/couchbase/couchbase/query_index_manager.hxx +16 -83
- data/ext/couchbase/couchbase/query_options.hxx +18 -0
- data/ext/couchbase/couchbase/query_string_query.hxx +72 -0
- data/ext/couchbase/couchbase/regexp_query.hxx +82 -0
- data/ext/couchbase/couchbase/remove_options.hxx +2 -2
- data/ext/couchbase/couchbase/replace_options.hxx +3 -3
- data/ext/couchbase/couchbase/scope.hxx +40 -0
- data/ext/couchbase/couchbase/search_date_range.hxx +68 -0
- data/ext/couchbase/couchbase/search_error_context.hxx +138 -0
- data/ext/couchbase/couchbase/search_facet.hxx +60 -0
- data/ext/couchbase/couchbase/search_facet_result.hxx +50 -0
- data/ext/couchbase/couchbase/search_meta_data.hxx +85 -0
- data/ext/couchbase/couchbase/search_metrics.hxx +127 -0
- data/ext/couchbase/couchbase/search_numeric_range.hxx +69 -0
- data/ext/couchbase/couchbase/search_options.hxx +509 -0
- data/ext/couchbase/couchbase/search_query.hxx +69 -0
- data/ext/couchbase/couchbase/search_result.hxx +77 -0
- data/ext/couchbase/couchbase/search_row.hxx +104 -0
- data/ext/couchbase/couchbase/search_row_location.hxx +55 -0
- data/ext/couchbase/couchbase/search_row_locations.hxx +86 -0
- data/ext/couchbase/couchbase/search_scan_consistency.hxx +34 -0
- data/ext/couchbase/couchbase/search_sort.hxx +58 -0
- data/ext/couchbase/couchbase/search_sort_field.hxx +117 -0
- data/ext/couchbase/couchbase/search_sort_field_missing.hxx +26 -0
- data/ext/couchbase/couchbase/search_sort_field_mode.hxx +27 -0
- data/ext/couchbase/couchbase/search_sort_field_type.hxx +28 -0
- data/ext/couchbase/couchbase/search_sort_id.hxx +60 -0
- data/ext/couchbase/couchbase/search_sort_score.hxx +60 -0
- data/ext/couchbase/couchbase/search_term_range.hxx +51 -0
- data/ext/couchbase/couchbase/security_options.hxx +18 -0
- data/ext/couchbase/couchbase/subdocument_error_context.hxx +4 -2
- data/ext/couchbase/couchbase/term_facet.hxx +48 -0
- data/ext/couchbase/couchbase/term_facet_result.hxx +55 -0
- data/ext/couchbase/couchbase/term_query.hxx +151 -0
- data/ext/couchbase/couchbase/term_range_query.hxx +142 -0
- data/ext/couchbase/couchbase/touch_options.hxx +2 -2
- data/ext/couchbase/couchbase/tracing/request_span.hxx +63 -0
- data/ext/couchbase/couchbase/tracing/request_tracer.hxx +2 -40
- data/ext/couchbase/couchbase/transactions/async_attempt_context.hxx +83 -4
- data/ext/couchbase/couchbase/transactions/attempt_context.hxx +67 -0
- data/ext/couchbase/couchbase/transactions/transaction_get_result.hxx +2 -0
- data/ext/couchbase/couchbase/transactions/transaction_keyspace.hxx +11 -1
- data/ext/couchbase/couchbase/transactions/transaction_options.hxx +79 -8
- data/ext/couchbase/couchbase/transactions/transaction_query_options.hxx +128 -15
- data/ext/couchbase/couchbase/transactions/transaction_query_result.hxx +4 -0
- data/ext/couchbase/couchbase/transactions/transaction_result.hxx +1 -1
- data/ext/couchbase/couchbase/transactions/transactions_cleanup_config.hxx +5 -3
- data/ext/couchbase/couchbase/transactions/transactions_config.hxx +9 -5
- data/ext/couchbase/couchbase/transactions/transactions_query_config.hxx +6 -3
- data/ext/couchbase/couchbase/transactions.hxx +34 -1
- data/ext/couchbase/couchbase/unlock_options.hxx +2 -2
- data/ext/couchbase/couchbase/update_bucket_options.hxx +41 -0
- data/ext/couchbase/couchbase/upsert_options.hxx +3 -3
- data/ext/couchbase/couchbase/watch_query_indexes_options.hxx +0 -31
- data/ext/couchbase/couchbase/wildcard_query.hxx +83 -0
- data/ext/couchbase/test/CMakeLists.txt +8 -5
- data/ext/couchbase/test/benchmark_helper_integration.hxx +2 -2
- data/ext/couchbase/test/test_helper.hxx +5 -5
- data/ext/couchbase/test/test_integration_analytics.cxx +28 -6
- data/ext/couchbase/test/test_integration_collections.cxx +13 -3
- data/ext/couchbase/test/test_integration_connect.cxx +7 -3
- data/ext/couchbase/test/test_integration_crud.cxx +18 -3
- data/ext/couchbase/test/test_integration_diagnostics.cxx +11 -5
- data/ext/couchbase/test/test_integration_durability.cxx +12 -7
- data/ext/couchbase/test/test_integration_examples.cxx +419 -11
- data/ext/couchbase/test/test_integration_management.cxx +867 -368
- data/ext/couchbase/test/test_integration_query.cxx +87 -17
- data/ext/couchbase/test/test_integration_range_scan.cxx +363 -124
- data/ext/couchbase/test/test_integration_read_replica.cxx +48 -11
- data/ext/couchbase/test/test_integration_search.cxx +32 -3
- data/ext/couchbase/test/test_integration_subdoc.cxx +717 -11
- data/ext/couchbase/test/test_integration_tracer.cxx +5 -0
- data/ext/couchbase/test/test_integration_transcoders.cxx +13 -5
- data/ext/couchbase/test/{test_transaction_transaction_context.cxx → test_transaction_context.cxx} +1 -1
- data/ext/couchbase/test/test_transaction_examples.cxx +195 -0
- data/ext/couchbase/test/{test_transaction_transaction_public_async_api.cxx → test_transaction_public_async_api.cxx} +13 -12
- data/ext/couchbase/test/{test_transaction_transaction_public_blocking_api.cxx → test_transaction_public_blocking_api.cxx} +27 -21
- data/ext/couchbase/test/{test_transaction_transaction_simple.cxx → test_transaction_simple.cxx} +17 -5
- data/ext/couchbase/test/{test_transaction_transaction_simple_async.cxx → test_transaction_simple_async.cxx} +19 -21
- data/ext/couchbase/test/test_unit_config_profiles.cxx +1 -1
- data/ext/couchbase/test/test_unit_connection_string.cxx +29 -0
- data/ext/couchbase/test/test_unit_json_transcoder.cxx +4 -0
- data/ext/couchbase/test/test_unit_query.cxx +75 -0
- data/ext/couchbase/test/test_unit_search.cxx +427 -0
- data/ext/couchbase/test/test_unit_transaction_utils.cxx +10 -1
- data/ext/couchbase/test/test_unit_utils.cxx +8 -4
- data/ext/couchbase.cxx +641 -45
- data/ext/revisions.rb +3 -3
- data/lib/couchbase/authenticator.rb +0 -1
- data/lib/couchbase/cluster.rb +1 -5
- data/lib/couchbase/collection.rb +108 -0
- data/lib/couchbase/collection_options.rb +100 -0
- data/lib/couchbase/config_profiles.rb +1 -1
- data/lib/couchbase/errors.rb +5 -0
- data/lib/couchbase/json_transcoder.rb +12 -5
- data/lib/couchbase/key_value_scan.rb +125 -0
- data/lib/couchbase/management/collection_query_index_manager.rb +54 -15
- data/lib/couchbase/management/query_index_manager.rb +70 -5
- data/lib/couchbase/options.rb +151 -0
- data/lib/couchbase/raw_binary_transcoder.rb +37 -0
- data/lib/couchbase/raw_json_transcoder.rb +38 -0
- data/lib/couchbase/raw_string_transcoder.rb +40 -0
- data/lib/couchbase/scope.rb +1 -1
- data/lib/couchbase/search_options.rb +5 -0
- data/lib/couchbase/transcoder_flags.rb +62 -0
- data/lib/couchbase/utils/time.rb +14 -1
- data/lib/couchbase/version.rb +1 -1
- metadata +175 -13
- data/ext/couchbase/core/config_profile.cxx +0 -47
- data/ext/couchbase/core/impl/collection_query_index_manager.cxx +0 -93
|
@@ -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,81 +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_with_hostname(hostname)) {
|
|
319
|
-
CB_LOG_TRACE(
|
|
320
|
-
R"({} requested to restart session, but the node has been ejected from current configuration already. idx={}, address="{}:{}")",
|
|
321
|
-
log_prefix_,
|
|
322
|
-
index,
|
|
323
|
-
hostname,
|
|
324
|
-
port);
|
|
325
|
-
return;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
couchbase::core::origin origin(origin_.credentials(), hostname, port, origin_.options());
|
|
329
289
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
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];
|
|
333
293
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
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="{}:{}")",
|
|
348
344
|
log_prefix_,
|
|
349
|
-
|
|
350
|
-
|
|
345
|
+
config_->rev_str(),
|
|
346
|
+
node.index,
|
|
351
347
|
session.id(),
|
|
352
348
|
hostname,
|
|
353
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;
|
|
354
363
|
}
|
|
364
|
+
}
|
|
355
365
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
});
|
|
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
|
+
}
|
|
375
384
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
true);
|
|
380
|
-
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
|
+
}
|
|
381
388
|
}
|
|
382
389
|
|
|
383
390
|
void bootstrap(utils::movable_function<void(std::error_code, topology::configuration)>&& handler)
|
|
@@ -392,15 +399,11 @@ class bucket_impl
|
|
|
392
399
|
topology::configuration cfg) mutable {
|
|
393
400
|
if (ec) {
|
|
394
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());
|
|
395
403
|
} else {
|
|
396
404
|
const std::size_t this_index = new_session.index();
|
|
397
405
|
new_session.on_configuration_update(self);
|
|
398
|
-
new_session.on_stop([
|
|
399
|
-
retry_reason reason) {
|
|
400
|
-
if (reason == retry_reason::socket_closed_while_in_flight) {
|
|
401
|
-
self->restart_node(this_index, hostname, port);
|
|
402
|
-
}
|
|
403
|
-
});
|
|
406
|
+
new_session.on_stop([id = new_session.id(), self]() { self->remove_session(id); });
|
|
404
407
|
|
|
405
408
|
{
|
|
406
409
|
std::scoped_lock lock(self->sessions_mutex_);
|
|
@@ -454,6 +457,9 @@ class bucket_impl
|
|
|
454
457
|
std::scoped_lock lock(deferred_commands_mutex_);
|
|
455
458
|
std::swap(deferred_commands_, commands);
|
|
456
459
|
}
|
|
460
|
+
if (!commands.empty()) {
|
|
461
|
+
CB_LOG_TRACE(R"({} draining deferred operation queue, size={})", log_prefix_, commands.size());
|
|
462
|
+
}
|
|
457
463
|
while (!commands.empty()) {
|
|
458
464
|
commands.front()();
|
|
459
465
|
commands.pop();
|
|
@@ -488,9 +494,33 @@ class bucket_impl
|
|
|
488
494
|
}
|
|
489
495
|
}
|
|
490
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
|
+
|
|
491
522
|
void update_config(topology::configuration config) override
|
|
492
523
|
{
|
|
493
|
-
bool forced_config = false;
|
|
494
524
|
std::vector<topology::configuration::node> added{};
|
|
495
525
|
std::vector<topology::configuration::node> removed{};
|
|
496
526
|
{
|
|
@@ -499,7 +529,6 @@ class bucket_impl
|
|
|
499
529
|
CB_LOG_DEBUG("{} initialize configuration rev={}", log_prefix_, config.rev_str());
|
|
500
530
|
} else if (config.force) {
|
|
501
531
|
CB_LOG_DEBUG("{} forced to accept configuration rev={}", log_prefix_, config.rev_str());
|
|
502
|
-
forced_config = true;
|
|
503
532
|
} else if (!config.vbmap) {
|
|
504
533
|
CB_LOG_DEBUG("{} will not update the configuration old={} -> new={}, because new config does not have partition map",
|
|
505
534
|
log_prefix_,
|
|
@@ -532,78 +561,81 @@ class bucket_impl
|
|
|
532
561
|
std::scoped_lock lock(sessions_mutex_);
|
|
533
562
|
std::map<size_t, io::mcbp_session> new_sessions{};
|
|
534
563
|
|
|
535
|
-
|
|
536
|
-
std::size_t new_index = config.nodes.size() + 1;
|
|
537
|
-
for (const auto& node : config.nodes) {
|
|
538
|
-
if (session.bootstrap_hostname() == node.hostname_for(origin_.options().network) &&
|
|
539
|
-
session.bootstrap_port() ==
|
|
540
|
-
std::to_string(
|
|
541
|
-
node.port_or(origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0))) {
|
|
542
|
-
new_index = node.index;
|
|
543
|
-
break;
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
if (new_index < config.nodes.size()) {
|
|
547
|
-
CB_LOG_DEBUG(R"({} rev={}, preserve session="{}", address="{}:{}", index={}->{})",
|
|
548
|
-
log_prefix_,
|
|
549
|
-
config.rev_str(),
|
|
550
|
-
session.id(),
|
|
551
|
-
session.bootstrap_hostname(),
|
|
552
|
-
session.bootstrap_port(),
|
|
553
|
-
index,
|
|
554
|
-
new_index);
|
|
555
|
-
new_sessions.insert_or_assign(new_index, std::move(session));
|
|
556
|
-
} else {
|
|
557
|
-
CB_LOG_DEBUG(R"({} rev={}, drop session="{}", address="{}:{}", index={})",
|
|
558
|
-
log_prefix_,
|
|
559
|
-
config.rev_str(),
|
|
560
|
-
session.id(),
|
|
561
|
-
session.bootstrap_hostname(),
|
|
562
|
-
session.bootstrap_port(),
|
|
563
|
-
index);
|
|
564
|
-
asio::post(asio::bind_executor(
|
|
565
|
-
ctx_, [session = std::move(session)]() mutable { return session.stop(retry_reason::do_not_retry); }));
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
|
|
564
|
+
std::size_t next_index{ 0 };
|
|
569
565
|
for (const auto& node : config.nodes) {
|
|
570
|
-
if (new_sessions.find(node.index) != new_sessions.end()) {
|
|
571
|
-
continue;
|
|
572
|
-
}
|
|
573
|
-
|
|
574
566
|
const auto& hostname = node.hostname_for(origin_.options().network);
|
|
575
567
|
auto port = node.port_or(origin_.options().network, service_type::key_value, origin_.options().enable_tls, 0);
|
|
576
568
|
if (port == 0) {
|
|
577
569
|
continue;
|
|
578
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
|
+
|
|
579
594
|
couchbase::core::origin origin(origin_.credentials(), hostname, port, origin_.options());
|
|
580
595
|
io::mcbp_session session = origin_.options().enable_tls
|
|
581
596
|
? io::mcbp_session(client_id_, ctx_, tls_, origin, state_listener_, name_, known_features_)
|
|
582
597
|
: io::mcbp_session(client_id_, ctx_, origin, state_listener_, name_, known_features_);
|
|
583
|
-
CB_LOG_DEBUG(
|
|
584
|
-
|
|
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);
|
|
585
605
|
session.bootstrap(
|
|
586
|
-
[self = shared_from_this(), session,
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
}
|
|
597
|
-
});
|
|
598
|
-
self->drain_deferred_queue();
|
|
599
|
-
} else if (err == errc::common::unambiguous_timeout && forced_config) {
|
|
600
|
-
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());
|
|
601
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();
|
|
602
621
|
},
|
|
603
622
|
true);
|
|
604
|
-
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); }));
|
|
605
638
|
}
|
|
606
|
-
sessions_ = new_sessions;
|
|
607
639
|
}
|
|
608
640
|
}
|
|
609
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)));
|
|
@@ -106,6 +106,8 @@ class bucket
|
|
|
106
106
|
} else {
|
|
107
107
|
auto [partition, server] = map_id(cmd->request.id);
|
|
108
108
|
if (!server.has_value()) {
|
|
109
|
+
CB_LOG_TRACE(
|
|
110
|
+
R"({} unable to map key="{}" to the node, id={}, partition={})", log_prefix(), cmd->request.id, cmd->id_, partition);
|
|
109
111
|
return io::retry_orchestrator::maybe_retry(
|
|
110
112
|
cmd->manager_, cmd, retry_reason::node_not_available, errc::common::request_canceled);
|
|
111
113
|
}
|
|
@@ -114,12 +116,32 @@ class bucket
|
|
|
114
116
|
}
|
|
115
117
|
auto session = find_session_by_index(index);
|
|
116
118
|
if (!session || !session->has_config()) {
|
|
119
|
+
CB_LOG_TRACE(R"({} defer operation id={}, key="{}", partition={}, index={}, session={}, address="{}", has_config={})",
|
|
120
|
+
log_prefix(),
|
|
121
|
+
cmd->id_,
|
|
122
|
+
cmd->request.id,
|
|
123
|
+
cmd->request.partition,
|
|
124
|
+
index,
|
|
125
|
+
session.has_value(),
|
|
126
|
+
session.has_value() ? session->bootstrap_address() : "",
|
|
127
|
+
session.has_value() && session->has_config());
|
|
117
128
|
return defer_command([self = shared_from_this(), cmd]() { self->map_and_send(cmd); });
|
|
118
129
|
}
|
|
119
130
|
if (session->is_stopped()) {
|
|
131
|
+
CB_LOG_TRACE(
|
|
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());
|
|
120
140
|
return io::retry_orchestrator::maybe_retry(
|
|
121
141
|
cmd->manager_, cmd, retry_reason::node_not_available, errc::common::request_canceled);
|
|
122
142
|
}
|
|
143
|
+
cmd->last_dispatched_from_ = session->local_address();
|
|
144
|
+
cmd->last_dispatched_to_ = session->bootstrap_address();
|
|
123
145
|
cmd->send_to(session.value());
|
|
124
146
|
}
|
|
125
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
|
|
|
@@ -78,6 +79,7 @@ class cluster : public std::enable_shared_from_this<cluster>
|
|
|
78
79
|
}
|
|
79
80
|
|
|
80
81
|
origin_ = std::move(origin);
|
|
82
|
+
CB_LOG_DEBUG(R"(open cluster, id: "{}", core version: "{}", {})", id_, couchbase::core::meta::sdk_semver(), origin_.to_json());
|
|
81
83
|
// ignore the enable_tracing flag if a tracer was passed in
|
|
82
84
|
if (nullptr != origin_.options().tracer) {
|
|
83
85
|
tracer_ = origin_.options().tracer;
|
|
@@ -110,10 +112,7 @@ class cluster : public std::enable_shared_from_this<cluster>
|
|
|
110
112
|
return self->dns_srv_tracker_->get_srv_nodes(
|
|
111
113
|
[self, hostname = std::move(hostname), handler = std::forward<Handler>(handler)](origin::node_list nodes,
|
|
112
114
|
std::error_code ec) mutable {
|
|
113
|
-
if (ec) {
|
|
114
|
-
return self->close([ec, handler = std::forward<Handler>(handler)]() mutable { handler(ec); });
|
|
115
|
-
}
|
|
116
|
-
if (!nodes.empty()) {
|
|
115
|
+
if (!ec && !nodes.empty()) {
|
|
117
116
|
self->origin_.set_nodes(std::move(nodes));
|
|
118
117
|
CB_LOG_INFO("replace list of bootstrap nodes with addresses from DNS SRV of \"{}\": [{}]",
|
|
119
118
|
hostname,
|
|
@@ -338,8 +337,8 @@ class cluster : public std::enable_shared_from_this<cluster>
|
|
|
338
337
|
void do_open(Handler&& handler)
|
|
339
338
|
{
|
|
340
339
|
// Warn users if they attempt to use Capella without TLS being enabled.
|
|
340
|
+
bool has_capella_host = false;
|
|
341
341
|
{
|
|
342
|
-
bool has_capella_host = false;
|
|
343
342
|
bool has_non_capella_host = false;
|
|
344
343
|
static std::string suffix = "cloud.couchbase.com";
|
|
345
344
|
for (const auto& node : origin_.get_hostnames()) {
|
|
@@ -358,6 +357,7 @@ class cluster : public std::enable_shared_from_this<cluster>
|
|
|
358
357
|
|
|
359
358
|
if (origin_.options().enable_tls /* TLS is enabled */
|
|
360
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 */
|
|
361
361
|
&& origin_.options().tls_verify != tls_verify_mode::none /* The user did not disable all TLS verification */
|
|
362
362
|
&& has_non_capella_host /* The connection string has a hostname that does NOT end in ".cloud.couchbase.com" */) {
|
|
363
363
|
CB_LOG_WARNING("[{}] When TLS is enabled, the cluster options must specify certificate(s) to trust or ensure that they are "
|
|
@@ -367,7 +367,17 @@ class cluster : public std::enable_shared_from_this<cluster>
|
|
|
367
367
|
}
|
|
368
368
|
|
|
369
369
|
if (origin_.options().enable_tls) {
|
|
370
|
-
|
|
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);
|
|
371
381
|
switch (origin_.options().tls_verify) {
|
|
372
382
|
case tls_verify_mode::none:
|
|
373
383
|
tls_.set_verify_mode(asio::ssl::verify_none);
|
|
@@ -377,7 +387,8 @@ class cluster : public std::enable_shared_from_this<cluster>
|
|
|
377
387
|
tls_.set_verify_mode(asio::ssl::verify_peer);
|
|
378
388
|
break;
|
|
379
389
|
}
|
|
380
|
-
if (origin_.options().trust_certificate.empty()
|
|
390
|
+
if (origin_.options().trust_certificate.empty() &&
|
|
391
|
+
origin_.options().trust_certificate_value.empty()) { // trust certificate is not explicitly specified
|
|
381
392
|
CB_LOG_DEBUG(R"([{}]: use default CA for TLS verify)", id_);
|
|
382
393
|
std::error_code ec{};
|
|
383
394
|
|
|
@@ -394,15 +405,41 @@ class cluster : public std::enable_shared_from_this<cluster>
|
|
|
394
405
|
CB_LOG_WARNING("[{}]: unable to load default CAs: {}", id_, ec.message());
|
|
395
406
|
// we don't consider this fatal and try to continue without it
|
|
396
407
|
}
|
|
408
|
+
|
|
409
|
+
if (const auto certificates = default_ca::mozilla_ca_certs();
|
|
410
|
+
!origin_.options().disable_mozilla_ca_certificates && !certificates.empty()) {
|
|
411
|
+
CB_LOG_DEBUG("[{}]: loading {} CA certificates from Mozilla bundle. Update date: \"{}\", SHA256: \"{}\"",
|
|
412
|
+
id_,
|
|
413
|
+
certificates.size(),
|
|
414
|
+
default_ca::mozilla_ca_certs_date(),
|
|
415
|
+
default_ca::mozilla_ca_certs_sha256());
|
|
416
|
+
for (const auto& cert : certificates) {
|
|
417
|
+
tls_.add_certificate_authority(asio::const_buffer(cert.body.data(), cert.body.size()), ec);
|
|
418
|
+
if (ec) {
|
|
419
|
+
CB_LOG_WARNING("[{}]: unable to load CA \"{}\" from Mozilla bundle: {}", id_, cert.authority, ec.message());
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
397
423
|
} else { // trust certificate is explicitly specified
|
|
398
424
|
std::error_code ec{};
|
|
399
425
|
// load only the explicit certificate
|
|
400
426
|
// system and default capella certificates are not loaded
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
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
|
+
}
|
|
406
443
|
}
|
|
407
444
|
}
|
|
408
445
|
#ifdef COUCHBASE_CXX_CLIENT_TLS_KEY_LOG_FILE
|
|
@@ -430,6 +467,7 @@ class cluster : public std::enable_shared_from_this<cluster>
|
|
|
430
467
|
return close([ec, handler = std::forward<Handler>(handler)]() mutable { return handler(ec); });
|
|
431
468
|
}
|
|
432
469
|
}
|
|
470
|
+
|
|
433
471
|
session_ = io::mcbp_session(id_, ctx_, tls_, origin_, dns_srv_tracker_);
|
|
434
472
|
} else {
|
|
435
473
|
session_ = io::mcbp_session(id_, ctx_, origin_, dns_srv_tracker_);
|
|
@@ -466,7 +504,7 @@ class cluster : public std::enable_shared_from_this<cluster>
|
|
|
466
504
|
}
|
|
467
505
|
self->session_manager_->set_configuration(config, self->origin_.options());
|
|
468
506
|
self->session_->on_configuration_update(self->session_manager_);
|
|
469
|
-
self->session_->on_stop([self](
|
|
507
|
+
self->session_->on_stop([self]() {
|
|
470
508
|
if (self->session_) {
|
|
471
509
|
self->session_.reset();
|
|
472
510
|
}
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
#include "cluster_options.hxx"
|
|
19
|
-
#include "
|
|
19
|
+
#include "config_profiles.hxx"
|
|
20
20
|
#include <stdexcept>
|
|
21
21
|
|
|
22
22
|
namespace couchbase::core
|
|
@@ -45,6 +45,6 @@ cluster_options::default_timeout_for(service_type type) const
|
|
|
45
45
|
void
|
|
46
46
|
cluster_options::apply_profile(std::string profile_name)
|
|
47
47
|
{
|
|
48
|
-
|
|
48
|
+
known_profiles().apply(profile_name, *this);
|
|
49
49
|
}
|
|
50
50
|
} // namespace couchbase::core
|