neo4j-ruby-driver 4.4.0.alpha.2 → 4.4.0.alpha.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -1
  3. data/ruby/neo4j/driver/config.rb +8 -10
  4. data/ruby/neo4j/driver/graph_database.rb +0 -60
  5. data/ruby/neo4j/driver/internal/async/connection/channel_connector_impl.rb +8 -2
  6. data/ruby/neo4j/driver/internal/async/inbound/inbound_message_dispatcher.rb +1 -1
  7. data/ruby/neo4j/driver/internal/async/network_connection.rb +15 -22
  8. data/ruby/neo4j/driver/internal/async/pool/channel.rb +1 -0
  9. data/ruby/neo4j/driver/internal/async/pool/connection_pool_impl.rb +1 -0
  10. data/ruby/neo4j/driver/internal/cluster/loadbalancing/load_balancer.rb +1 -1
  11. data/ruby/neo4j/driver/internal/cluster/routing_table_registry_impl.rb +1 -1
  12. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_impl.rb +13 -21
  13. data/ruby/neo4j/driver/internal/cursor/async_result_cursor_only_factory.rb +2 -3
  14. data/ruby/neo4j/driver/internal/driver_factory.rb +10 -11
  15. data/ruby/neo4j/driver/internal/handlers/channel_releasing_reset_response_handler.rb +11 -10
  16. data/ruby/neo4j/driver/internal/handlers/legacy_pull_all_response_handler.rb +6 -6
  17. data/ruby/neo4j/driver/internal/handlers/pulln/auto_pull_response_handler.rb +7 -4
  18. data/ruby/neo4j/driver/internal/handlers/reset_response_handler.rb +1 -1
  19. data/ruby/neo4j/driver/internal/handlers/run_response_handler.rb +2 -1
  20. data/ruby/neo4j/driver/internal/internal_bookmark.rb +3 -5
  21. data/ruby/neo4j/driver/internal/internal_driver.rb +1 -1
  22. data/ruby/neo4j/driver/internal/internal_entity.rb +3 -5
  23. data/ruby/neo4j/driver/internal/messaging/v3/bolt_protocol_v3.rb +2 -3
  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/ruby/neo4j/driver/version.rb +1 -1
  28. metadata +2 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 698039b3b9cd2cf99a79e5a96f23ad4be85aabe2dbf85274b01ec8bf05301658
4
- data.tar.gz: cf29ed98589d4e6aac9469d67d3e069696091612d9a0fd8eef2e3993f2ef9a4f
3
+ metadata.gz: 92d999b42ad79f180328388f8b50e610e35190b2efc0b5ad9f799773a3d5d006
4
+ data.tar.gz: 759f1058c5dcf0c12d970dec2793bd2f6a5600aecfcdeb43f63b19630f038fb2
5
5
  SHA512:
6
- metadata.gz: 3f2beecb1b73d3394f3ea6259c4664b7aa0400472edba1aafdc02a0b5932cd90e1e5ff2bf8319e6931c341b9e74a0037d4727ceffc4e29138f188fa373aee4b0
7
- data.tar.gz: 673f97b1c0eed87beea9f0c1538eb96fe34ff92fdd9b49ef82c9dc9e54b49b0197c98e578ea399023b3b1579774e474d3019527c67ed7a62b5251fdeff078f23
6
+ metadata.gz: 50d2744664faa1596e8fe964db0b083e216f58b001a4d3d7d70218752814a164d4e83ea71f5d4b4b2330432aa58d74b12875ea182bb8f99aad701a831032cc73
7
+ data.tar.gz: 5d8f9e3e8eb358d7aa494d7be74d3ee49507ff2496f346d0b5ab9defea5c92a6017e147ae51b0e128728a667ef924cdf8b7e13f69ff398a1f6f6606d24cddeef
data/README.md CHANGED
@@ -56,12 +56,23 @@ $ bin/setup
56
56
  $ rspec spec
57
57
  ```
58
58
 
59
- In case of heap space memory error (`org.neo4j.driver.exceptions.DatabaseException: Java heap space`), you should limit the dbms memory, for example:
59
+ Known errors:
60
+
61
+ 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
62
 
61
63
  ```console
62
64
  $ 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
