neo4j-ruby-driver 4.4.0.alpha.1 → 4.4.0.alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -2
  3. data/lib/loader.rb +3 -2
  4. data/ruby/neo4j/driver/config.rb +10 -12
  5. data/ruby/neo4j/driver/graph_database.rb +0 -60
  6. data/ruby/neo4j/driver/internal/async/connection/channel_connector_impl.rb +8 -2
  7. data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +1 -1
  8. data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +1 -1
  9. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +13 -21
  10. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_only_factory.rb +2 -3
  11. data/ruby/neo4j/driver/internal/driver_factory.rb +10 -11
  12. data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +5 -5
  13. data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +6 -2
  14. data/ruby/neo4j/driver/internal/handlers/run_response_handler.rb +2 -1
  15. data/ruby/neo4j/driver/internal/internal_bookmark.rb +3 -5
  16. data/ruby/neo4j/driver/internal/internal_entity.rb +3 -5
  17. data/ruby/neo4j/driver/internal/messaging/abstract_message_writer.rb +2 -2
  18. data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +2 -3
  19. data/ruby/neo4j/driver/internal/messaging/v3/message_writer_v3.rb +11 -16
  20. data/ruby/neo4j/driver/internal/messaging/v4/message_writer_v4.rb +11 -16
  21. data/ruby/neo4j/driver/internal/messaging/v41/bolt_protocol_v41.rb +1 -1
  22. data/ruby/neo4j/driver/internal/messaging/v43/message_writer_v43.rb +12 -17
  23. data/ruby/neo4j/driver/internal/messaging/v44/message_writer_v44.rb +0 -4
  24. data/ruby/neo4j/driver/internal/packstream/pack_stream.rb +1 -1
  25. data/ruby/neo4j/driver/internal/security/security_plan_impl.rb +16 -65
  26. data/ruby/neo4j/driver/internal/security_setting.rb +41 -48
  27. data/{lib → ruby}/neo4j/driver/version.rb +1 -1
  28. metadata +3 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 66dae72d3ada4d96cffcce68f8caa4ca4d0077979b3f8e4062ab4743b127eefd
4
- data.tar.gz: 03da615177758e34cf55aa8b0ae50ec10a03e6d80ed20dc89ddc1ccac7957085
3
+ metadata.gz: dceecd30fd6fa4473c3ec6bb640b6126bd7bb06eb5057d58e46064d8c434a929
4
+ data.tar.gz: 0e1a77da3ca678a1b4a201fa0d0211a771a009a77bb81b1a0c98e331b22c5471
5
5
  SHA512:
6
- metadata.gz: c624a88a71ba6c8dc3eee672058609aeadeed4890996d7e92e97682f8fb3ffff6d275720c99abe08be73765bfd266ae56b6fb4f87fcdd562e7db5428445624d9
7
- data.tar.gz: ca7633a62d8654d82a23e7829e8b3b934fbdfbec13718193fd80a0671569d11e48fb9ebc81bbbe45a574c3a73b23b53e55dea4c4c1051c09a6329d1ec9490075
6
+ metadata.gz: fdd3c4bbdd314fb7036ce6c7fedba8a49e26b194450dea535a7aa05f380d58a6ab04ea7edbba6cf664514c1585084ad0e17c40fb719a9794f127ee3623c169db
7
+ data.tar.gz: 673a7aa8a4f3192f7b9b15b91efaca7c05dfcb79779b39ed4f014989db06672f7c293fd3948e16fc515177cae84e428f5885b3f1d3b4c081f05e580afbd66b5d
data/README.md CHANGED
@@ -42,7 +42,6 @@ This gem includes 2 different implementations: java driver wrapper and pure ruby
42
42
  ## Testing
43
43
 
44
44
  To run the tests the following tools need to be installed:
45
-
46
45
  $ brew install python
47
46
  $ pip3 install --user git+https://github.com/klobuczek/boltkit@1.3#egg=boltkit
48
47
  $ neoctrl-install -e 4.4.5 servers
@@ -56,12 +55,23 @@ $ bin/setup
56
55
  $ rspec spec
57
56
  ```
58
57
 
59
- In case of heap space memory error (`org.neo4j.driver.exceptions.DatabaseException: Java heap space`), you should limit the dbms memory, for example:
58
+ Known errors:
59
+
60
+ 1. In case of heap space memory error (`org.neo4j.driver.exceptions.DatabaseException: Java heap space`), you should limit the dbms memory, for example:
60
61
 
61
62
  ```console
62
63
  $ neoctrl-configure servers/neo4j-enterprise-4.4.5 dbms.memory.pagecache.size=600m dbms.memory.heap.max_size=600m dbms.memory.heap.initial_size=600m dbms.directories.import= dbms.connectors.default_listen_address=::
63
64
  ```
64
65
 
66
+ 2. When using command `pip3 install --user git+https://github.com/klobuczek/boltkit@1.3#egg=boltkit`, if you have m1 mac chip, you may get error when pip3 tries to install `cryptography`. Steps to take in that case (reference https://stackoverflow.com/a/70074869/2559490)
67
+
68
+ ```console
69
+ $ pip uninstall cffi
70
+ $ python -m pip install --upgrade pip
71
+ $ pip install cffi
72
+ $ pip install cryptography
73
+ ```
74
+
65
75
  ## Contributing
66
76
 
67
77
  Suggestions, improvements, bug reports and pull requests are welcome on GitHub at https://github.com/neo4jrb/neo4j-ruby-driver.
data/lib/loader.rb CHANGED
@@ -7,12 +7,13 @@ class Loader
7
7
  loader = Zeitwerk::Loader.new
