neo4j-ruby-driver 1.7.5 → 4.4.0.alpha.2
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 +26 -42
- data/lib/loader.rb +5 -3
- data/lib/neo4j/driver/auto_closable.rb +2 -2
- data/lib/neo4j/driver/exceptions/authentication_exception.rb +6 -1
- data/lib/neo4j/driver/exceptions/authorization_expired_exception.rb +14 -0
- data/lib/neo4j/driver/{types/bytes.rb → exceptions/certificate_exception.rb} +2 -2
- data/lib/neo4j/driver/exceptions/client_exception.rb +3 -0
- data/lib/neo4j/driver/exceptions/connection_read_timeout_exception.rb +14 -0
- data/lib/neo4j/driver/exceptions/database_exception.rb +3 -0
- data/lib/neo4j/driver/exceptions/discovery_exception.rb +16 -0
- data/lib/neo4j/driver/exceptions/fatal_discovery_exception.rb +13 -0
- data/lib/neo4j/driver/exceptions/protocol_exception.rb +7 -0
- data/lib/neo4j/driver/exceptions/result_consumed_exception.rb +13 -0
- data/lib/neo4j/driver/exceptions/security_exception.rb +5 -1
- data/lib/neo4j/driver/exceptions/service_unavailable_exception.rb +2 -0
- data/lib/neo4j/driver/exceptions/session_expired_exception.rb +4 -0
- data/lib/neo4j/driver/exceptions/token_expired_exception.rb +15 -0
- data/lib/neo4j/driver/exceptions/transaction_nesting_exception.rb +11 -0
- data/lib/neo4j/driver/exceptions/transient_exception.rb +3 -0
- data/lib/neo4j/driver/exceptions/untrusted_server_exception.rb +1 -0
- data/lib/neo4j/driver/exceptions/value/lossy_coercion.rb +15 -0
- data/lib/neo4j/driver/exceptions/value/not_multi_valued.rb +13 -0
- data/lib/neo4j/driver/exceptions/value/uncoercible.rb +15 -0
- data/lib/neo4j/driver/exceptions/value/unsizable.rb +12 -0
- data/lib/neo4j/driver/exceptions/value/value_exception.rb +12 -0
- data/lib/neo4j/driver/internal/bolt_server_address.rb +97 -0
- data/lib/neo4j/driver/internal/duration_normalizer.rb +1 -1
- data/lib/neo4j/driver/internal/validator.rb +5 -4
- data/{ffi/neo4j/driver/summary/statement_type.rb → lib/neo4j/driver/summary/query_type.rb} +1 -3
- data/lib/neo4j/driver/synchronizable.rb +23 -0
- data/lib/neo4j_ruby_driver.rb +5 -10
- data/{ffi → ruby}/neo4j/driver/access_mode.rb +2 -2
- data/ruby/neo4j/driver/auth_tokens.rb +34 -0
- data/ruby/neo4j/driver/bookmark.rb +21 -0
- data/ruby/neo4j/driver/config.rb +91 -0
- data/ruby/neo4j/driver/graph_database.rb +140 -0
- data/ruby/neo4j/driver/internal/async/connection/bolt_protocol_util.rb +51 -0
- data/ruby/neo4j/driver/internal/async/connection/bootstrap_factory.rb +22 -0
- data/ruby/neo4j/driver/internal/async/connection/channel_attributes.rb +31 -0
- data/ruby/neo4j/driver/internal/async/connection/channel_connected_listener.rb +32 -0
- data/ruby/neo4j/driver/internal/async/connection/channel_connector_impl.rb +77 -0
- data/ruby/neo4j/driver/internal/async/connection/channel_pipeline_builder_impl.rb +22 -0
- data/ruby/neo4j/driver/internal/async/connection/direct_connection.rb +30 -0
- data/ruby/neo4j/driver/internal/async/connection/event_loop_group_factory.rb +83 -0
- data/ruby/neo4j/driver/internal/async/connection/handshake_completed_listener.rb +27 -0
- data/ruby/neo4j/driver/internal/async/connection/handshake_handler.rb +113 -0
- data/ruby/neo4j/driver/internal/async/connection/netty_channel_initializer.rb +57 -0
- data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver.rb +26 -0
- data/ruby/neo4j/driver/internal/async/connection/netty_domain_name_resolver_group.rb +19 -0
- data/ruby/neo4j/driver/internal/async/connection/routing_connection.rb +36 -0
- data/ruby/neo4j/driver/internal/async/connection/stream.rb +12 -0
- data/ruby/neo4j/driver/internal/async/connection/stream_reader.rb +16 -0
- data/ruby/neo4j/driver/internal/async/connection_context.rb +10 -0
- data/ruby/neo4j/driver/internal/async/immutable_connection_context.rb +24 -0
- data/ruby/neo4j/driver/internal/async/inbound/byte_buf_input.rb +30 -0
- data/ruby/neo4j/driver/internal/async/inbound/channel_error_handler.rb +77 -0
- data/ruby/neo4j/driver/internal/async/inbound/chunk_decoder.rb +41 -0
- data/ruby/neo4j/driver/internal/async/inbound/connect_timeout_handler.rb +32 -0
- data/ruby/neo4j/driver/internal/async/inbound/connection_read_timeout_handler.rb +17 -0
- data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +172 -0
- data/ruby/neo4j/driver/internal/async/inbound/inbound_message_handler.rb +42 -0
- data/ruby/neo4j/driver/internal/async/inbound/message_decoder.rb +51 -0
- data/ruby/neo4j/driver/internal/async/internal_async_session.rb +98 -0
- data/ruby/neo4j/driver/internal/async/internal_async_transaction.rb +13 -0
- data/ruby/neo4j/driver/internal/async/leak_logging_network_session.rb +34 -0
- data/ruby/neo4j/driver/internal/async/network_connection.rb +196 -0
- data/ruby/neo4j/driver/internal/async/network_session.rb +152 -0
- data/ruby/neo4j/driver/internal/async/outbound/chunk_aware_byte_buf_output.rb +110 -0
- data/ruby/neo4j/driver/internal/async/outbound/outbound_message_handler.rb +39 -0
- data/ruby/neo4j/driver/internal/async/pool/channel.rb +63 -0
- data/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb +149 -0
- data/ruby/neo4j/driver/internal/async/pool/controller.rb +25 -0
- data/ruby/neo4j/driver/internal/async/pool/netty_channel_health_checker.rb +87 -0
- data/ruby/neo4j/driver/internal/async/pool/netty_channel_pool.rb +52 -0
- data/ruby/neo4j/driver/internal/async/pool/netty_channel_tracker.rb +137 -0
- data/ruby/neo4j/driver/internal/async/pool/network_connection_factory.rb +21 -0
- data/ruby/neo4j/driver/internal/async/pool/pool_settings.rb +34 -0
- data/ruby/neo4j/driver/internal/async/result_cursors_holder.rb +17 -0
- data/ruby/neo4j/driver/internal/async/unmanaged_transaction.rb +214 -0
- data/ruby/neo4j/driver/internal/bookmark_holder.rb +9 -0
- data/ruby/neo4j/driver/internal/cluster/cluster_composition.rb +58 -0
- data/ruby/neo4j/driver/internal/cluster/cluster_composition_lookup_result.rb +14 -0
- data/ruby/neo4j/driver/internal/cluster/cluster_routing_table.rb +139 -0
- data/ruby/neo4j/driver/internal/cluster/identity_resolver.rb +13 -0
- data/ruby/neo4j/driver/internal/cluster/loadbalancing/least_connected_load_balancing_strategy.rb +68 -0
- data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +159 -0
- data/ruby/neo4j/driver/internal/cluster/loadbalancing/round_robin_array_index.rb +13 -0
- data/ruby/neo4j/driver/internal/cluster/multi_databases_routing_procedure_runner.rb +34 -0
- data/ruby/neo4j/driver/internal/cluster/rediscovery_impl.rb +238 -0
- data/ruby/neo4j/driver/internal/cluster/route_message_routing_procedure_runner.rb +43 -0
- data/ruby/neo4j/driver/internal/cluster/routing_context.rb +77 -0
- data/ruby/neo4j/driver/internal/cluster/routing_procedure_cluster_composition_provider.rb +64 -0
- data/ruby/neo4j/driver/internal/cluster/routing_procedure_response.rb +19 -0
- data/ruby/neo4j/driver/internal/cluster/routing_settings.rb +24 -0
- data/ruby/neo4j/driver/internal/cluster/routing_table_handler_impl.rb +116 -0
- data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +140 -0
- data/ruby/neo4j/driver/internal/cluster/single_database_routing_procedure_runner.rb +76 -0
- data/ruby/neo4j/driver/internal/connection_settings.rb +16 -0
- data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +76 -0
- data/ruby/neo4j/driver/internal/cursor/async_result_cursor_only_factory.rb +29 -0
- data/ruby/neo4j/driver/internal/cursor/disposable_async_result_cursor.rb +59 -0
- data/ruby/neo4j/driver/internal/cursor/result_cursor_factory_impl.rb +29 -0
- data/ruby/neo4j/driver/internal/cursor/rx_result_cursor_impl.rb +110 -0
- data/ruby/neo4j/driver/internal/database_name.rb +12 -0
- data/ruby/neo4j/driver/internal/database_name_util.rb +37 -0
- data/ruby/neo4j/driver/internal/default_bookmark_holder.rb +15 -0
- data/ruby/neo4j/driver/internal/default_domain_name_resolver.rb +11 -0
- data/ruby/neo4j/driver/internal/direct_connection_provider.rb +40 -0
- data/ruby/neo4j/driver/internal/driver_factory.rb +127 -0
- data/ruby/neo4j/driver/internal/handlers/begin_tx_response_handler.rb +20 -0
- data/ruby/neo4j/driver/internal/handlers/channel_releasing_reset_response_handler.rb +29 -0
- data/ruby/neo4j/driver/internal/handlers/commit_tx_response_handler.rb +25 -0
- data/ruby/neo4j/driver/internal/handlers/hello_response_handler.rb +65 -0
- data/ruby/neo4j/driver/internal/handlers/init_response_handler.rb +34 -0
- data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +228 -0
- data/ruby/neo4j/driver/internal/handlers/no_op_response_handler.rb +16 -0
- data/ruby/neo4j/driver/internal/handlers/ping_response_handler.rb +29 -0
- data/ruby/neo4j/driver/internal/handlers/pull_handlers.rb +32 -0
- data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +174 -0
- data/ruby/neo4j/driver/internal/handlers/pulln/basic_pull_response_handler.rb +288 -0
- data/ruby/neo4j/driver/internal/handlers/pulln/fetch_size_util.rb +20 -0
- data/ruby/neo4j/driver/internal/handlers/reset_response_handler.rb +34 -0
- data/ruby/neo4j/driver/internal/handlers/rollback_tx_response_handler.rb +19 -0
- data/ruby/neo4j/driver/internal/handlers/route_message_response_handler.rb +21 -0
- data/ruby/neo4j/driver/internal/handlers/routing_response_handler.rb +70 -0
- data/ruby/neo4j/driver/internal/handlers/run_response_handler.rb +37 -0
- data/ruby/neo4j/driver/internal/handlers/session_pull_response_completion_listener.rb +34 -0
- data/ruby/neo4j/driver/internal/handlers/transaction_pull_response_completion_listener.rb +20 -0
- data/ruby/neo4j/driver/internal/impersonation_util.rb +22 -0
- data/ruby/neo4j/driver/internal/internal_bookmark.rb +38 -0
- data/ruby/neo4j/driver/internal/internal_database_name.rb +11 -0
- data/ruby/neo4j/driver/internal/internal_driver.rb +78 -0
- data/ruby/neo4j/driver/internal/internal_entity.rb +22 -0
- data/ruby/neo4j/driver/internal/internal_node.rb +21 -0
- data/ruby/neo4j/driver/internal/internal_pair.rb +9 -0
- data/ruby/neo4j/driver/internal/internal_path.rb +35 -0
- data/ruby/neo4j/driver/internal/internal_point2_d.rb +9 -0
- data/ruby/neo4j/driver/internal/internal_point3_d.rb +6 -0
- data/{ffi → ruby}/neo4j/driver/internal/internal_record.rb +2 -1
- data/ruby/neo4j/driver/internal/internal_relationship.rb +26 -0
- data/ruby/neo4j/driver/internal/internal_result.rb +60 -0
- data/ruby/neo4j/driver/internal/internal_session.rb +81 -0
- data/ruby/neo4j/driver/internal/internal_transaction.rb +48 -0
- data/ruby/neo4j/driver/internal/logging/channel_activity_logger.rb +29 -0
- data/ruby/neo4j/driver/internal/logging/channel_error_logger.rb +17 -0
- data/ruby/neo4j/driver/internal/logging/prefixed_logger.rb +19 -0
- data/ruby/neo4j/driver/internal/logging/reformatted_logger.rb +17 -0
- data/ruby/neo4j/driver/internal/messaging/abstract_message_writer.rb +23 -0
- data/ruby/neo4j/driver/internal/messaging/bolt_protocol.rb +30 -0
- data/ruby/neo4j/driver/internal/messaging/bolt_protocol_version.rb +46 -0
- data/ruby/neo4j/driver/internal/messaging/common/common_message_reader.rb +51 -0
- data/ruby/neo4j/driver/internal/messaging/common/common_value.rb +31 -0
- data/ruby/neo4j/driver/internal/messaging/common/common_value_packer.rb +101 -0
- data/ruby/neo4j/driver/internal/messaging/common/common_value_unpacker.rb +234 -0
- data/ruby/neo4j/driver/internal/messaging/encode/begin_message_encoder.rb +15 -0
- data/ruby/neo4j/driver/internal/messaging/encode/commit_message_encoder.rb +14 -0
- data/ruby/neo4j/driver/internal/messaging/encode/discard_all_message_encoder.rb +14 -0
- data/ruby/neo4j/driver/internal/messaging/encode/discard_message_encoder.rb +15 -0
- data/ruby/neo4j/driver/internal/messaging/encode/goodbye_message_encoder.rb +14 -0
- data/ruby/neo4j/driver/internal/messaging/encode/hello_message_encoder.rb +15 -0
- data/ruby/neo4j/driver/internal/messaging/encode/init_message_encoder.rb +16 -0
- data/ruby/neo4j/driver/internal/messaging/encode/pull_all_message_encoder.rb +14 -0
- data/ruby/neo4j/driver/internal/messaging/encode/pull_message_encoder.rb +15 -0
- data/ruby/neo4j/driver/internal/messaging/encode/reset_message_encoder.rb +14 -0
- data/ruby/neo4j/driver/internal/messaging/encode/rollback_message_encoder.rb +14 -0
- data/ruby/neo4j/driver/internal/messaging/encode/route_message_encoder.rb +18 -0
- data/ruby/neo4j/driver/internal/messaging/encode/route_v44_message_encoder.rb +27 -0
- data/ruby/neo4j/driver/internal/messaging/encode/run_message_encoder.rb +16 -0
- data/ruby/neo4j/driver/internal/messaging/encode/run_with_metadata_message_encoder.rb +17 -0
- data/ruby/neo4j/driver/internal/messaging/request/abstract_streaming_message.rb +22 -0
- data/ruby/neo4j/driver/internal/messaging/request/begin_message.rb +26 -0
- data/ruby/neo4j/driver/internal/messaging/request/commit_message.rb +20 -0
- data/ruby/neo4j/driver/internal/messaging/request/discard_all_message.rb +20 -0
- data/ruby/neo4j/driver/internal/messaging/request/discard_message.rb +23 -0
- data/ruby/neo4j/driver/internal/messaging/request/goodbye_message.rb +20 -0
- data/ruby/neo4j/driver/internal/messaging/request/hello_message.rb +31 -0
- data/ruby/neo4j/driver/internal/messaging/request/init_message.rb +19 -0
- data/ruby/neo4j/driver/internal/messaging/request/message_with_metadata.rb +10 -0
- data/ruby/neo4j/driver/internal/messaging/request/multi_database_util.rb +26 -0
- data/ruby/neo4j/driver/internal/messaging/request/pull_all_message.rb +23 -0
- data/ruby/neo4j/driver/internal/messaging/request/pull_message.rb +22 -0
- data/ruby/neo4j/driver/internal/messaging/request/reset_message.rb +32 -0
- data/ruby/neo4j/driver/internal/messaging/request/rollback_message.rb +20 -0
- data/ruby/neo4j/driver/internal/messaging/request/route_message.rb +33 -0
- data/ruby/neo4j/driver/internal/messaging/request/run_message.rb +23 -0
- data/ruby/neo4j/driver/internal/messaging/request/run_with_metadata_message.rb +47 -0
- data/ruby/neo4j/driver/internal/messaging/request/transaction_metadata_builder.rb +24 -0
- data/ruby/neo4j/driver/internal/messaging/response/failure_message.rb +40 -0
- data/ruby/neo4j/driver/internal/messaging/response/ignored_message.rb +29 -0
- data/ruby/neo4j/driver/internal/messaging/response/record_message.rb +33 -0
- data/ruby/neo4j/driver/internal/messaging/response/success_message.rb +34 -0
- data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +79 -0
- data/ruby/neo4j/driver/internal/messaging/v3/message_format_v3.rb +17 -0
- data/ruby/neo4j/driver/internal/messaging/v3/message_writer_v3.rb +27 -0
- data/ruby/neo4j/driver/internal/messaging/v4/bolt_protocol_v4.rb +29 -0
- data/ruby/neo4j/driver/internal/messaging/v4/message_format_v4.rb +17 -0
- data/ruby/neo4j/driver/internal/messaging/v4/message_writer_v4.rb +28 -0
- data/ruby/neo4j/driver/internal/messaging/v41/bolt_protocol_v41.rb +25 -0
- data/ruby/neo4j/driver/internal/messaging/v42/bolt_protocol_v42.rb +13 -0
- data/ruby/neo4j/driver/internal/messaging/v43/bolt_protocol_v43.rb +19 -0
- data/ruby/neo4j/driver/internal/messaging/v43/message_format_v43.rb +18 -0
- data/ruby/neo4j/driver/internal/messaging/v43/message_writer_v43.rb +34 -0
- data/ruby/neo4j/driver/internal/messaging/v44/bolt_protocol_v44.rb +17 -0
- data/ruby/neo4j/driver/internal/messaging/v44/message_format_v44.rb +18 -0
- data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +26 -0
- data/ruby/neo4j/driver/internal/metrics/connection_pool_metrics_listener.rb +34 -0
- data/ruby/neo4j/driver/internal/metrics/internal_abstract_metrics.rb +46 -0
- data/ruby/neo4j/driver/internal/metrics/internal_connection_pool_metrics.rb +105 -0
- data/ruby/neo4j/driver/internal/metrics/internal_metrics.rb +82 -0
- data/ruby/neo4j/driver/internal/metrics/internal_metrics_provider.rb +18 -0
- data/ruby/neo4j/driver/internal/metrics/listener_event.rb +17 -0
- data/ruby/neo4j/driver/internal/metrics/metrics_provider.rb +24 -0
- data/ruby/neo4j/driver/internal/metrics/time_recorder_listener_event.rb +15 -0
- data/ruby/neo4j/driver/internal/packstream/byte_array_incompatible_packer.rb +12 -0
- data/ruby/neo4j/driver/internal/packstream/pack_input.rb +47 -0
- data/ruby/neo4j/driver/internal/packstream/pack_output.rb +39 -0
- data/ruby/neo4j/driver/internal/packstream/pack_stream.rb +326 -0
- data/ruby/neo4j/driver/internal/packstream/pack_type.rb +17 -0
- data/ruby/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +151 -0
- data/ruby/neo4j/driver/internal/revocation_strategy.rb +19 -0
- data/ruby/neo4j/driver/internal/scheme.rb +32 -0
- data/ruby/neo4j/driver/internal/security/internal_auth_token.rb +15 -0
- data/ruby/neo4j/driver/internal/security/security_plan_impl.rb +92 -0
- data/ruby/neo4j/driver/internal/security_setting.rb +73 -0
- data/ruby/neo4j/driver/internal/session_factory_impl.rb +32 -0
- data/ruby/neo4j/driver/internal/spi/connection.rb +19 -0
- data/ruby/neo4j/driver/internal/spi/connection_pool.rb +9 -0
- data/ruby/neo4j/driver/internal/spi/response_handler.rb +23 -0
- data/ruby/neo4j/driver/internal/summary/internal_database_info.rb +7 -0
- data/ruby/neo4j/driver/internal/summary/internal_input_position.rb +11 -0
- data/ruby/neo4j/driver/internal/summary/internal_notification.rb +16 -0
- data/ruby/neo4j/driver/internal/summary/internal_plan.rb +41 -0
- data/ruby/neo4j/driver/internal/summary/internal_profiled_plan.rb +32 -0
- data/ruby/neo4j/driver/internal/summary/internal_result_summary.rb +33 -0
- data/ruby/neo4j/driver/internal/summary/internal_server_info.rb +6 -0
- data/ruby/neo4j/driver/internal/summary/internal_summary_counters.rb +18 -0
- data/ruby/neo4j/driver/internal/svm/netty_substitutions.rb +196 -0
- data/ruby/neo4j/driver/internal/svm/z_lib_substitutions.rb +21 -0
- data/ruby/neo4j/driver/internal/util/certificate_tool.rb +65 -0
- data/ruby/neo4j/driver/internal/util/clock.rb +29 -0
- data/ruby/neo4j/driver/internal/util/error_util.rb +104 -0
- data/ruby/neo4j/driver/internal/util/extract.rb +123 -0
- data/ruby/neo4j/driver/internal/util/format.rb +39 -0
- data/ruby/neo4j/driver/internal/util/futures.rb +99 -0
- data/ruby/neo4j/driver/internal/util/iterables.rb +35 -0
- data/ruby/neo4j/driver/internal/util/lock_util.rb +23 -0
- data/ruby/neo4j/driver/internal/util/metadata_extractor.rb +109 -0
- data/ruby/neo4j/driver/internal/util/mutex.rb +9 -0
- data/ruby/neo4j/driver/internal/util/preconditions.rb +16 -0
- data/ruby/neo4j/driver/internal/util/server_version.rb +60 -0
- data/ruby/neo4j/driver/logging1.rb +51 -0
- data/ruby/neo4j/driver/net/server_address1.rb +9 -0
- data/ruby/neo4j/driver/query.rb +48 -0
- data/ruby/neo4j/driver/records.rb +13 -0
- data/ruby/neo4j/driver/session_config.rb +15 -0
- data/ruby/neo4j/driver/transaction_config.rb +46 -0
- data/ruby/neo4j/driver/values.rb +26 -0
- data/{lib → ruby}/neo4j/driver/version.rb +1 -1
- data/ruby/neo4j/driver.rb +30 -0
- metadata +267 -92
- data/ffi/bolt/address.rb +0 -11
- data/ffi/bolt/address_resolver.rb +0 -12
- data/ffi/bolt/address_set.rb +0 -9
- data/ffi/bolt/auth.rb +0 -10
- data/ffi/bolt/auto_releasable.rb +0 -22
- data/ffi/bolt/boolean.rb +0 -9
- data/ffi/bolt/bytes.rb +0 -10
- data/ffi/bolt/config.rb +0 -45
- data/ffi/bolt/connection.rb +0 -44
- data/ffi/bolt/connector.rb +0 -17
- data/ffi/bolt/dictionary.rb +0 -15
- data/ffi/bolt/error.rb +0 -74
- data/ffi/bolt/float.rb +0 -9
- data/ffi/bolt/integer.rb +0 -9
- data/ffi/bolt/library.rb +0 -12
- data/ffi/bolt/lifecycle.rb +0 -9
- data/ffi/bolt/list.rb +0 -10
- data/ffi/bolt/log.rb +0 -16
- data/ffi/bolt/socket_options.rb +0 -14
- data/ffi/bolt/status.rb +0 -25
- data/ffi/bolt/string.rb +0 -9
- data/ffi/bolt/structure.rb +0 -10
- data/ffi/bolt/value.rb +0 -35
- data/ffi/neo4j/driver/auth_tokens.rb +0 -18
- data/ffi/neo4j/driver/config.rb +0 -40
- data/ffi/neo4j/driver/graph_database.rb +0 -52
- data/ffi/neo4j/driver/internal/async/access_mode_connection.rb +0 -19
- data/ffi/neo4j/driver/internal/async/direct_connection.rb +0 -106
- data/ffi/neo4j/driver/internal/bolt_server_address.rb +0 -18
- data/ffi/neo4j/driver/internal/bookmarks_holder.rb +0 -30
- data/ffi/neo4j/driver/internal/direct_connection_provider.rb +0 -28
- data/ffi/neo4j/driver/internal/driver_factory.rb +0 -126
- data/ffi/neo4j/driver/internal/error_handling.rb +0 -112
- data/ffi/neo4j/driver/internal/explicit_transaction.rb +0 -146
- data/ffi/neo4j/driver/internal/handlers/pull_all_response_handler.rb +0 -104
- data/ffi/neo4j/driver/internal/handlers/response_handler.rb +0 -49
- data/ffi/neo4j/driver/internal/handlers/run_response_handler.rb +0 -32
- data/ffi/neo4j/driver/internal/handlers/session_pull_all_response_handler.rb +0 -32
- data/ffi/neo4j/driver/internal/handlers/transaction_pull_all_response_handler.rb +0 -23
- data/ffi/neo4j/driver/internal/internal_driver.rb +0 -45
- data/ffi/neo4j/driver/internal/internal_logger.rb +0 -32
- data/ffi/neo4j/driver/internal/internal_resolver.rb +0 -31
- data/ffi/neo4j/driver/internal/internal_statement_result.rb +0 -52
- data/ffi/neo4j/driver/internal/messaging/bolt_protocol.rb +0 -24
- data/ffi/neo4j/driver/internal/messaging/v1/bolt_protocol_v1.rb +0 -59
- data/ffi/neo4j/driver/internal/messaging/v2/bolt_protocol_v2.rb +0 -16
- data/ffi/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +0 -63
- data/ffi/neo4j/driver/internal/network_session.rb +0 -129
- data/ffi/neo4j/driver/internal/retry/exponential_backoff_retry_logic.rb +0 -80
- data/ffi/neo4j/driver/internal/session_factory_impl.rb +0 -28
- data/ffi/neo4j/driver/internal/summary/internal_result_summary.rb +0 -67
- data/ffi/neo4j/driver/internal/summary/internal_server_info.rb +0 -19
- data/ffi/neo4j/driver/internal/summary/internal_summary_counters.rb +0 -23
- data/ffi/neo4j/driver/internal/util/metadata_extractor.rb +0 -15
- data/ffi/neo4j/driver/internal/value/base_time_value.rb +0 -22
- data/ffi/neo4j/driver/internal/value/date_value.rb +0 -25
- data/ffi/neo4j/driver/internal/value/duration_value.rb +0 -27
- data/ffi/neo4j/driver/internal/value/local_date_time_value.rb +0 -24
- data/ffi/neo4j/driver/internal/value/local_time_value.rb +0 -19
- data/ffi/neo4j/driver/internal/value/node_value.rb +0 -18
- data/ffi/neo4j/driver/internal/value/offset_time_value.rb +0 -25
- data/ffi/neo4j/driver/internal/value/path_value.rb +0 -41
- data/ffi/neo4j/driver/internal/value/point2_d_value.rb +0 -24
- data/ffi/neo4j/driver/internal/value/point3_d_value.rb +0 -24
- data/ffi/neo4j/driver/internal/value/relationship_value.rb +0 -18
- data/ffi/neo4j/driver/internal/value/structure_value.rb +0 -42
- data/ffi/neo4j/driver/internal/value/time_with_zone_id_value.rb +0 -25
- data/ffi/neo4j/driver/internal/value/time_with_zone_offset_value.rb +0 -28
- data/ffi/neo4j/driver/internal/value/unbound_relationship_value.rb +0 -18
- data/ffi/neo4j/driver/internal/value/value_adapter.rb +0 -101
- data/ffi/neo4j/driver/net/server_address.rb +0 -13
- data/ffi/neo4j/driver/statement.rb +0 -15
- data/ffi/neo4j/driver/types/entity.rb +0 -21
- data/ffi/neo4j/driver/types/node.rb +0 -16
- data/ffi/neo4j/driver/types/path.rb +0 -35
- data/ffi/neo4j/driver/types/relationship.rb +0 -19
- data/ffi/neo4j/driver.rb +0 -61
- data/lib/neo4j/driver/internal/ruby_signature.rb +0 -18
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module Neo4j::Driver
|
|
2
|
+
module Internal
|
|
3
|
+
module Cluster
|
|
4
|
+
class RoutingProcedureClusterCompositionProvider
|
|
5
|
+
PROTOCOL_ERROR_MESSAGE = "Failed to parse '%s' result received from server due to "
|
|
6
|
+
|
|
7
|
+
def initialize(clock, routing_context)
|
|
8
|
+
@clock = clock
|
|
9
|
+
@single_database_routing_procedure_runner = SingleDatabaseRoutingProcedureRunner.new(routing_context)
|
|
10
|
+
@multi_database_routing_procedure_runner = MultiDatabasesRoutingProcedureRunner.new(routing_context)
|
|
11
|
+
@route_message_routing_procedure_runner = RouteMessageRoutingProcedureRunner.new(routing_context)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def get_cluster_composition(connection, database_name, bookmark, impersonated_user)
|
|
15
|
+
runner = if Messaging::Request::MultiDatabaseUtil.supports_route_message(connection)
|
|
16
|
+
@route_message_routing_procedure_runner
|
|
17
|
+
elsif Messaging::Request::MultiDatabaseUtil.supports_multi_database(connection)
|
|
18
|
+
@multi_database_routing_procedure_runner
|
|
19
|
+
else
|
|
20
|
+
@single_database_routing_procedure_runner
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
runner.run(connection, database_name, bookmark, impersonated_user).then_apply do
|
|
24
|
+
self::process_routing_response
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def process_routing_response(response)
|
|
29
|
+
if !response.success?
|
|
30
|
+
raise java.util.concurrent.CompletionException, "Failed to run '#{invoked_procedure_string(response)}' on server. Please make sure that there is a Neo4j server or cluster up running.", response.error
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
records = response.records
|
|
34
|
+
now = clock.millis
|
|
35
|
+
|
|
36
|
+
# the record size is wrong
|
|
37
|
+
if records.size != 1
|
|
38
|
+
raise Exceptions::ProtocolException, "#{PROTOCOL_ERROR_MESSAGE % invoked_procedure_string(response)} records received '#{records.size}' is too few or too many."
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# failed to parse the record
|
|
42
|
+
begin
|
|
43
|
+
cluster = ClusterComposition.parse( records[0], now)
|
|
44
|
+
rescue Exceptions::Value::ValueException => e
|
|
45
|
+
raise Exceptions::ProtocolException, "#{PROTOCOL_ERROR_MESSAGE % invoked_procedure_string(response)} unparsable record received. #{e}"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# the cluster result is not a legal reply
|
|
49
|
+
if !cluster.has_routers_and_readers?
|
|
50
|
+
raise Exceptions::ProtocolException, "#{PROTOCOL_ERROR_MESSAGE % invoked_procedure_string(response)} no router or reader found in response."
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# all good
|
|
54
|
+
cluster
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def invoked_procedure_string(response)
|
|
58
|
+
query = response.procedure
|
|
59
|
+
query.text + '' + query.parameters
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Neo4j::Driver
|
|
2
|
+
module Internal
|
|
3
|
+
module Cluster
|
|
4
|
+
class RoutingProcedureResponse
|
|
5
|
+
attr_reader :procedure, :records, :error
|
|
6
|
+
|
|
7
|
+
def initialize(procedure, records = nil, error = nil)
|
|
8
|
+
@procedure = procedure
|
|
9
|
+
@records = records
|
|
10
|
+
@error = error
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def success?
|
|
14
|
+
!records.nil?
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Neo4j::Driver
|
|
2
|
+
module Internal
|
|
3
|
+
module Cluster
|
|
4
|
+
class RoutingSettings
|
|
5
|
+
attr_reader :max_routing_failures, :retry_timeout_delay, :routing_context, :routing_table_purge_delay
|
|
6
|
+
|
|
7
|
+
def initialize(max_routing_failures, retry_timeout_delay, routing_table_purge_delay,
|
|
8
|
+
routing_context = RoutingContext::EMPTY)
|
|
9
|
+
@max_routing_failures = max_routing_failures
|
|
10
|
+
@retry_timeout_delay = retry_timeout_delay
|
|
11
|
+
@routing_context = routing_context
|
|
12
|
+
@routing_table_purge_delay = routing_table_purge_delay
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
STALE_ROUTING_TABLE_PURGE_DELAY = 30.seconds
|
|
16
|
+
DEFAULT = new(1, 5.seconds, STALE_ROUTING_TABLE_PURGE_DELAY)
|
|
17
|
+
|
|
18
|
+
def with_routing_context(new_routing_context)
|
|
19
|
+
self.class.new(@max_routing_failures, @retry_timeout_delay, @routing_table_purge_delay, new_routing_context)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
module Neo4j::Driver
|
|
2
|
+
module Internal
|
|
3
|
+
module Cluster
|
|
4
|
+
class RoutingTableHandlerImpl
|
|
5
|
+
attr_reader :routing_table
|
|
6
|
+
|
|
7
|
+
delegate :servers, to: :routing_table
|
|
8
|
+
|
|
9
|
+
def initialize(routing_table, rediscovery, connection_pool, routing_table_registry, logger, routing_table_purge_delay_ms)
|
|
10
|
+
@routing_table = routing_table
|
|
11
|
+
@database_name = routing_table.database
|
|
12
|
+
@rediscovery = rediscovery
|
|
13
|
+
@connection_pool = connection_pool
|
|
14
|
+
@routing_table_registry = routing_table_registry
|
|
15
|
+
@log = logger
|
|
16
|
+
@routing_table_purge_delay_ms = routing_table_purge_delay_ms
|
|
17
|
+
@resolved_initial_routers = []
|
|
18
|
+
@refresh_routing_table_future = nil
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def on_connection_failure(address)
|
|
22
|
+
# remove server from the routing table, to prevent concurrent threads from making connections to this address
|
|
23
|
+
routing_table.forget(address)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def on_write_failure(address)
|
|
27
|
+
routing_table.forget_writer(address)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def ensure_routing_table(context)
|
|
31
|
+
# refresh is already happening concurrently, just use it's result
|
|
32
|
+
return @refresh_routing_table_future unless @refresh_routing_table_future.nil?
|
|
33
|
+
|
|
34
|
+
if routing_table.stale_for?(context.mode)
|
|
35
|
+
# existing routing table is not fresh and should be updated
|
|
36
|
+
@log.debug( "Routing table for database '#{@database_name.description}' is stale. #{routing_table}")
|
|
37
|
+
|
|
38
|
+
result_future = java.util.concurrent.CompletableFuture.new
|
|
39
|
+
@refresh_routing_table_future = result_future
|
|
40
|
+
|
|
41
|
+
@rediscovery.lookup_cluster_composition(routing_table, @connection_pool, context.rediscovery_bookmark, nil).when_complete do |composition, completion_error|
|
|
42
|
+
error = Util::Futures.completion_exception_cause(completion_error)
|
|
43
|
+
|
|
44
|
+
if error.nil?
|
|
45
|
+
fresh_cluster_composition_fetched(composition)
|
|
46
|
+
else
|
|
47
|
+
cluster_composition_lookup_failed(error)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
result_future
|
|
52
|
+
else
|
|
53
|
+
# existing routing table is fresh, use it
|
|
54
|
+
java.util.concurrent.CompletableFuture.completed_future(routing_table)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def update_routing_table(composition_lookup_result)
|
|
59
|
+
if !@refresh_routing_table_future.nil?
|
|
60
|
+
# refresh is already happening concurrently, just use its result
|
|
61
|
+
@refresh_routing_table_future
|
|
62
|
+
else
|
|
63
|
+
if composition_lookup_result.get_cluster_composition.expiration_timestamp < routing_table.expiration_timestamp
|
|
64
|
+
return java.util.concurrent.CompletableFuture.completed_future(routing_table)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
result_future = java.util.concurrent.CompletableFuture.new
|
|
68
|
+
@refresh_routing_table_future = result_future
|
|
69
|
+
fresh_cluster_composition_fetched(composition_lookup_result)
|
|
70
|
+
result_future
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private def fresh_cluster_composition_fetched(composition_lookup_result)
|
|
75
|
+
begin
|
|
76
|
+
@log.debug("Fetched cluster composition for database '#{@database_name.description}'. #{composition_lookup_result.cluster_composition}")
|
|
77
|
+
routing_table.update(composition_lookup_result.cluster_composition)
|
|
78
|
+
@routing_table_registry.remove_aged
|
|
79
|
+
|
|
80
|
+
addresses_to_retain = []
|
|
81
|
+
@routing_table_registry.all_servers.stream.flat_map(BoltServerAddress::unicast_stream).for_each(addresses_to_retain::add)
|
|
82
|
+
|
|
83
|
+
composition_lookup_result.resolved_initial_routers.if_present do |addresses|
|
|
84
|
+
@resolved_initial_routers.clear
|
|
85
|
+
@resolved_initial_routers << addresses
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
addresses_to_retain << @resolved_initial_routers
|
|
89
|
+
@connection_pool.retain_all(addresses_to_retain)
|
|
90
|
+
|
|
91
|
+
@log.debug("Updated routing table for database '#{@database_name.description}'. #{routing_table}")
|
|
92
|
+
|
|
93
|
+
routing_table_future = @refresh_routing_table_future
|
|
94
|
+
@refresh_routing_table_future = nil
|
|
95
|
+
routing_table_future.complete( routing_table)
|
|
96
|
+
rescue StandardError => error
|
|
97
|
+
cluster_composition_lookup_failed(error)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
private def cluster_composition_lookup_failed(error)
|
|
102
|
+
@log.error("Failed to update routing table for database '#{database_name.description}'. Current routing table: #{routing_table}.", error)
|
|
103
|
+
@routing_table_registry.remove(database_name)
|
|
104
|
+
routing_table_future = @refresh_routing_table_future
|
|
105
|
+
@refresh_routing_table_future = nil
|
|
106
|
+
routing_table_future.complete_exceptionally(error)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# This method cannot be synchronized as it will be visited by all routing table handler's threads concurrently
|
|
110
|
+
def routing_table_aged?
|
|
111
|
+
@refresh_routing_table_future.nil? && routing_table.has_been_stale_for?(@routing_table_purge_delay_ms)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
module Neo4j::Driver
|
|
2
|
+
module Internal
|
|
3
|
+
module Cluster
|
|
4
|
+
class RoutingTableRegistryImpl
|
|
5
|
+
def initialize(connection_pool, rediscovery, clock, logger, routing_table_purge_delay_ms)
|
|
6
|
+
@factory = RoutingTableHandlerFactory.new(connection_pool, rediscovery, clock, logger, routing_table_purge_delay_ms)
|
|
7
|
+
@routing_table_handlers = {}
|
|
8
|
+
@principal_to_database_name_stage = {}
|
|
9
|
+
@clock = clock
|
|
10
|
+
@connection_pool = connection_pool
|
|
11
|
+
@rediscovery = rediscovery
|
|
12
|
+
@log = logger
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def ensure_routing_table(context)
|
|
16
|
+
ensure_database_name_is_completed(context).then_compose do |ctx_and_handler|
|
|
17
|
+
completed_context = ctx_and_handler.context
|
|
18
|
+
handler = ctx_and_handler.handler.nil? ? get_or_create(Util::Futures.join_now_or_else_throw(completed_context.database_name_future, Async::ConnectionContext::PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER)) : ctx_and_handler.handler
|
|
19
|
+
handler.ensure_routing_table(completed_context).then_apply(-> (_ignored) { handler })
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private def ensure_database_name_is_completed(context)
|
|
24
|
+
context_database_name_future = context.database_name_future
|
|
25
|
+
|
|
26
|
+
if context_database_name_future.done?
|
|
27
|
+
context_and_handler_stage = java.util.concurrent.CompletableFuture.completed_future(ConnectionContextAndHandler.new(context, nil))
|
|
28
|
+
else
|
|
29
|
+
impersonated_user = context.impersonated_user
|
|
30
|
+
principal = Principal.new(impersonated_user)
|
|
31
|
+
database_name_stage = @principal_to_database_name_stage[principal]
|
|
32
|
+
handler_ref = java.util.concurrent.atomic.AtomicReference.new
|
|
33
|
+
|
|
34
|
+
if database_name_stage.nil?
|
|
35
|
+
database_name_future = java.util.concurrent.CompletableFuture.new
|
|
36
|
+
@principal_to_database_name_stage[principal] = database_name_future
|
|
37
|
+
database_name_stage = database_name_future
|
|
38
|
+
|
|
39
|
+
routing_table = ClusterRoutingTable.new(DatabaseNameUtil::DEFAULT_DATABASE, @clock)
|
|
40
|
+
|
|
41
|
+
@rediscovery.lookup_cluster_composition(routing_table, @connection_pool, context.rediscovery_bookmark, impersonated_user).then_compose do |composition_lookup_result|
|
|
42
|
+
database_name = DatabaseNameUtil.database(composition_lookup_result.cluster_composition.database_name)
|
|
43
|
+
handler = get_or_create(database_name)
|
|
44
|
+
handler_ref.set(handler)
|
|
45
|
+
handler.update_routing_table(composition_lookup_result).then_apply(-> (_ignored) { database_name })
|
|
46
|
+
end.when_complete do |database_name, _throwable|
|
|
47
|
+
@principal_to_database_name_stage.delete(principal)
|
|
48
|
+
end.when_complete do |database_name, throwable|
|
|
49
|
+
if throwable.nil?
|
|
50
|
+
database_name_future.complete(database_name)
|
|
51
|
+
else
|
|
52
|
+
database_name_future.complete_exceptionally(throwable)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
context_and_handler_stage =
|
|
58
|
+
database_name_stage.then_apply do |database_name|
|
|
59
|
+
context_database_name_future.complete(database_name)
|
|
60
|
+
ConnectionContextAndHandler.new(context, handler_ref)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context_and_handler_stage
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def all_servers
|
|
68
|
+
# obviously we just had a snapshot of all servers in all routing tables
|
|
69
|
+
# after we read it, the set could already be changed.
|
|
70
|
+
servers = []
|
|
71
|
+
|
|
72
|
+
@routing_table_handlers.values.each do |table_handler|
|
|
73
|
+
servers << table_handler.servers
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
servers
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def remove(database_name)
|
|
80
|
+
@routing_table_handlers.delete(database_name)
|
|
81
|
+
@log.debug("Routing table handler for database '#{database_name.description}' is removed.")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def remove_aged
|
|
85
|
+
@routing_table_handlers.each do |database_name, handler|
|
|
86
|
+
if handler.routing_table_aged?
|
|
87
|
+
@log.info("Routing table handler for database '#{database_name.description}' is removed because it has not been used for a long time. Routing table: #{handler.routing_table}")
|
|
88
|
+
@routing_table_handlers.delete(database_name)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def get_routing_table_handler(database_name)
|
|
94
|
+
java.util.Optional.of_nullable(@routing_table_handlers[database_name])
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def contains(database_name)
|
|
98
|
+
@routing_table_handlers.keys.include?(database_name)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def get_or_create(database_name)
|
|
102
|
+
@routing_table_handlers.compute_if_absent(database_name) do |name|
|
|
103
|
+
handler = @factory.new_instance(name, self)
|
|
104
|
+
@log.debug("Routing table handler for database '#{database_name.description}' is added.")
|
|
105
|
+
handler
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
private
|
|
110
|
+
|
|
111
|
+
class RoutingTableHandlerFactory
|
|
112
|
+
def initialize(connection_pool, rediscovery, clock, logger, routing_table_purge_delay_ms)
|
|
113
|
+
@connection_pool = connection_pool
|
|
114
|
+
@rediscovery = rediscovery
|
|
115
|
+
@clock = clock
|
|
116
|
+
@logger = logger
|
|
117
|
+
@routing_table_purge_delay_ms = routing_table_purge_delay_ms
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def new_instance(database_name, all_tables)
|
|
121
|
+
routing_table = ClusterRoutingTable.new(database_name, @clock)
|
|
122
|
+
RoutingTableHandlerImpl.new(routing_table, @rediscovery, @connection_pool, all_tables, @logger, @routing_table_purge_delay_ms)
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
class Principal < Struct.new(:id)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
class ConnectionContextAndHandler
|
|
130
|
+
attr_reader :context, :handler
|
|
131
|
+
|
|
132
|
+
def initialize(context, handler)
|
|
133
|
+
@context = context
|
|
134
|
+
@handler = handler
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module Neo4j::Driver
|
|
2
|
+
module Internal
|
|
3
|
+
module Cluster
|
|
4
|
+
|
|
5
|
+
# This implementation of the {@link RoutingProcedureRunner} works with single database versions of Neo4j calling
|
|
6
|
+
# the procedure `dbms.cluster.routing.getRoutingTable`
|
|
7
|
+
class SingleDatabaseRoutingProcedureRunner
|
|
8
|
+
ROUTING_CONTEXT = 'context'
|
|
9
|
+
GET_ROUTING_TABLE = "CALL dbms.cluster.routing.getRoutingTable($#{ROUTING_CONTEXT})"
|
|
10
|
+
|
|
11
|
+
def initialize(context)
|
|
12
|
+
@context = context
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def run(connection, database_name, bookmark, impersonated_user)
|
|
16
|
+
delegate = connection(connection)
|
|
17
|
+
procedure = procedure_query(connection.server_version, database_name)
|
|
18
|
+
bookmark_holder = bookmark_holder(bookmark)
|
|
19
|
+
run_procedure(delegate, procedure, bookmark_holder).then_compose do |records|
|
|
20
|
+
release_connection(delegate, records).handle do |records, error|
|
|
21
|
+
process_procedure_response(procedure, records, error)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def connection(connection)
|
|
29
|
+
Async::Connection::DirectConnection.new(connection, default_database, AccessMode::WRITE, nil)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def procedure_query(server_version, database_name)
|
|
33
|
+
if database_name.database_name.present?
|
|
34
|
+
raise Exceptions::FatalDiscoveryException, "Refreshing routing table for multi-databases is not supported in server version lower than 4.0. Current server version: #{server_version}. Database name: '#{database_name.description}'"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
Query.new(GET_ROUTING_TABLE, Values.parameters(ROUTING_CONTEXT, @context.to_map))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def bookmark_holder(_ignored)
|
|
41
|
+
BookmarkHolder::NO_OP
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def run_procedure(connection, procedure, bookmark_holder)
|
|
45
|
+
connection.protocol
|
|
46
|
+
.run_in_auto_commit_transaction(connection, procedure, bookmark_holder, TransactionConfig.empty,
|
|
47
|
+
Handlers::Pulln::FetchSizeUtil::UNLIMITED_FETCH_SIZE)
|
|
48
|
+
.async_result.then_compose(Async::ResultCursor::list_async)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def release_connection(connection, records)
|
|
52
|
+
# It is not strictly required to release connection after routing procedure invocation because it'll
|
|
53
|
+
# be released by the PULL_ALL response handler after result is fully fetched. Such release will happen
|
|
54
|
+
# in background. However, releasing it early as part of whole chain makes it easier to reason about
|
|
55
|
+
# rediscovery in stub server tests. Some of them assume connections to instances not present in new
|
|
56
|
+
# routing table will be closed immediately.
|
|
57
|
+
connection.release.then_apply(->(_ignore) { records } )
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def process_procedure_response(procedure, records, error)
|
|
61
|
+
cause = Util::Futures.completion_exception_cause(error)
|
|
62
|
+
|
|
63
|
+
return RoutingProcedureResponse.new(procedure, records) if cause.nil?
|
|
64
|
+
|
|
65
|
+
handle_error(procedure, cause)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def handle_error(procedure, error)
|
|
69
|
+
return RoutingProcedureResponse.new(procedure, records) if error.is_a? Exceptions::ClientException
|
|
70
|
+
|
|
71
|
+
raise java.util.concurrent.CompletionException, error
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Neo4j::Driver
|
|
2
|
+
module Internal
|
|
3
|
+
|
|
4
|
+
# The connection settings are used whenever a new connection is
|
|
5
|
+
# established to a server, specifically as part of the INIT request.
|
|
6
|
+
class ConnectionSettings
|
|
7
|
+
attr_reader :auth_token, :user_agent, :connect_timeout_millis
|
|
8
|
+
|
|
9
|
+
def initialize(auth_token, user_agent, connect_timeout_millis)
|
|
10
|
+
@auth_token = auth_token
|
|
11
|
+
@user_agent = user_agent
|
|
12
|
+
@connect_timeout_millis = connect_timeout_millis
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module Neo4j::Driver
|
|
2
|
+
module Internal
|
|
3
|
+
module Cursor
|
|
4
|
+
class AsyncResultCursorImpl
|
|
5
|
+
delegate :consume_async, :next_async, :peek_async, to: :@pull_all_handler
|
|
6
|
+
|
|
7
|
+
def initialize(run_handler, pull_all_handler)
|
|
8
|
+
@run_handler = run_handler
|
|
9
|
+
@pull_all_handler = pull_all_handler
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def keys
|
|
13
|
+
@run_handler.query_keys
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def single_async
|
|
17
|
+
first_record = next_async
|
|
18
|
+
unless first_record
|
|
19
|
+
raise Exceptions::NoSuchRecordException, 'Cannot retrieve a single record, because this result is empty.'
|
|
20
|
+
end
|
|
21
|
+
if next_async
|
|
22
|
+
raise Exceptions::NoSuchRecordException,
|
|
23
|
+
'Expected a result with a single record, but this result contains at least one more. Ensure your query returns only one record.'
|
|
24
|
+
end
|
|
25
|
+
first_record
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def each_async(&action)
|
|
29
|
+
internal_for_each_async(result_future, &action)
|
|
30
|
+
consume_async
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def to_async(&map_function)
|
|
34
|
+
@pull_all_handler.list_async(&block_given? ? map_function : :itself)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def discard_all_failure_async
|
|
38
|
+
# runError has priority over other errors and is expected to have been reported to user by now
|
|
39
|
+
consume_async #.chain { |_fulfilled, _summary, error| @run_error ? nil : error }
|
|
40
|
+
nil
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def pull_all_failure_async
|
|
44
|
+
# runError has priority over other errors and is expected to have been reported to user by now
|
|
45
|
+
@pull_all_handler.pull_all_failure_async.then { |error| @run_error ? nil : error }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private def internal_for_each_async(result_future, &action)
|
|
49
|
+
record_future = next_async
|
|
50
|
+
|
|
51
|
+
# use async completion listener because of recursion, otherwise it is possible for
|
|
52
|
+
# the caller thread to get StackOverflowError when result is large and buffered
|
|
53
|
+
record_future.on_complete do |_fulfilled, record, error|
|
|
54
|
+
if error
|
|
55
|
+
result_future.reject(error)
|
|
56
|
+
elsif record
|
|
57
|
+
begin
|
|
58
|
+
yield record
|
|
59
|
+
rescue => action_error
|
|
60
|
+
result_future.reject(action_error)
|
|
61
|
+
return
|
|
62
|
+
end
|
|
63
|
+
internal_for_each_async(result_future, &action)
|
|
64
|
+
else
|
|
65
|
+
result_future.fulfill(nil)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def map_successful_run_completion_async
|
|
71
|
+
@run_error || self
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Neo4j::Driver
|
|
2
|
+
module Internal
|
|
3
|
+
module Cursor
|
|
4
|
+
# Used by Bolt V1, V2, V3
|
|
5
|
+
class AsyncResultCursorOnlyFactory
|
|
6
|
+
def initialize(connection, run_message, run_handler, run_future, pull_handler)
|
|
7
|
+
@connection = Internal::Validator.require_non_nil!(connection)
|
|
8
|
+
@run_message = Internal::Validator.require_non_nil!(run_message)
|
|
9
|
+
@run_handler = Internal::Validator.require_non_nil!(run_handler)
|
|
10
|
+
@run_future = Internal::Validator.require_non_nil!(run_future)
|
|
11
|
+
|
|
12
|
+
@pull_all_handler = Internal::Validator.require_non_nil!(pull_handler)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def async_result
|
|
16
|
+
# only write and flush messages when async result is wanted.
|
|
17
|
+
@connection.write(@run_message, @run_handler) # queues the run message, will be flushed with pull message together
|
|
18
|
+
@pull_all_handler.pre_populate_records
|
|
19
|
+
|
|
20
|
+
@run_future.handle { |_ignored, error| DisposableAsyncResultCursor.new(AsyncResultCursorImpl.new(error, @run_handler, @pull_all_handler)) }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def rx_result
|
|
24
|
+
Util::Futures.failed_future(Exceptions::ClientException.new('Driver is connected to the database that does not support driver reactive API. In order to use the driver reactive API, please upgrade to neo4j 4.0.0 or later.'))
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module Neo4j::Driver
|
|
2
|
+
module Internal
|
|
3
|
+
module Cursor
|
|
4
|
+
class DisposableAsyncResultCursor
|
|
5
|
+
delegate :keys, :pull_all_failure_async, to: :@delegate
|
|
6
|
+
|
|
7
|
+
def initialize(delegate)
|
|
8
|
+
@delegate = delegate
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def consume_async
|
|
12
|
+
@disposed = true
|
|
13
|
+
@delegate.consume_async
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def next_async
|
|
17
|
+
assert_not_disposed.then_compose(-> (_ignored) { @delegate.next_async })
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def peek_async
|
|
21
|
+
assert_not_disposed.then_compose(-> (_ignored) { @delegate.peek_async })
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def single_async
|
|
25
|
+
assert_not_disposed.then_compose(-> (_ignored) { @delegate.single_async })
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def for_each_async(action)
|
|
29
|
+
assert_not_disposed.then_compose(-> (_ignored) { @delegate.for_each_async(action) })
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def list_async(map_function = nil)
|
|
33
|
+
return assert_not_disposed.then_compose(-> (_ignored) { @delegate.list_async(map_function) }) if map_function.present?
|
|
34
|
+
|
|
35
|
+
assert_not_disposed.then_compose(-> (_ignored) { @delegate.list_async })
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def discard_all_failure_async
|
|
39
|
+
@disposed = true
|
|
40
|
+
@delegate.discard_all_failure_async
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private def assert_not_disposed
|
|
44
|
+
return Util::Futures.failed_future(new_result_consumed_error) if @disposed
|
|
45
|
+
|
|
46
|
+
Util::Futures.completed_with_null
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def disposed?
|
|
50
|
+
@disposed
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def map_successful_run_completion_async
|
|
54
|
+
@delegate.map_successful_run_completion_async
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Neo4j::Driver
|
|
2
|
+
module Internal
|
|
3
|
+
module Cursor
|
|
4
|
+
# Bolt V4
|
|
5
|
+
class ResultCursorFactoryImpl
|
|
6
|
+
def initialize(connection, run_message, run_handler, pull_handler, pull_all_handler)
|
|
7
|
+
@connection = Internal::Validator.require_non_nil!(connection)
|
|
8
|
+
@run_message = Internal::Validator.require_non_nil!(run_message)
|
|
9
|
+
@run_handler = Internal::Validator.require_non_nil!(run_handler)
|
|
10
|
+
@pull_handler = Internal::Validator.require_non_nil!(pull_handler)
|
|
11
|
+
@pull_all_handler = Internal::Validator.require_non_nil!(pull_all_handler)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def async_result
|
|
15
|
+
# only write and flush messages when async result is wanted.
|
|
16
|
+
@connection.write(@run_message, @run_handler) # queues the run message, will be flushed with pull message together
|
|
17
|
+
@pull_all_handler.pre_populate_records
|
|
18
|
+
|
|
19
|
+
DisposableAsyncResultCursor.new(AsyncResultCursorImpl.new(@run_handler, @pull_all_handler))
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def rx_result
|
|
23
|
+
@connection.write_and_flush(@run_message, @run_handler)
|
|
24
|
+
@run_future.handle { |_ignored, error| RxResultCursorImpl.new(error, @run_handler, @pull_handler) }
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|