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

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 -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