8
8
  loader.tag = 'neo4j-ruby-driver'
9
9
  loader.push_dir(File.expand_path(__dir__))
10
- loader.push_dir(File.dirname(File.dirname(caller_locations(1..1).first.path)))
10
+ driver_specific_dir = File.dirname(File.dirname(caller_locations(1..1).first.path))
11
+ loader.push_dir(driver_specific_dir)
11
12
  yield loader if block_given?
12
13
  loader.ignore(File.expand_path('neo4j-*-driver_jars.rb', __dir__))
13
14
  loader.ignore(File.expand_path('neo4j_ruby_driver.rb', __dir__))
14
15
  loader.ignore(File.expand_path('org', __dir__))
15
- loader.inflector = Zeitwerk::GemInflector.new(File.expand_path('neo4j/driver', __dir__))
16
+ loader.inflector = Zeitwerk::GemInflector.new(File.expand_path('neo4j/driver', driver_specific_dir))
16
17
  loader.setup
17
18
  loader.eager_load
18
19
  end
@@ -10,7 +10,7 @@ module Neo4j
10
10
 
11
11
  attr_reader :strategy, :cert_files, :revocation_strategy
12
12
 
13
- #
13
+ # Sample config:
14
14
  # {
15
15
  # trust_strategy: {
16
16
  # strategy: :trust_custom_certificates,
@@ -38,8 +38,8 @@ module Neo4j
38
38
 
39
39
  # Console.logger = ::Logger.new(STDOUT, level: :debug)
40
40
  DEFAULTS = {
41
- # logger: ::Logger.new(nil),
42
- logger: ::Logger.new(STDOUT, level: :debug),
41
+ logger: ::Logger.new(nil),
42
+ # logger: ::Logger.new(STDOUT, level: :debug),
43
43
  # logger: Console.logger,
44
44
  leaked_sessions_logging: false,
45
45
  max_connection_pool_size: Internal::Async::Pool::PoolSettings::DEFAULT_MAX_CONNECTION_POOL_SIZE,
@@ -62,12 +62,12 @@ module Neo4j
62
62
  max_transaction_retry_time: Internal::Retry::ExponentialBackoffRetryLogic::DEFAULT_MAX_RETRY_TIME,
63
63
  metrics_enabled: false,
64
64
  # resolver: nil # :set_address_resolver
65
- trust_strategy: TrustStrategy.trust_all_certificates,
65
+ trust_strategy: { strategy: :trust_all_certificates }
66
66
  }.freeze
67
67
 
68
68
  def initialize(**config)
69
69
  merge!(DEFAULTS).merge!(config.compact)
70
- init_security_and_trust_config(config)
70
+ init_security_and_trust_config
71
71
  end
72
72
 
73
73
  def routing_settings
@@ -77,13 +77,11 @@ module Neo4j
77
77
 
78
78
  private
79
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
80
+ def init_security_and_trust_config
81
+ relevant = %i[encryption trust_strategy]
82
+ customized = slice(*relevant) == DEFAULTS.slice(*relevant)
83
+ merge!(security_settings: Neo4j::Driver::Internal::SecuritySetting.new(
84
+ fetch(:encryption), TrustStrategy.new(**fetch(:trust_strategy)), customized),
87
85
  )
88
86
  end
89
87
  end
@@ -8,66 +8,6 @@ module Neo4j::Driver
8
8
  auto_closable :driver, :routing_driver
9
9
  sync :driver
10
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
11
  def driver(uri, auth_token = nil, **config)
72
12
  internal_driver(uri, auth_token, config, Internal::DriverFactory.new)
73
13
  end
@@ -16,9 +16,15 @@ module Neo4j::Driver
16
16
  end
17
17
 
18
18
  def connect(address)
19
- socket_host = (@domain_name_resolver.call(address.connection_host).first.ip_address rescue nil) || bracketless(address.connection_host)
19
+ socket_host = (@domain_name_resolver.call(address.connection_host).first.ip_address rescue nil) ||
20
+ bracketless(address.connection_host)
20
21
 
21
- channel_connected = ::Async::IO::Endpoint.tcp(socket_host, address.port).connect
22
+ endpoint = ::Async::IO::Endpoint.tcp(socket_host, address.port)
23
+ if @security_plan.requires_encryption?
24
+ endpoint = ::Async::IO::SSLEndpoint.new(endpoint, ssl_context: @security_plan.ssl_context,
25
+ hostname: address.host)
26
+ end
27
+ channel_connected = endpoint.connect
22
28
 
23
29
  # install_channel_connected_listeners(address, channel_connected, handshake_completed)
24
30
  # install_handshake_completed_listeners(handshake_completed, connection_initialized)
@@ -26,7 +26,7 @@ module Neo4j::Driver
26
26
  @routing_tables.ensure_routing_table(context).then_flat do |handler|
27
27
  acquire(context.mode, handler.routing_table).then do |connection|
28
28
  Async::Connection::RoutingConnection.new(connection,
29
- Util::Futures.join_now_or_else_throw(context.database_name_future, Async::ConnectionContext::PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER),
29
+ Util::Futures.join_now_or_else_throw(context.database_name, Async::ConnectionContext::PENDING_DATABASE_NAME_EXCEPTION_SUPPLIER),
30
30
  context.mode, context.impersonated_user, handler)
31
31
  end
32
32
  end
@@ -4,7 +4,7 @@ module Neo4j::Driver
4
4
  class RoutingTableRegistryImpl
5
5
  def initialize(connection_pool, rediscovery, clock, logger, routing_table_purge_delay_ms)