65
  ```
64
66
 
67
+ 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)
68
+
69
+ ```console
70
+ $ pip uninstall cffi
71
+ $ python -m pip install --upgrade pip
72
+ $ pip install cffi
73
+ $ pip install cryptography
74
+ ```
75
+
65
76
  ## Contributing
66
77
 
67
78
  Suggestions, improvements, bug reports and pull requests are welcome on GitHub at https://github.com/neo4jrb/neo4j-ruby-driver.
@@ -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,
@@ -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)
@@ -151,7 +151,7 @@ module Neo4j::Driver
151
151
  @auto_read_managing_handler.disable_auto_read_management
152
152
 
153
153
  # restore the default value of auto-read
154
- @channel.config.set_auto_read(true)
154
+ @channel.auto_read = true
155
155
  end
156
156
 
157
157
  @auto_read_managing_handler = new_handler
@@ -33,11 +33,11 @@ module Neo4j::Driver
33
33
  end
34
34
 
35
35
  def enable_auto_read
36
- set_auto_read(true) if open?
36
+ @channel.auto_read = true if open?
37
37
  end
38
38
 
39
39
  def disable_auto_read
40
- set_auto_read(false) if open?
40
+ @channel.auto_read = false if open?
41
41
  end
42
42
 
43
43
  def flush
@@ -69,13 +69,12 @@ module Neo4j::Driver
69
69
 
70
70
  def release
71
71
  if @status.compare_and_set(Status::OPEN, Status::RELEASED)
72
- @channel_pool.release(@channel)
72
+ handler = Handlers::ChannelReleasingResetResponseHandler.new(@channel, @channel_pool, @message_dispatcher, @log, @release)
73
+ write_reset_message_if_needed(handler, false)
74
+ # @metrics_listener.after_connection_released(Connection::ChannelAttributes.pool_id(@channel), @in_use_event)
75
+ # end
76
+ # @release_future
73
77
  end
74
- # handler = Handlers::ChannelReleasingResetResponseHandler.new(@channel, @channel_pool, @message_dispatcher, @clock, @release)
75
- # write_reset_message_if_needed(handler, false)
76
- # @metrics_listener.after_connection_released(Connection::ChannelAttributes.pool_id(@channel), @in_use_event)
77
- # end
78
- # @release_future
79
78
  end
80
79
 
81
80
  def terminate_and_release(reason)
@@ -91,15 +90,13 @@ module Neo4j::Driver
91
90
  private
92
91
 
93
92
  def write_reset_message_if_needed(reset_handler, is_session_reset)
94
- @channel.event_loop.execute do
95
- if is_session_reset && !open?
96
- reset_handler.on_success(java.util.Collections.empty_map)
97
- else
98
- # auto-read could've been disabled, re-enable it to automatically receive response for RESET
99
- set_auto_read(true)
100
- @message_dispatcher.enqueue(reset_handler)
101
- @channel.write_and_flush(Messaging::Request::ResetMessage::RESET).add_listener(-> (_future) { register_connection_read_timeout(@channel) })
102
- end
93
+ if is_session_reset && !open?
94
+ reset_handler.on_success
95
+ else
96
+ # auto-read could've been disabled, re-enable it to automatically receive response for RESET
97
+ @channel.auto_read = true
98
+ @message_dispatcher.enqueue(reset_handler)
99
+ @channel.write_and_flush(Messaging::Request::ResetMessage::RESET)#.add_listener(-> (_future) { register_connection_read_timeout(@channel) })
103
100
  end
104
101
  end
105
102
 
@@ -114,7 +111,7 @@ module Neo4j::Driver
114
111
  @message_dispatcher.enqueue(handler)
115
112
 
116
113
  if flush
117
- @channel.write_and_flush(message)#.add_listener(-> (_future) { register_connection_read_timeout(@channel) })
114
+ @channel.write_and_flush(message) #.add_listener(-> (_future) { register_connection_read_timeout(@channel) })
118
115
  else
119
116
  @channel.write(message)
120
117
  end
@@ -135,10 +132,6 @@ module Neo4j::Driver
135
132
  end
136
133
  end
137
134
 
138
- def set_auto_read(value)
139
- @channel.config.set_auto_read(value)
140
- end
141
-
142
135
  def verify_open(handler1, handler2)
143
136
  connection_status = @status.get
144
137
 
@@ -6,6 +6,7 @@ module Neo4j::Driver
6
6
  attr :stream
7
7
  attr_accessor :version, :protocol, :message_format, :message_dispatcher
8
8
  attr :attributes # should be attr
9
+ attr_accessor :auto_read
9
10
 
10
11
  def initialize(address, connector, logger)
11
12
  super()
@@ -20,6 +20,7 @@ module Neo4j::Driver
20
20
 
21
21
  begin
22
22
  channel = pool.acquire
23
+ @log.debug{"Channel #{channel.object_id} acquired"}
23
24
  rescue => error
24
25
  process_acquisition_error(pool, address, error)
25
26
  end
@@ -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)
@@ -2,26 +2,27 @@ module Neo4j::Driver
2
2
  module Internal
3
3
  module Handlers
4
4
  class ChannelReleasingResetResponseHandler < ResetResponseHandler
5
- def initialize(channel, pool, message_dispatcher, clock, release_future)
5
+ def initialize(channel, pool, message_dispatcher, log, release_future)
6
6
  super(message_dispatcher, release_future)
7
7
  @channel = channel
8
8
  @pool = pool
9
- @clock = clock
9
+ @log = log
10
10
  end
11
11
 
12
- def reset_completed(completion_future, success)
12
+ def reset_completed(success)
13
13
  if success
14
14
  # update the last-used timestamp before returning the channel back to the pool
15
- Async::Connection::ChannelAttributes.set_last_used_timestamp(@channel, @clock.millis)
16
- closure_stage = Util::Futures.completed_with_null
15
+ # Async::Connection::ChannelAttributes.set_last_used_timestamp(@channel, @clock.millis)
16
+ # closure_stage = Util::Futures.completed_with_null
17
17
  else
18
18
  # close the channel before returning it back to the pool if RESET failed
19
- closure_stage = Util::Futures.as_completion_stage(@channel.close)
20
- end
21
-
22
- closure_stage.exceptionally(-> (_throwable) { nil }).then_compose(-> (_ignored) { @pool.release(@channel) }).when_complete do |_, _error|
23
- completion_future.complete(nil)
19
+ @channel.close
24
20
  end
21
+ rescue
22
+ nil
23
+ ensure
24
+ @pool.release(@channel)
25
+ @log.debug { "Channel #{@channel.object_id} released." }
25
26
  end
26
27
  end
27
28
  end
@@ -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
 
@@ -212,7 +212,7 @@ module Neo4j::Driver
212
212
 
213
213
  def extract_result_summary(metadata)
214
214
  result_available_after = @run_response_handler.result_available_after
215
- @metadataExtractor.extract_summary(@query, @connection, result_available_after, metadata)
215
+ @metadata_extractor.extract_summary(@query, @connection, result_available_after, metadata)
216
216
  end
217
217
 
218
218
  def enable_auto_read
@@ -4,7 +4,6 @@ module Neo4j::Driver
4
4
  module Pulln
5
5
  class AutoPullResponseHandler < BasicPullResponseHandler
6
6
  delegate :signal, to: :@records
7
- UNINITIALIZED_RECORDS = ::Async::Queue.new
8
7
  LONG_MAX_VALUE = 2 ** 63 - 1
9
8
 
10
9
  def initialize(query, run_response_handler, connection, metadata_extractor, completion_listener, fetch_size)
@@ -20,7 +19,7 @@ module Neo4j::Driver
20
19
  @low_record_watermark = fetch_size * 0.3
21
20
  end
22
21
 
23
- @records = UNINITIALIZED_RECORDS
22
+ @records = ::Async::Queue.new
24
23
  @auto_pull_enabled = true
25
24
 
26
25
  install_record_and_summary_consumers
@@ -79,8 +78,8 @@ module Neo4j::Driver
79
78
  @summary
80
79
  end
81
80
 
82
- def list_async(map_function)
83
- pull_all_async.then_apply(-> (summary) { records_as_list(map_function) })
81
+ def list_async(&map_function)
82
+ pull_all_async.then_apply(-> (summary) { records_as_list(&map_function) })
84
83
  end
85
84
 
86
85
  def pull_all_failure_async
@@ -167,6 +166,10 @@ module Neo4j::Driver
167
166
  def completed_with_value_if_no_failure(value)
168
167
  @failure ? extract_failure : value
169
168
  end
169
+
170
+ # def request(size)
171
+ # @auto_pull_enabled ? Async { super } : super
172
+ # end
170
173
  end
171
174
  end
172
175
  end
@@ -9,7 +9,7 @@ module Neo4j::Driver
9
9
  @completion_future = completion_future
10
10
  end
11
11
 
12
- def on_success(_metadata)
12
+ def on_success(_metadata = {})
13
13
  reset_completed(true)
14
14
  end
15
15
 
@@ -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
@@ -7,7 +7,7 @@ module Neo4j::Driver
7
7
  # delegate :verify_connectivity, to: :session_factory
8
8
  delegate :metrics, :metrics_enabled?, to: :metrics_provider
9
9
  auto_closable :session
10
- sync :close, :supports_multi_db?, :verify_connectivity
10
+ sync :close, :supports_multi_db?, :verify_connectivity, :session
11
11
 
12
12
  def initialize(security_plan, session_factory, metrics_provider, logger)
13
13
  @closed = Concurrent::AtomicBoolean.new(false)
@@ -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
@@ -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)
@@ -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.2'
5
+ VERSION = '4.4.0.alpha.5'
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.2
4
+ version: 4.4.0.alpha.5
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-14 00:00:00.000000000 Z
11
+ date: 2022-06-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -136,20 +136,6 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: parallel
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
139
  - !ruby/object:Gem::Dependency
154
140
  name: rake
155
141
  requirement: !ruby/object:Gem::Requirement