neo4j-ruby-driver 1.7.5 → 4.4.0.alpha.2
Sign up to get free protection for your applications and to get access to all the features.
- 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,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
class AuthTokens
|
6
|
+
class << self
|
7
|
+
def basic(username, password, realm = nil)
|
8
|
+
Internal::Validator.require_non_nil_credentials!(username, password)
|
9
|
+
Internal::Security::InternalAuthToken[
|
10
|
+
{ scheme: 'basic', principal: username, credentials: password, realm: realm }.compact]
|
11
|
+
end
|
12
|
+
|
13
|
+
def bearer(token)
|
14
|
+
Internal::Validator.require_non_nil!(token, "Token")
|
15
|
+
Internal::Security::InternalAuthToken[scheme: 'bearer', credentials: token]
|
16
|
+
end
|
17
|
+
|
18
|
+
def kerberos(base64_encoded_ticket)
|
19
|
+
Internal::Validator.require_non_nil!(base64_encoded_ticket, "Ticket")
|
20
|
+
Internal::Security::InternalAuthToken[scheme: 'bearer', credentials: base64_encoded_ticket]
|
21
|
+
end
|
22
|
+
|
23
|
+
def custom(principal, credentials, realm, scheme, **parameters)
|
24
|
+
Internal::Security::InternalAuthToken[{ scheme: scheme, principal: principal, credentials: credentials,
|
25
|
+
realm: realm, parameters: parameters.presence || nil }.compact]
|
26
|
+
end
|
27
|
+
|
28
|
+
def none
|
29
|
+
Internal::Security::InternalAuthToken[scheme: 'none']
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Neo4j
|
2
|
+
module Driver
|
3
|
+
# Causal chaining is carried out by passing bookmarks between transactions.
|
4
|
+
|
5
|
+
# When starting a session with initial bookmarks, the first transaction will be ensured to run at least after
|
6
|
+
# the database is as up-to-date as the latest transaction referenced by the supplied bookmarks.
|
7
|
+
|
8
|
+
# Within a session, bookmark propagation is carried out automatically.
|
9
|
+
# Thus all transactions in a session (both managed and unmanaged) are guaranteed to be carried out one after another.
|
10
|
+
|
11
|
+
# To opt out of this mechanism for unrelated units of work, applications can use multiple sessions.
|
12
|
+
module Bookmark
|
13
|
+
# Reconstruct bookmark from \bookmarks string values.
|
14
|
+
# @param values values obtained from a previous bookmark.
|
15
|
+
# @return A bookmark.
|
16
|
+
def self.from(*values)
|
17
|
+
Internal::InternalBookmark.parse(*values)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j
|
4
|
+
module Driver
|
5
|
+
class Config < Hash
|
6
|
+
class TrustStrategy
|
7
|
+
TRUST_ALL_CERTIFICATES = :trust_all_certificates
|
8
|
+
TRUST_CUSTOM_CA_SIGNED_CERTIFICATES = :trust_custom_certificates
|
9
|
+
TRUST_SYSTEM_CA_SIGNED_CERTIFICATES = :trust_system_certificates
|
10
|
+
|
11
|
+
attr_reader :strategy, :cert_files, :revocation_strategy
|
12
|
+
|
13
|
+
#
|
14
|
+
# {
|
15
|
+
# trust_strategy: {
|
16
|
+
# strategy: :trust_custom_certificates,
|
17
|
+
# cert_files: ['some_path', 'another_path'],
|
18
|
+
# revocation_strategy: :no_checks, # or :verify_if_present, :strict
|
19
|
+
# hostname_verification: true
|
20
|
+
# },
|
21
|
+
# encryption: true
|
22
|
+
# }
|
23
|
+
def initialize(**config)
|
24
|
+
@strategy = config[:strategy]
|
25
|
+
@cert_files = config[:cert_files]
|
26
|
+
@revocation_strategy = config[:revocation_strategy] || Neo4j::Driver::Internal::RevocationStrategy::NO_CHECKS
|
27
|
+
@hostname_verification_enabled = config[:hostname_verification] || false
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.trust_all_certificates
|
31
|
+
new(trust_strategy: TRUST_ALL_CERTIFICATES)
|
32
|
+
end
|
33
|
+
|
34
|
+
def hostname_verification_enabled?
|
35
|
+
@hostname_verification_enabled
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Console.logger = ::Logger.new(STDOUT, level: :debug)
|
40
|
+
DEFAULTS = {
|
41
|
+
logger: ::Logger.new(nil),
|
42
|
+
# logger: ::Logger.new(STDOUT, level: :debug),
|
43
|
+
# logger: Console.logger,
|
44
|
+
leaked_sessions_logging: false,
|
45
|
+
max_connection_pool_size: Internal::Async::Pool::PoolSettings::DEFAULT_MAX_CONNECTION_POOL_SIZE,
|
46
|
+
idle_time_before_connection_test: Internal::Async::Pool::PoolSettings::DEFAULT_IDLE_TIME_BEFORE_CONNECTION_TEST,
|
47
|
+
max_connection_lifetime: Internal::Async::Pool::PoolSettings::DEFAULT_MAX_CONNECTION_LIFETIME,
|
48
|
+
connection_acquisition_timeout: Internal::Async::Pool::PoolSettings::DEFAULT_CONNECTION_ACQUISITION_TIMEOUT,
|
49
|
+
routing_failure_limit: Internal::Cluster::RoutingSettings::DEFAULT.max_routing_failures,
|
50
|
+
routing_retry_delay: Internal::Cluster::RoutingSettings::DEFAULT.retry_timeout_delay,
|
51
|
+
routing_table_purge_delay: Internal::Cluster::RoutingSettings::DEFAULT.routing_table_purge_delay,
|
52
|
+
user_agent: "neo4j-ruby/#{Neo4j::Driver::VERSION}",
|
53
|
+
connection_timeout: 30.seconds,
|
54
|
+
driver_metrics: false,
|
55
|
+
fetch_size: Internal::Handlers::Pulln::FetchSizeUtil::DEFAULT_FETCH_SIZE,
|
56
|
+
event_loop_threads: 0,
|
57
|
+
|
58
|
+
# TODO: Still to cleanup
|
59
|
+
encryption: false, # :set_transport
|
60
|
+
keep_alive: true, # BoltSocketOptions_set_keep_alive
|
61
|
+
# connection_liveness_check_timeout: -1, # Not configured
|
62
|
+
max_transaction_retry_time: Internal::Retry::ExponentialBackoffRetryLogic::DEFAULT_MAX_RETRY_TIME,
|
63
|
+
metrics_enabled: false,
|
64
|
+
# resolver: nil # :set_address_resolver
|
65
|
+
trust_strategy: TrustStrategy.trust_all_certificates,
|
66
|
+
}.freeze
|
67
|
+
|
68
|
+
def initialize(**config)
|
69
|
+
merge!(DEFAULTS).merge!(config.compact)
|
70
|
+
init_security_and_trust_config(config)
|
71
|
+
end
|
72
|
+
|
73
|
+
def routing_settings
|
74
|
+
Internal::Cluster::RoutingSettings.new(
|
75
|
+
*values_at(:routing_failure_limit, :routing_retry_delay, :routing_table_purge_delay))
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def init_security_and_trust_config(config)
|
81
|
+
trust_strategy = config.key?(:trust_strategy) ? TrustStrategy.new(**config) : DEFAULTS[:trust_strategy]
|
82
|
+
encryption = config.key?(:encryption) ? config[:encryption] : DEFAULTS[:encryption]
|
83
|
+
customized = %i[encryption trust_strategy].any?(&config.method(:key?))
|
84
|
+
merge!(
|
85
|
+
security_settings: Neo4j::Driver::Internal::SecuritySetting.new(encryption, trust_strategy, customized),
|
86
|
+
trust_strategy: trust_strategy
|
87
|
+
)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Neo4j::Driver
|
4
|
+
class GraphDatabase
|
5
|
+
class << self
|
6
|
+
extend AutoClosable
|
7
|
+
extend Synchronizable
|
8
|
+
auto_closable :driver, :routing_driver
|
9
|
+
sync :driver
|
10
|
+
|
11
|
+
GOGOBOLT = ["6060B017"].pack('H*')
|
12
|
+
|
13
|
+
def handshake_concurrent(*versions)
|
14
|
+
remote_port = 7687
|
15
|
+
remote_addr = 'localhost'
|
16
|
+
selector = NIO::Selector.new
|
17
|
+
socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
|
18
|
+
begin
|
19
|
+
socket.connect_nonblock Socket.sockaddr_in(remote_port, remote_addr)
|
20
|
+
rescue Errno::EINPROGRESS
|
21
|
+
# Ruby's a-tryin' to connect us, we swear!
|
22
|
+
selector.register(socket, :w)
|
23
|
+
end
|
24
|
+
selector.select do |monitor|
|
25
|
+
case monitor.io
|
26
|
+
when Socket
|
27
|
+
if monitor.writable?
|
28
|
+
begin
|
29
|
+
socket.connect_nonblock Socket.sockaddr_in(remote_port, remote_addr)
|
30
|
+
rescue Errno::EISCONN
|
31
|
+
# SUCCESS! Since Ruby is crazy we discover we're successful via an exception
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
socket.write_nonblock(GOGOBOLT)
|
37
|
+
socket.write_nonblock(bolt_versions(*versions))
|
38
|
+
|
39
|
+
@data = nil
|
40
|
+
begin
|
41
|
+
@data = socket.read_nonblock(16384)
|
42
|
+
rescue IO::WaitReadable
|
43
|
+
monitor = selector.register(socket, :r)
|
44
|
+
monitor.value = proc do
|
45
|
+
@data = socket.read_nonblock(16384)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
Concurrent::Promises.future do
|
49
|
+
selector.select do |monitor|
|
50
|
+
monitor.value.call
|
51
|
+
end
|
52
|
+
ruby_version(@data)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
class Connection < Async::Pool::Resource
|
57
|
+
attr :version, true
|
58
|
+
attr :io
|
59
|
+
|
60
|
+
def initialize
|
61
|
+
super
|
62
|
+
@io = Async::IO::Endpoint.tcp('localhost', 7687).connect
|
63
|
+
end
|
64
|
+
|
65
|
+
def close
|
66
|
+
super
|
67
|
+
@io.close
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def driver(uri, auth_token = nil, **config)
|
72
|
+
internal_driver(uri, auth_token, config, Internal::DriverFactory.new)
|
73
|
+
end
|
74
|
+
|
75
|
+
def internal_driver(uri, auth_token, config, factory)
|
76
|
+
uri = URI(uri)
|
77
|
+
config = Config.new(**config)
|
78
|
+
|
79
|
+
factory.new_instance(
|
80
|
+
uri,
|
81
|
+
auth_token || AuthTokens.none,
|
82
|
+
config.routing_settings,
|
83
|
+
config[:max_transaction_retry_time],
|
84
|
+
config,
|
85
|
+
config[:security_settings].create_security_plan(uri.scheme)
|
86
|
+
)
|
87
|
+
end
|
88
|
+
|
89
|
+
def routing_driver(routing_uris, auth_toke, **config)
|
90
|
+
assert_routing_uris(routing_uris)
|
91
|
+
log = Config.new(**config)[:logger]
|
92
|
+
|
93
|
+
routing_uris.each do |uri|
|
94
|
+
driver = driver(uri, auth_toke, **config)
|
95
|
+
begin
|
96
|
+
return driver.tap(&:verify_connectivity)
|
97
|
+
rescue Exceptions::ServiceUnavailableException => e
|
98
|
+
log.warn { "Unable to create routing driver for URI: #{uri}\n#{e}" }
|
99
|
+
close_driver(driver, uri, log)
|
100
|
+
rescue Exception => e
|
101
|
+
close_driver(driver, uri, log)
|
102
|
+
raise e
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
raise Exceptions::ServiceUnavailableException, 'Failed to discover an available server'
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
def bolt_version(version)
|
112
|
+
pad(version.split(/[.\-]/).map(&:to_i), 4).reverse
|
113
|
+
end
|
114
|
+
|
115
|
+
def ruby_version(bolt_version)
|
116
|
+
bolt_version.unpack('C*').reverse.map(&:to_s).join('.')
|
117
|
+
end
|
118
|
+
|
119
|
+
def bolt_versions(*versions)
|
120
|
+
pad(versions[0..3].map(&method(:bolt_version)).flatten, 16).pack('C*')
|
121
|
+
end
|
122
|
+
|
123
|
+
def pad(arr, n)
|
124
|
+
arr + [0] * [0, n - arr.size].max
|
125
|
+
end
|
126
|
+
|
127
|
+
def close_driver(driver, uri, log)
|
128
|
+
driver.close
|
129
|
+
rescue StandardError => close_error
|
130
|
+
log.warn { "Unable to close driver towards URI: #{uri}\n#{close_error}" }
|
131
|
+
end
|
132
|
+
|
133
|
+
def assert_routing_uris(uris)
|
134
|
+
uris.find { |uri| URI(uri).scheme != Neo4j::Driver::Internal::Scheme::NEO4J_URI_SCHEME }&.tap do |uri|
|
135
|
+
raise ArgumentError, "Illegal URI scheme, expected '#{Internal::Scheme::NEO4J_URI_SCHEME}' in '#{uri}'"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Neo4j::Driver
|
2
|
+
module Internal
|
3
|
+
module Async
|
4
|
+
module Connection
|
5
|
+
class BoltProtocolUtil
|
6
|
+
BOLT_MAGIC_PREAMBLE = 0x6060B017
|
7
|
+
NO_PROTOCOL_VERSION = Messaging::BoltProtocolVersion.new(0, 0)
|
8
|
+
CHUNK_HEADER_SIZE_BYTES = 2
|
9
|
+
DEFAULT_MAX_OUTBOUND_CHUNK_SIZE_BYTES = 2 ** 15 - 1
|
10
|
+
HANDSHAKE = [
|
11
|
+
BOLT_MAGIC_PREAMBLE,
|
12
|
+
Messaging::V44::BoltProtocolV44::VERSION.to_int_range(Messaging::V42::BoltProtocolV42::VERSION),
|
13
|
+
Messaging::V41::BoltProtocolV41::VERSION.to_int,
|
14
|
+
Messaging::V4::BoltProtocolV4::VERSION.to_int,
|
15
|
+
Messaging::V3::BoltProtocolV3::VERSION.to_int]
|
16
|
+
HANDSHAKE_BUF = HANDSHAKE.pack('N*').freeze
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def handshake_buf
|
20
|
+
HANDSHAKE_BUF
|
21
|
+
end
|
22
|
+
|
23
|
+
def handshake_string
|
24
|
+
HANDSHAKE_STRING
|
25
|
+
end
|
26
|
+
|
27
|
+
def write_message_boundary(buf)
|
28
|
+
buf.write_short(0)
|
29
|
+
end
|
30
|
+
|
31
|
+
def write_empty_chunk_header(buf)
|
32
|
+
buf.write_short(0)
|
33
|
+
end
|
34
|
+
|
35
|
+
def write_chunk_header(buf, chunk_start_index, header_value)
|
36
|
+
buf.set_short(chunk_start_index, header_value)
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def create_handshake_string
|
42
|
+
"[0x#{HANDSHAKE.first.to_s(16)}, %s, %s, %s, %s]" % HANDSHAKE[1, 4]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
HANDSHAKE_STRING = create_handshake_string
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Neo4j::Driver
|
2
|
+
module Internal
|
3
|
+
module Async
|
4
|
+
module Connection
|
5
|
+
class BootstrapFactory
|
6
|
+
class << self
|
7
|
+
def new_bootstrap(thread_count: nil,
|
8
|
+
event_loop_group: EventLoopGroupFactory.new_event_loop_group(thread_count))
|
9
|
+
# Ione::Io::IoReactor.new
|
10
|
+
# Io::Bootstrap.new.tap do |bootstrap|
|
11
|
+
# bootstrap.group = event_loop_group
|
12
|
+
# bootstrap.channel(EventLoopGroupFactory.channel_class)
|
13
|
+
# bootstrap.option(org.neo4j.driver.internal.shaded.io.netty.channel.ChannelOption::SO_KEEPALIVE, true)
|
14
|
+
# bootstrap.option(org.neo4j.driver.internal.shaded.io.netty.channel.ChannelOption::SO_REUSEADDR, true)
|
15
|
+
# end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Neo4j::Driver
|
2
|
+
module Internal
|
3
|
+
module Async
|
4
|
+
module Connection
|
5
|
+
class ChannelAttributes < Hash
|
6
|
+
# CONNECTION_ID = org.neo4j.driver.internal.shaded.io.netty.util.AttributeKey.new_instance('connectionId')
|
7
|
+
# POOL_ID = org.neo4j.driver.internal.shaded.io.netty.util.AttributeKey.new_instance('poolId')
|
8
|
+
# PROTOCOL_VERSION = org.neo4j.driver.internal.shaded.io.netty.util.AttributeKey.new_instance('protocolVersion')
|
9
|
+
# SERVER_AGENT = org.neo4j.driver.internal.shaded.io.netty.util.AttributeKey.new_instance('serverAgent')
|
10
|
+
# ADDRESS = org.neo4j.driver.internal.shaded.io.netty.util.AttributeKey.new_instance('serverAddress')
|
11
|
+
# SERVER_VERSION = org.neo4j.driver.internal.shaded.io.netty.util.AttributeKey.new_instance('serverVersion')
|
12
|
+
# CREATION_TIMESTAMP = org.neo4j.driver.internal.shaded.io.netty.util.AttributeKey.new_instance('creationTimestamp')
|
13
|
+
# LAST_USED_TIMESTAMP = org.neo4j.driver.internal.shaded.io.netty.util.AttributeKey.new_instance('lastUsedTimestamp')
|
14
|
+
# MESSAGE_DISPATCHER = org.neo4j.driver.internal.shaded.io.netty.util.AttributeKey.new_instance('messageDispatcher')
|
15
|
+
# TERMINATION_REASON = org.neo4j.driver.internal.shaded.io.netty.util.AttributeKey.new_instance('terminationReason')
|
16
|
+
# AUTHORIZATION_STATE_LISTENER = org.neo4j.driver.internal.shaded.io.netty.util.AttributeKey.new_instance('authorizationStateListener')
|
17
|
+
# CONNECTION_READ_TIMEOUT = org.neo4j.driver.internal.shaded.io.netty.util.AttributeKey.new_instance('connectionReadTimeout')
|
18
|
+
|
19
|
+
UPDATABLE_KEYS = %i[last_used_timestamp authorization_state_listener]
|
20
|
+
|
21
|
+
def []=(key, value)
|
22
|
+
if !UPDATABLE_KEYS.include?(key) && key?(key)
|
23
|
+
raise Neo4j::Driver::Exceptions::IllegalStateException, "Unable to set #{key} because it is already set to #{self[key]}"
|
24
|
+
end
|
25
|
+
super
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Neo4j::Driver
|
2
|
+
module Internal
|
3
|
+
module Async
|
4
|
+
module Connection
|
5
|
+
class ChannelConnectedListener < Struct.new(:address, :pipeline_builder, :handshake_completed_promise, :logger)
|
6
|
+
# include org.neo4j.driver.internal.shaded.io.netty.channel.ChannelFutureListener
|
7
|
+
def operationComplete(future)
|
8
|
+
channel = future.channel
|
9
|
+
log = Logging::ChannelActivityLogger.new(channel, logger, self.class)
|
10
|
+
|
11
|
+
if future.fulfilled?
|
12
|
+
log.debug("Channel #{channel} connected, initiating bolt handshake")
|
13
|
+
|
14
|
+
pipeline = channel.pipeline
|
15
|
+
pipeline.add_last(HandshakeHandler.new(pipeline_builder, handshake_completed_promise, logger))
|
16
|
+
log.debug("C: [Bolt Handshake] #{BoltProtocolUtil.handshake_string}")
|
17
|
+
channel.write_and_flush(BoltProtocolUtil.handshake_buf, channel.void_promise)
|
18
|
+
else
|
19
|
+
handshake_completed_promise.set_failure(self.class.database_unavailable_error(address, future.cause))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.database_unavailable_error(address, cause)
|
24
|
+
Neo4j::Driver::Exceptions::ServiceUnavailableException.new(
|
25
|
+
"Unable to connect to #{address}, ensure the database is running and that there is a working network connection to it.",
|
26
|
+
cause)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Neo4j::Driver
|
2
|
+
module Internal
|
3
|
+
module Async
|
4
|
+
module Connection
|
5
|
+
class ChannelConnectorImpl
|
6
|
+
def initialize(connection_settings, security_plan, logger, clock, routing_context, pipeline_builder = ChannelPipelineBuilderImpl.new, &domain_name_resolver)
|
7
|
+
@user_agent = connection_settings.user_agent
|
8
|
+
@auth_token = self.class.require_valid_auth_token(connection_settings.auth_token)
|
9
|
+
@routing_context = routing_context
|
10
|
+
@connect_timeout_millis = connection_settings.connect_timeout_millis
|
11
|
+
@security_plan = Validator.require_non_nil!(security_plan)
|
12
|
+
@pipeline_builder = pipeline_builder
|
13
|
+
@logger = Validator.require_non_nil!(logger)
|
14
|
+
@clock = Validator.require_non_nil!(clock)
|
15
|
+
@domain_name_resolver = Validator.require_non_nil!(domain_name_resolver)
|
16
|
+
end
|
17
|
+
|
18
|
+
def connect(address)
|
19
|
+
socket_host = (@domain_name_resolver.call(address.connection_host).first.ip_address rescue nil) || bracketless(address.connection_host)
|
20
|
+
|
21
|
+
channel_connected = ::Async::IO::Endpoint.tcp(socket_host, address.port).connect
|
22
|
+
|
23
|
+
# install_channel_connected_listeners(address, channel_connected, handshake_completed)
|
24
|
+
# install_handshake_completed_listeners(handshake_completed, connection_initialized)
|
25
|
+
|
26
|
+
channel_connected
|
27
|
+
rescue Errno::ECONNREFUSED => e
|
28
|
+
raise Exceptions::ServiceUnavailableException, e.message
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize_channel(channel, protocol)
|
32
|
+
protocol.initialize_channel(channel, @user_agent, @auth_token, @routing_context)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def bracketless(host)
|
38
|
+
host.delete_prefix('[').delete_suffix(']')
|
39
|
+
end
|
40
|
+
|
41
|
+
def install_channel_connected_listeners(address, channel_connected, handshake_completed)
|
42
|
+
pipeline = channel_connected.channel.pipeline
|
43
|
+
|
44
|
+
# add timeout handler to the pipeline when channel is connected. it's needed to limit amount of time code
|
45
|
+
# spends in TLS and Bolt handshakes. prevents infinite waiting when database does not respond
|
46
|
+
channel_connected.add_listener { pipeline.add_first(Inbound::ConnectTimeoutHandler.new(@connect_timeout_millis)) }
|
47
|
+
|
48
|
+
# add listener that sends Bolt handshake bytes when channel is connected
|
49
|
+
channel_connected.add_listener(ChannelConnectedListener.new(address, @pipeline_builder, handshake_completed, @logger))
|
50
|
+
end
|
51
|
+
|
52
|
+
def install_handshake_completed_listeners(handshake_completed, connection_initialized)
|
53
|
+
pipeline = handshake_completed.channel.pipeline
|
54
|
+
|
55
|
+
# remove timeout handler from the pipeline once TLS and Bolt handshakes are completed. regular protocol
|
56
|
+
# messages will flow next and we do not want to have read timeout for them
|
57
|
+
handshake_completed.add_listener { pipeline.remove(Inbound::ConnectTimeoutHandler.java_class) }
|
58
|
+
|
59
|
+
# add listener that sends an INIT message. connection is now fully established. channel pipeline if fully
|
60
|
+
# set to send/receive messages for a selected protocol version
|
61
|
+
handshake_completed.add_listener(HandshakeCompletedListener.new(@user_agent, @auth_token, @routing_context, connection_initialized))
|
62
|
+
end
|
63
|
+
|
64
|
+
class << self
|
65
|
+
def require_valid_auth_token(token)
|
66
|
+
if token.is_a? Internal::Security::InternalAuthToken
|
67
|
+
token
|
68
|
+
else
|
69
|
+
raise Exceptions::ClientException, "Unknown authentication token, `#{token}`. Please use one of the supported tokens from `#{AuthTokens.class}`."
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Neo4j::Driver
|
2
|
+
module Internal
|
3
|
+
module Async
|
4
|
+
module Connection
|
5
|
+
class ChannelPipelineBuilderImpl
|
6
|
+
def build(message_format, pipeline, logger)
|
7
|
+
# inbound handlers
|
8
|
+
pipeline.add_last(Inbound::ChunkDecoder.new(logger))
|
9
|
+
pipeline.add_last(Inbound::MessageDecoder.new)
|
10
|
+
pipeline.add_last(Inbound::InboundMessageHandler.new(message_format, logger))
|
11
|
+
|
12
|
+
# outbound handlers
|
13
|
+
pipeline.add_last(Outbound::OutboundMessageHandler::NAME, Outbound::OutboundMessageHandler.new(message_format, logger))
|
14
|
+
|
15
|
+
# last one - error handler
|
16
|
+
pipeline.add_last(Inbound::ChannelErrorHandler.new(logger))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Neo4j::Driver
|
2
|
+
module Internal
|
3
|
+
module Async
|
4
|
+
module Connection
|
5
|
+
# This is a connection used by {@link DirectConnectionProvider} to connect to a remote database.
|
6
|
+
class DirectConnection < Struct.new(:delegate, :database_name, :mode, :impersonated_user)
|
7
|
+
delegate *%i[enable_auto_read disable_auto_read reset open? release terminate_and_release server_agent
|
8
|
+
server_address server_version protocol flush], to: :delegate
|
9
|
+
alias connection delegate
|
10
|
+
|
11
|
+
def write(message1, handler1, message2 = nil, handler2 = nil)
|
12
|
+
if message2.present? && handler2.present?
|
13
|
+
delegate.write(message1, handler1, message2, handler2)
|
14
|
+
else
|
15
|
+
delegate.write(message1, handler1)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def write_and_flush(message1, handler1, message2 = nil, handler2 = nil)
|
20
|
+
if message2.present? && handler2.present?
|
21
|
+
delegate.write_and_flush(message1, handler1, message2, handler2)
|
22
|
+
else
|
23
|
+
delegate.write_and_flush(message1, handler1)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Neo4j::Driver
|
2
|
+
module Internal
|
3
|
+
module Async
|
4
|
+
module Connection
|
5
|
+
class EventLoopGroupFactory
|
6
|
+
THREAD_NAME_PREFIX = "Neo4jDriverIO"
|
7
|
+
THREAD_PRIORITY = 10
|
8
|
+
THREAD_IS_DAEMON = true
|
9
|
+
|
10
|
+
class << self
|
11
|
+
# Get class of {@link Channel} for {@link Bootstrap#channel(Class)} method.
|
12
|
+
|
13
|
+
# @return class of the channel, which should be consistent with {@link EventLoopGroup}s returned by
|
14
|
+
# {@link #newEventLoopGroup(int)}.
|
15
|
+
def channel_class
|
16
|
+
# org.neo4j.driver.internal.shaded.io.netty.channel.socket.nio.NioSocketChannel
|
17
|
+
end
|
18
|
+
|
19
|
+
# Create new {@link EventLoopGroup} with specified thread count. Returned group should by given to
|
20
|
+
# {@link Bootstrap#group(EventLoopGroup)}.
|
21
|
+
|
22
|
+
# @param threadCount amount of IO threads for the new group.
|
23
|
+
# @return new group consistent with channel class returned by {@link #channelClass()}.
|
24
|
+
def new_event_loop_group(thread_count)
|
25
|
+
DriverEventLoopGroup.new(thread_count)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Assert that current thread is not an event loop used for async IO operations. This check is needed because
|
29
|
+
# blocking API methods like {@link Session#run(String)} are implemented on top of corresponding async API methods
|
30
|
+
# like {@link AsyncSession#runAsync(String)} using basically {@link Future#get()} calls. Deadlocks might happen when IO
|
31
|
+
# thread executes blocking API call and has to wait for itself to read from the network.
|
32
|
+
|
33
|
+
# @throws IllegalStateException when current thread is an event loop IO thread.
|
34
|
+
def assert_not_in_event_loop_thread
|
35
|
+
if event_loop_thread?(Thread.current)
|
36
|
+
raise Exceptions::IllegalStateException, "Blocking operation can't be executed in IO thread because it might result in a deadlock. Please do not use blocking API when chaining futures returned by async API methods."
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Check if given thread is an event loop IO thread.
|
41
|
+
|
42
|
+
# @param thread the thread to check.
|
43
|
+
# @return {@code true} when given thread belongs to the event loop, {@code false} otherwise.
|
44
|
+
def event_loop_thread?(thread)
|
45
|
+
thread.is_a?(DriverThread)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# Same as {@link NioEventLoopGroup} but uses a different {@link ThreadFactory} that produces threads of
|
52
|
+
# {@link DriverThread} class. Such threads can be recognized by {@link #assertNotInEventLoopThread()}.
|
53
|
+
class DriverEventLoopGroup #< org.neo4j.driver.internal.shaded.io.netty.channel.nio.NioEventLoopGroup
|
54
|
+
def initialize(n_threads = nil)
|
55
|
+
end
|
56
|
+
|
57
|
+
protected
|
58
|
+
|
59
|
+
def new_default_thread_factory
|
60
|
+
DriverThreadFactory.new
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Same as {@link DefaultThreadFactory} created by {@link NioEventLoopGroup} by default, except produces threads of
|
65
|
+
# {@link DriverThread} class. Such threads can be recognized by {@link #assertNotInEventLoopThread()}.
|
66
|
+
|
67
|
+
class DriverThreadFactory #< org.neo4j.driver.internal.shaded.io.netty.util.concurrent.DefaultThreadFactory
|
68
|
+
def initialize()
|
69
|
+
super(THREAD_NAME_PREFIX, THREAD_IS_DAEMON, THREAD_PRIORITY)
|
70
|
+
end
|
71
|
+
|
72
|
+
def new_thread(r, name)
|
73
|
+
DriverThread.new(@thread_group, r, name)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class DriverThread #< org.neo4j.driver.internal.shaded.io.netty.util.concurrent.FastThreadLocalThread
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Neo4j::Driver
|
2
|
+
module Internal
|
3
|
+
module Async
|
4
|
+
module Connection
|
5
|
+
class HandshakeCompletedListener
|
6
|
+
attr_reader :user_agent, :auth_token, :routing_context, :connection_initialized_promise
|
7
|
+
|
8
|
+
def initialize(user_agent, auth_token, routing_context, connection_initialized_promise)
|
9
|
+
@user_agent = java.util.Objects.require_non_null(user_agent)
|
10
|
+
@auth_token = java.util.Objects.require_non_null(auth_token)
|
11
|
+
@routing_context = routing_context
|
12
|
+
@connection_initialized_promise = java.util.Objects.require_non_null(connection_initialized_promise)
|
13
|
+
end
|
14
|
+
|
15
|
+
def operation_complete(future)
|
16
|
+
if future.is_success?
|
17
|
+
protocol = Messaging::BoltProtocol.for_channel(future.channel)
|
18
|
+
protocol.initialize_channel(user_agent, auth_token, routing_context, connection_initialized_promise)
|
19
|
+
else
|
20
|
+
connection_initialized_promise.set_failure(future.cause)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|