6
6
  @factory = RoutingTableHandlerFactory.new(connection_pool, rediscovery, clock, logger, routing_table_purge_delay_ms)
7
- @routing_table_handlers = {}
7
+ @routing_table_handlers = Concurrent::Hash.new
8
8
  @principal_to_database_name_stage = {}
9
9
  @clock = clock
10
10
  @connection_pool = connection_pool
@@ -26,7 +26,7 @@ module Neo4j::Driver
26
26
  end
27
27
 
28
28
  def each_async(&action)
29
- internal_for_each_async(result_future, &action)
29
+ internal_for_each_async(&action)
30
30
  consume_async
31
31
  end
32
32
 
@@ -42,33 +42,25 @@ module Neo4j::Driver
42
42
 
43
43
  def pull_all_failure_async
44
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 }
45
+ @pull_all_handler.pull_all_failure_async.then { |error| run_error ? nil : error }
46
46
  end
47
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)
48
+ private def internal_for_each_async
49
+ while record = next_async
50
+ begin
51
+ yield record
52
+ rescue
53
+ nil
66
54
  end
67
55
  end
68
56
  end
69
57
 
70
58
  def map_successful_run_completion_async
71
- @run_error || self
59
+ run_error || self
60
+ end
61
+
62
+ def run_error
63
+ @run_handler.error
72
64
  end
73
65
  end
74
66
  end
@@ -3,11 +3,10 @@ module Neo4j::Driver
3
3
  module Cursor
4
4
  # Used by Bolt V1, V2, V3
5
5
  class AsyncResultCursorOnlyFactory
6
- def initialize(connection, run_message, run_handler, run_future, pull_handler)
6
+ def initialize(connection, run_message, run_handler, pull_handler)
7
7
  @connection = Internal::Validator.require_non_nil!(connection)
8
8
  @run_message = Internal::Validator.require_non_nil!(run_message)
9
9
  @run_handler = Internal::Validator.require_non_nil!(run_handler)
10
- @run_future = Internal::Validator.require_non_nil!(run_future)
11
10
 
12
11
  @pull_all_handler = Internal::Validator.require_non_nil!(pull_handler)
13
12
  end
@@ -17,7 +16,7 @@ module Neo4j::Driver
17
16
  @connection.write(@run_message, @run_handler) # queues the run message, will be flushed with pull message together
18
17
  @pull_all_handler.pre_populate_records
19
18
 
20
- @run_future.handle { |_ignored, error| DisposableAsyncResultCursor.new(AsyncResultCursorImpl.new(error, @run_handler, @pull_all_handler)) }
19
+ DisposableAsyncResultCursor.new(AsyncResultCursorImpl.new(@run_handler, @pull_all_handler))
21
20
  end
22
21
 
23
22
  def rx_result
@@ -67,36 +67,35 @@ module Neo4j::Driver::Internal
67
67
 
68
68
  def create_driver(uri, security_plan, address, connection_pool, eventExecutorGroup, routing_settings, retryLogic, metricsProvider, config)
69
69
  if routing_scheme?(uri.scheme.downcase)
70
- createRoutingDriver(security_plan, address, connection_pool, eventExecutorGroup, routing_settings, retryLogic, metricsProvider, config)
70
+ create_routing_driver(security_plan, address, connection_pool, eventExecutorGroup, routing_settings, retryLogic, metricsProvider, config)
71
71
  else
72
72
  assert_no_routing_context(uri, routing_settings)
73
- createDirectDriver(security_plan, address, connection_pool, retryLogic, metricsProvider, config)
73
+ create_direct_driver(security_plan, address, connection_pool, retryLogic, metricsProvider, config)
74
74
  end
75
75
  rescue => driver_error
76
76
  # we need to close the connection pool if driver creation threw exception
77
- closeConnectionPoolAndSuppressError(connection_pool, driver_error)
78
- raise driver_error
77
+ close_connection_pool_and_suppress_error(connection_pool, driver_error)
78
+ raise
79
79
  end
80
80
 
81
- def createDirectDriver(securityPlan, address, connection_pool, retryLogic, metricsProvider, config)
81
+ def create_direct_driver(securityPlan, address, connection_pool, retryLogic, metricsProvider, config)
82
82
  connection_provider = DirectConnectionProvider.new(address, connection_pool)
83
83
  driver(:Direct, securityPlan, address, connection_provider, retryLogic, metricsProvider, config)
84
84
  end
85
85
 
86
- def createRoutingDriver(securityPlan, address, connection_pool, eventExecutorGroup, routingSettings, retryLogic, metricsProvider, config)
87
- connection_provider = createLoadBalancer(address, connection_pool, eventExecutorGroup, config, routingSettings)
86
+ def create_routing_driver(securityPlan, address, connection_pool, eventExecutorGroup, routingSettings, retryLogic, metricsProvider, config)
87
+ connection_provider = create_load_balancer(address, connection_pool, eventExecutorGroup, config, routingSettings)
88
88
  driver(:Routing, securityPlan, address, connection_provider, retryLogic, metricsProvider, config)
89
89
  end
90
90
 
91
91
  def driver(type, security_plan, address, connection_provider, retry_logic, metrics_provider, config)
92
92
  session_factory = SessionFactoryImpl.new(connection_provider, retry_logic, config)
93
93
  InternalDriver.new(security_plan, session_factory, metrics_provider, config[:logger]).tap do |driver|
94
- log = config[:logger]
95
- log.info { "#{type} driver instance #{driver.object_id} created for server address #{address}" }
94
+ config[:logger]&.info { "#{type} driver instance #{driver.object_id} created for server address #{address}" }
96
95
  end
97
96
  end
98
97
 
99
- def createLoadBalancer(address, connection_pool, eventExecutorGroup, config, routingSettings)
98
+ def create_load_balancer(address, connection_pool, eventExecutorGroup, config, routingSettings)
100
99
  load_balancing_strategy = Cluster::Loadbalancing::LeastConnectedLoadBalancingStrategy.new(connection_pool, config[:logger])
101
100
  resolver = create_resolver(config)
102
101
  Cluster::Loadbalancing::LoadBalancer.new(
@@ -110,7 +109,7 @@ module Neo4j::Driver::Internal
110
109
 
111
110
  protected
112
111
 
113
- def closeConnectionPoolAndSuppressError(connection_pool, main_error)
112
+ def close_connection_pool_and_suppress_error(connection_pool, main_error)
114
113
  connection_pool.close
115
114
  rescue => close_error
116
115
  Util::ErrorUtil.add_suppressed(main_error, close_error)
@@ -9,11 +9,11 @@ module Neo4j::Driver
9
9
  RECORD_BUFFER_HIGH_WATERMARK = ENV['record_buffer_high_watermark']&.to_i || 1000
10
10
 
11
11
  def initialize(query, run_response_handler, connection, metadata_extractor, completion_listener)
12
- @query = Util::Validator.require_non_nil!(query)
13
- @run_response_handler = Util::Validator.require_non_nil!(run_response_handler)
14
- @metadata_extractor = Util::Validator.require_non_nil!(metadata_extractor)
15
- @connection = Util::Validator.require_non_nil!(connection)
16
- @completion_listener = Util::Validator.require_non_nil!(completion_listener)
12
+ @query = Internal::Validator.require_non_nil!(query)
13
+ @run_response_handler = Internal::Validator.require_non_nil!(run_response_handler)
14
+ @metadata_extractor = Internal::Validator.require_non_nil!(metadata_extractor)
15
+ @connection = Internal::Validator.require_non_nil!(connection)
16
+ @completion_listener = Internal::Validator.require_non_nil!(completion_listener)
17
17
  @records = UNINITIALIZED_RECORDS
18
18
  end
19
19
 
@@ -79,8 +79,8 @@ module Neo4j::Driver
79
79
  @summary
80
80
  end
81
81
 
82
- def list_async(map_function)
83
- pull_all_async.then_apply(-> (summary) { records_as_list(map_function) })
82
+ def list_async(&map_function)
83
+ pull_all_async.then_apply(-> (summary) { records_as_list(&map_function) })
84
84
  end
85
85
 
86
86
  def pull_all_failure_async
@@ -167,6 +167,10 @@ module Neo4j::Driver
167
167
  def completed_with_value_if_no_failure(value)
168
168
  @failure ? extract_failure : value
169
169
  end
170
+
171
+ # def request(size)
172
+ # @auto_pull_enabled ? Async { super } : super
173
+ # end
170
174
  end
171
175
  end
172
176
  end
@@ -3,7 +3,7 @@ module Neo4j::Driver
3
3
  module Handlers
4
4
  class RunResponseHandler
5
5
  include Spi::ResponseHandler
6
- attr_reader :query_keys, :result_available_after, :query_id
6
+ attr :query_keys, :result_available_after, :query_id, :error
7
7
 
8
8
  def initialize(metadata_extractor, connection, tx)
9
9
  @query_keys = []
@@ -26,6 +26,7 @@ module Neo4j::Driver
26
26
  elsif error.is_a?(Exceptions::ConnectionReadTimeoutException)
27
27
  connection.terminate_and_release(error.message)
28
28
  end
29
+ @error = error
29
30
  end
30
31
 
31
32
  def on_record(_fields)
@@ -10,14 +10,12 @@ module Neo4j::Driver
10
10
  @values = values.to_set
11
11
  end
12
12
 
13
- def eql?(other)
14
- values.eql?(other.values)
15
- end
16
-
17
13
  def ==(other)
18
- values == other.values
14
+ equal?(other) || self.class == other.class && values == other.values
19
15
  end
20
16
 
17
+ alias eql? ==
18
+
21
19
  def to_s
22
20
  "Bookmark{values=#{values}}"
23
21
  end
@@ -10,13 +10,11 @@ module Neo4j::Driver
10
10
  @properties = properties
11
11
  end
12
12
 
13
- def eql?(other)
14
- id.eql?(other.id)
15
- end
16
-
17
13
  def ==(other)
18
- id == other.id
14
+ equal?(other) || self.class == other.class && id == other.id
19
15
  end
16
+
17
+ alias eql? ==
20
18
  end
21
19
  end
22
20
  end
@@ -2,9 +2,9 @@ module Neo4j::Driver
2
2
  module Internal
3
3
  module Messaging
4
4
  class AbstractMessageWriter
5
- def initialize(packer, encoders_by_message_signature)
5
+ def initialize(packer)
6
6
  @packer = Internal::Validator.require_non_nil!(packer)
7
- @encoders_by_message_signature = Internal::Validator.require_non_nil!(encoders_by_message_signature)
7
+ @encoders_by_message_signature = Internal::Validator.require_non_nil!(build_encoders)
8
8
  end
9
9
 
10
10
  def write(msg)
@@ -58,11 +58,10 @@ module Neo4j::Driver
58
58
  end
59
59
 
60
60
  def build_result_cursor_factory(connection, query, bookmark_holder, tx, run_message, ignored)
61
- run_future = java.util.concurrent.CompletableFuture.new
62
- run_handler = Handlers::RunResponseHandler.new(run_future, METADATA_EXTRACTOR, connection, tx)
61
+ run_handler = Handlers::RunResponseHandler.new(METADATA_EXTRACTOR, connection, tx)
63
62
  pull_handler = Handlers::PullHandlers.new_bolt_v3_pull_all_handler(query, run_handler, connection, bookmark_holder, tx)
64
63
 
65
- Cursor::AsyncResultCursorOnlyFactory.new(connection, run_message, run_handler, run_future, pull_handler)
64
+ Cursor::AsyncResultCursorOnlyFactory.new(connection, run_message, run_handler, pull_handler)
66
65
  end
67
66
 
68
67
  def verify_database_name_before_transaction(database_name)
@@ -3,27 +3,22 @@ module Neo4j::Driver
3
3
  module Messaging
4
4
  module V3
5
5
  class MessageWriterV3 < AbstractMessageWriter
6
- def initialize(output)
7
- super(Common::CommonValuePacker.new(output), build_encoders)
8
- end
9
-
10
6
  private
11
7
 
12
8
  def build_encoders
13
- result = Util::Iterables.new_hash_map_with_size(9)
14
- result.put(Request::HelloMessage::SIGNATURE, Encode::HelloMessageEncoder.new)
15
- result.put(Request::GoodbyeMessage::SIGNATURE, Encode::GoodbyeMessageEncoder.new)
16
-
17
- result.put(Request::RunWithMetadataMessage::SIGNATURE, Encode::RunWithMetadataMessageEncoder.new)
18
- result.put(Request::DiscardAllMessage::SIGNATURE, Encode::DiscardAllMessageEncoder.new)
19
- result.put(Request::PullAllMessage::SIGNATURE, Encode::PullAllMessageEncoder.new)
9
+ {
10
+ Request::HelloMessage::SIGNATURE => Encode::HelloMessageEncoder.new,
11
+ Request::GoodbyeMessage::SIGNATURE => Encode::GoodbyeMessageEncoder.new,
20
12
 
21
- result.put(Request::BeginMessage::SIGNATURE, Encode::BeginMessageEncoder.new)
22
- result.put(Request::CommitMessage::SIGNATURE, Encode::CommitMessageEncoder.new)
23
- result.put(Request::RollbackMessage::SIGNATURE, Encode::RollbackMessageEncoder.new)
24
- result.put(Request::ResetMessage::SIGNATURE, Encode::ResetMessageEncoder.new)
13
+ Request::RunWithMetadataMessage::SIGNATURE => Encode::RunWithMetadataMessageEncoder.new,
14
+ Request::DiscardAllMessage::SIGNATURE => Encode::DiscardAllMessageEncoder.new,
15
+ Request::PullAllMessage::SIGNATURE => Encode::PullAllMessageEncoder.new,
25
16
 
26
- result
17
+ Request::BeginMessage::SIGNATURE => Encode::BeginMessageEncoder.new,
18
+ Request::CommitMessage::SIGNATURE => Encode::CommitMessageEncoder.new,
19
+ Request::RollbackMessage::SIGNATURE => Encode::RollbackMessageEncoder.new,
20
+ Request::ResetMessage::SIGNATURE => Encode::ResetMessageEncoder.new,
21
+ }
27
22
  end
28
23
  end
29
24
  end
@@ -3,28 +3,23 @@ module Neo4j::Driver
3
3
  module Messaging
4
4
  module V4
5
5
  class MessageWriterV4 < AbstractMessageWriter
6
- def initialize(output)
7
- super(Common::CommonValuePacker.new(output), build_encoders)
8
- end
9
-
10
6
  private
11
7
 
12
8
  def build_encoders
13
- result = Util::Iterables.new_hash_map_with_size(9)
14
- result.put(Request::HelloMessage::SIGNATURE, Encode::HelloMessageEncoder.new)
15
- result.put(Request::GoodbyeMessage::SIGNATURE, Encode::GoodbyeMessageEncoder.new)
16
- result.put(Request::RunWithMetadataMessage::SIGNATURE, Encode::RunWithMetadataMessageEncoder.new)
17
-
18
- result.put(Request::DiscardAllMessage::SIGNATURE, Encode::DiscardAllMessageEncoder.new) # new
19
- result.put(Request::PullMessage::SIGNATURE, Encode::PullMessageEncoder.new) # new
9
+ {
10
+ Request::HelloMessage::SIGNATURE => Encode::HelloMessageEncoder.new,
11
+ Request::GoodbyeMessage::SIGNATURE => Encode::GoodbyeMessageEncoder.new,
12
+ Request::RunWithMetadataMessage::SIGNATURE => Encode::RunWithMetadataMessageEncoder.new,
20
13
 
21
- result.put(Request::BeginMessage::SIGNATURE, Encode::BeginMessageEncoder.new)
22
- result.put(Request::CommitMessage::SIGNATURE, Encode::CommitMessageEncoder.new)
23
- result.put(Request::RollbackMessage::SIGNATURE, Encode::RollbackMessageEncoder.new)
14
+ Request::DiscardAllMessage::SIGNATURE => Encode::DiscardAllMessageEncoder.new, # new
15
+ Request::PullMessage::SIGNATURE => Encode::PullMessageEncoder.new, # new
24
16
 
25
- result.put(Request::ResetMessage::SIGNATURE, Encode::ResetMessageEncoder.new)
17
+ Request::BeginMessage::SIGNATURE => Encode::BeginMessageEncoder.new,
18
+ Request::CommitMessage::SIGNATURE => Encode::CommitMessageEncoder.new,
19
+ Request::RollbackMessage::SIGNATURE => Encode::RollbackMessageEncoder.new,
26
20
 
27
- result
21
+ Request::ResetMessage::SIGNATURE => Encode::ResetMessageEncoder.new,
22
+ }
28
23
  end
29
24
  end
30
25
  end
@@ -7,7 +7,7 @@ module Neo4j::Driver
7
7
  INSTANCE = new
8
8
 
9
9
  def create_message_format
10
- V44::MessageFormatV4.new
10
+ V4::MessageFormatV4.new
11
11
  end
12
12
 
13
13
  def build_result_cursor_factory(connection, query, bookmark_holder, tx, run_message, fetch_size)
@@ -8,29 +8,24 @@ module Neo4j::Driver
8
8
 
9
9
  # new messages such as ROUTE
10
10
  class MessageWriterV43 < AbstractMessageWriter
11
- def initialize(output)
12
- super(Common::CommonValuePacker.new(output), build_encoders)
13
- end
14
-
15
11
  private
16
12
 
17
13
  def build_encoders
18
- result = Util::Iterables.new_hash_map_with_size(9)
19
- result.put(Request::HelloMessage::SIGNATURE, Encode::HelloMessageEncoder.new)
20
- result.put(Request::GoodbyeMessage::SIGNATURE, Encode::GoodbyeMessageEncoder.new)
21
- result.put(Request::RunWithMetadataMessage::SIGNATURE, Encode::RunWithMetadataMessageEncoder.new)
22
- result.put(Request::RouteMessage::SIGNATURE, Encode::RouteMessageEncoder.new) # new
23
-
24
- result.put(Request::DiscardMessage::SIGNATURE, Encode::DiscardMessageEncoder.new)
25
- result.put(Request::PullMessage::SIGNATURE, Encode::PullMessageEncoder.new)
14
+ {
15
+ Request::HelloMessage::SIGNATURE => Encode::HelloMessageEncoder.new,
16
+ Request::GoodbyeMessage::SIGNATURE => Encode::GoodbyeMessageEncoder.new,
17
+ Request::RunWithMetadataMessage::SIGNATURE => Encode::RunWithMetadataMessageEncoder.new,
18
+ Request::RouteMessage::SIGNATURE => Encode::RouteMessageEncoder.new, # new
26
19
 
27
- result.put(Request::BeginMessage::SIGNATURE, Encode::BeginMessageEncoder.new)
28
- result.put(Request::CommitMessage::SIGNATURE, Encode::CommitMessageEncoder.new)
29
- result.put(Request::RollbackMessage::SIGNATURE, Encode::RollbackMessageEncoder.new)
20
+ Request::DiscardMessage::SIGNATURE => Encode::DiscardMessageEncoder.new,
21
+ Request::PullMessage::SIGNATURE => Encode::PullMessageEncoder.new,
30
22
 
31
- result.put(Request::ResetMessage::SIGNATURE, Encode::ResetMessageEncoder.new)
23
+ Request::BeginMessage::SIGNATURE => Encode::BeginMessageEncoder.new,
24
+ Request::CommitMessage::SIGNATURE => Encode::CommitMessageEncoder.new,
25
+ Request::RollbackMessage::SIGNATURE => Encode::RollbackMessageEncoder.new,
32
26
 
33
- result
27
+ Request::ResetMessage::SIGNATURE => Encode::ResetMessageEncoder.new,
28
+ }
34
29
  end
35
30
  end
36
31
  end
@@ -3,10 +3,6 @@ module Neo4j::Driver
3
3
  module Messaging
4
4
  module V44
5
5
  class MessageWriterV44 < AbstractMessageWriter
6
- def initialize(output)
7
- super(output, build_encoders)
8
- end
9
-
10
6
  private
11
7
 
12
8
  def build_encoders
@@ -171,7 +171,7 @@ module Neo4j::Driver
171
171
  elsif size < PLUS_2_TO_THE_8
172
172
  write_byte(STRING_8).write_byte(size)
173
173
  elsif size < PLUS_2_TO_THE_16
174
- write_byte(BYTES_16).write_short(size)
174
+ write_byte(STRING_16).write_short(size)
175
175
  else
176
176
  write_byte(STRING_32).write_int(size)
177
177
  end
@@ -1,22 +1,20 @@
1
1
  module Neo4j::Driver::Internal
2
2
  module Security
3
- class SecurityPlanImpl < Struct.new(:requires_encryption, :ssl_context, :requires_hostname_verification,
3
+ class SecurityPlanImpl < Struct.new(:requires_encryption?, :ssl_context, :requires_hostname_verification?,
4
4
  :revocation_strategy)
5
5
  class << self
6
6
  def for_all_certificates(requires_hostname_verification, revocation_strategy)
7
- ssl_context = javax.net.ssl.SSLContext.get_instance('TLS')
8
- ssl_context.init(javax.net.ssl.KeyManager[0].new, [TrustAllTrustManager.new].to_java(javax.net.ssl.KeyManager), nil)
9
- new(true, ssl_context, requires_hostname_verification, revocation_strategy)
7
+ new(true, OpenSSL::SSL::SSLContext.new, requires_hostname_verification, revocation_strategy)
10
8
  end
11
9
 
12
- def for_custom_ca_signed_certificate(cert_file, requires_hostname_verification, revocation_strategy)
13
- ssl_context = config_ssl_context(cert_file, revocation_strategy)
14
- new(true, ssl_context, requires_hostname_verification, revocation_strategy)
10
+ def for_custom_ca_signed_certificates(cert_files, requires_hostname_verification, revocation_strategy)
11
+ new(true, custom_ca_signed_context(cert_files, requires_hostname_verification),
12
+ requires_hostname_verification, revocation_strategy)
15
13
  end
16
14
 
17
- def for_system_ca_signed_certificate(requires_hostname_verification, revocation_strategy)
18
- ssl_context = config_ssl_context(nil, revocation_strategy)
19
- new(true, ssl_context, requires_hostname_verification, revocation_strategy)
15
+ def for_system_ca_signed_certificates(requires_hostname_verification, revocation_strategy)
16
+ new(true, ca_signed_context(requires_hostname_verification), requires_hostname_verification,
17
+ revocation_strategy)
20
18
  end
21
19
 
22
20
  def insecure
@@ -25,68 +23,21 @@ module Neo4j::Driver::Internal
25
23
 
26
24
  private
27
25
 
28
- def configure_ssl_context(custom_cert_file, revocation_strategy)
29
- trusted_key_store = java.security.KeyStore.get_instance(java.security.KeyStore.get_default_type)
30
- trusted_key_store.load(nil, nil)
31
-
32
- if !custom_cert_file.nil?
33
- Util::CertificateTool.loadX509_cert(custom_cert_file, trusted_key_store)
34
- else
35
- load_system_certificates(trusted_key_store)
36
- end
37
-
38
- pkix_builder_parameters = java.security.cert.PKIXBuilderParameters.new(trusted_key_store, java.security.cert.X509CertSelector.new)
39
- pkix_builder_parameters.set_revocation_enabled(RevocationStrategy.requires_revocation_checking?(revocation_strategy))
40
-
41
- if RevocationStrategy.requires_revocation_checking?(revocation_strategy)
42
- java.lang.System.set_property('jdk.tls.client.enableStatusRequestExtension', true)
43
- if revocation_strategy == RevocationStrategy::VERIFY_IF_PRESENT
44
- java.security.Security.set_property('ocsp.enable', true)
45
- end
26
+ def ca_signed_context(requires_hostname_verification)
27
+ OpenSSL::SSL::SSLContext.new.tap do |context|
28
+ context.verify_mode = OpenSSL::SSL::VERIFY_PEER
29
+ context.verify_hostname = requires_hostname_verification
46
30
  end
47
-
48
- ssl_context = javax.net.ssl.SSLContext.get_instance('TLS')
49
-
50
- trust_manager_factory = javax.net.ssl.TrustManager.get_instance(javax.net.ssl.TrustManagerFactory.get_default_algorithm)
51
- trust_manager_factory.init(javax.net.ssl.CertPathTrustManagerParameters.new(pkix_builder_parameters))
52
- ssl_context.init(javax.net.ssl.KeyManager[0].new, trust_manager_factory.get_trust_managers, nil)
53
- ssl_context
54
31
  end
55
32
 
56
- def load_system_certificates(trusted_key_store)
57
- temp_factory = javax.net.ssl.TrustManagerFactory.get_instance(javax.net.ssl.TrustManagerFactory.get_default_algorithm)
58
- temp_factory.init(nil)
59
-
60
- x509_trust_manager = nil
61
- temp_factory.get_trust_managers.each do |trust_manager|
62
- if trust_manager.is_a?(javax.net.ssl.X509TrustManager)
63
- x509_trust_manager = javax.net.ssl.X509TrustManager.java_class.cast(trust_manager)
64
- break
33
+ def custom_ca_signed_context(cert_files, requires_hostname_verification)
34
+ ca_signed_context(requires_hostname_verification).tap do |context|
35
+ context.cert_store = OpenSSL::X509::Store.new.tap do |store|
36
+ cert_files.each(&store.method(:add_file))
65
37
  end
66
38
  end
67
-
68
- if x509_trust_manager.nil?
69
- raise Neo4j::Driver::Exceptions::CertificateException, 'No system certificates found'
70
- else
71
- Util::CertificateTool.load_x509_cert(x509_trust_manager.get_accepted_issuer, trusted_key_store)
72
- end
73
39
  end
74
40
  end
75
-
76
- class TrustAllTrustManager
77
- def check_client_trusted(chain, auth_type)
78
- raise Neo4j::Driver::Exceptions::CertificateException, 'All client connections to this client are forbidden.'
79
- end
80
-
81
- def check_server_trusted(chain, auth_type)
82
- end
83
-
84
- def get_accepted_issuers
85
- java.security.cert.X509Certificate[0].new
86
- end
87
- end
88
-
89
- private_constant :TrustAllTrustManager
90
41
  end
91
42
  end
92
43
  end
@@ -1,72 +1,65 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Neo4j::Driver::Internal
4
- class SecuritySetting
5
- include Scheme
3
+ module Neo4j::Driver
4
+ module Internal
5
+ class SecuritySetting
6
+ include Scheme
6
7
 
7
- attr_reader :encrypted, :trust_strategy, :customized
8
+ attr_reader :encrypted, :trust_strategy, :customized
8
9
 
9
- def initialize(encrypted, trust_strategy, customized)
10
- @encrypted = encrypted
11
- @trust_strategy = trust_strategy
12
- @customized = customized
13
- end
10
+ def initialize(encrypted, trust_strategy, customized)
11
+ @encrypted = encrypted
12
+ @trust_strategy = trust_strategy
13
+ @customized = customized
14
+ end
14
15
 
15
- def create_security_plan(uri_scheme)
16
- validate_scheme!(uri_scheme)
17
- begin
16
+ def create_security_plan(uri_scheme)
17
+ validate_scheme!(uri_scheme)
18
18
  if security_scheme?(uri_scheme)
19
19
  assert_security_settings_not_user_configured(uri_scheme)
20
20
  create_security_plan_from_scheme(uri_scheme)
21
21
  else
22
22
  create_security_plan_impl(encrypted, trust_strategy)
23
23
  end
24
- # rescue java.security.GeneralSecurityException, IOError
25
24
  rescue IOError
26
25
  raise Neo4j::Driver::Exceptions::ClientException, 'Unable to establish SSL parameters'
27
26
  end
28
- end
29
27
 
30
- def create_security_plan_from_scheme(uri_scheme)
31
- if high_trust_scheme?(uri_scheme)
32
- org.neo4j.driver.internal.security.SecurityPlanImpl.forSystemCASignedCertificates(
33
- true, org.neo4j.driver.internal.RevocationStrategy::NO_CHECKS
34
- )
35
- else
36
- org.neo4j.driver.internal.security.SecurityPlanImpl.forAllCertificates(false, org.neo4j.driver.internal.RevocationStrategy::NO_CHECKS)
28
+ def create_security_plan_from_scheme(uri_scheme)
29
+ if high_trust_scheme?(uri_scheme)
30
+ Security::SecurityPlanImpl.for_system_ca_signed_certificates(true, RevocationStrategy::NO_CHECKS)
31
+ else
32
+ Security::SecurityPlanImpl.for_all_certificates(false, RevocationStrategy::NO_CHECKS)
33
+ end
37
34
  end
38
- end
39
35
 
40
- private
36
+ private
41
37
 
42
- def assert_security_settings_not_user_configured(uri_scheme)
43
- return unless customized
44
-
45
- raise Neo4j::Driver::Exceptions::ClientException,
46
- "Scheme #{uri_scheme} is not configurable with manual encryption and trust settings"
47
- end
38
+ def assert_security_settings_not_user_configured(uri_scheme)
39
+ if customized
40
+ raise Neo4j::Driver::Exceptions::ClientException,
41
+ "Scheme #{uri_scheme} is not configurable with manual encryption and trust settings"
42
+ end
43
+ end
48
44
 
49
- def create_security_plan_impl(encrypted, trust_strategy)
50
- return Security::SecurityPlanImpl.insecure unless encrypted
45
+ def create_security_plan_impl(encrypted, trust_strategy)
46
+ return Security::SecurityPlanImpl.insecure unless encrypted
51
47
 
52
- hostname_verification_enabled = trust_strategy.hostname_verification_enabled?
53
- revocation_strategy = trust_strategy.revocation_strategy
48
+ hostname_verification_enabled = trust_strategy.hostname_verification_enabled?
49
+ revocation_strategy = trust_strategy.revocation_strategy
54
50
 
55
- case trust_strategy.strategy
56
- when Config::TrustStrategy::TRUST_CUSTOM_CA_SIGNED_CERTIFICATES
57
- return Security::SecurityPlanImpl.forCustomCASignedCertificates(
58
- trust_strategy.cert_file_to_java, hostname_verification_enabled, revocation_strategy
59
- )
60
- when Config::TrustStrategy::TRUST_SYSTEM_CA_SIGNED_CERTIFICATES
61
- return Security::SecurityPlanImpl.forSystemCASignedCertificates(
62
- hostname_verification_enabled, revocation_strategy
63
- )
64
- when Config::TrustStrategy::TRUST_ALL_CERTIFICATES
65
- return Security::SecurityPlanImpl.forAllCertificates(
66
- hostname_verification_enabled, revocation_strategy
67
- )
68
- else
69
- raise ClientException, "Unknown TLS authentication strategy: #{trust_strategy.strategy}"
51
+ case trust_strategy.strategy
52
+ when Config::TrustStrategy::TRUST_CUSTOM_CA_SIGNED_CERTIFICATES
53
+ Security::SecurityPlanImpl.for_custom_ca_signed_certificates(
54
+ trust_strategy.cert_files, hostname_verification_enabled, revocation_strategy)
55
+ when Config::TrustStrategy::TRUST_SYSTEM_CA_SIGNED_CERTIFICATES
56
+ Security::SecurityPlanImpl
57
+ .for_system_ca_signed_certificates(hostname_verification_enabled, revocation_strategy)
58
+ when Config::TrustStrategy::TRUST_ALL_CERTIFICATES
59
+ Security::SecurityPlanImpl.for_all_certificates(hostname_verification_enabled, revocation_strategy)
60
+ else
61
+ raise ClientException, "Unknown TLS authentication strategy: #{trust_strategy.strategy}"
62
+ end
70
63
  end
71
64
  end
72
65
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Neo4j
4
4
  module Driver
5
- VERSION = '4.4.0.alpha.1'
5
+ VERSION = '4.4.0.alpha.4'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: neo4j-ruby-driver
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.4.0.alpha.1
4
+ version: 4.4.0.alpha.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Heinrich Klobuczek
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-13 00:00:00.000000000 Z
11
+ date: 2022-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -260,7 +260,6 @@ files:
260
260
  - lib/neo4j/driver/types/offset_time.rb
261
261
  - lib/neo4j/driver/types/point.rb
262
262
  - lib/neo4j/driver/types/time.rb
263
- - lib/neo4j/driver/version.rb
264
263
  - lib/neo4j_ruby_driver.rb
265
264
  - ruby/neo4j/driver.rb
266
265
  - ruby/neo4j/driver/access_mode.rb
@@ -489,6 +488,7 @@ files:
489
488
  - ruby/neo4j/driver/session_config.rb
490
489
  - ruby/neo4j/driver/transaction_config.rb
491
490
  - ruby/neo4j/driver/values.rb
491
+ - ruby/neo4j/driver/version.rb
492
492
  homepage: https://github.com/neo4jrb/neo4j-ruby-driver
493
493
  licenses:
494
494
  - MIT