cassandra-driver 1.0.0.rc.1-java → 1.1.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +58 -18
  3. data/lib/cassandra.rb +132 -93
  4. data/lib/cassandra/auth.rb +3 -3
  5. data/lib/cassandra/cluster.rb +65 -39
  6. data/lib/cassandra/cluster/client.rb +67 -28
  7. data/lib/cassandra/{client/connection_manager.rb → cluster/connection_pool.rb} +9 -3
  8. data/lib/cassandra/cluster/connector.rb +101 -30
  9. data/lib/cassandra/cluster/control_connection.rb +160 -96
  10. data/lib/cassandra/{client/null_logger.rb → cluster/failed_connection.rb} +12 -14
  11. data/lib/cassandra/cluster/options.rb +26 -11
  12. data/lib/cassandra/cluster/schema.rb +22 -1
  13. data/lib/cassandra/column.rb +5 -0
  14. data/lib/cassandra/driver.rb +46 -12
  15. data/lib/cassandra/errors.rb +5 -5
  16. data/lib/cassandra/execution/options.rb +42 -8
  17. data/lib/cassandra/execution/trace.rb +4 -4
  18. data/lib/cassandra/executors.rb +111 -0
  19. data/lib/cassandra/future.rb +88 -64
  20. data/lib/cassandra/keyspace.rb +12 -0
  21. data/lib/cassandra/load_balancing.rb +10 -0
  22. data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +10 -5
  23. data/lib/cassandra/load_balancing/policies/round_robin.rb +7 -5
  24. data/lib/cassandra/load_balancing/policies/token_aware.rb +31 -10
  25. data/lib/cassandra/load_balancing/policies/white_list.rb +4 -7
  26. data/lib/cassandra/null_logger.rb +35 -0
  27. data/lib/cassandra/protocol/cql_protocol_handler.rb +8 -1
  28. data/lib/cassandra/protocol/requests/query_request.rb +1 -11
  29. data/lib/cassandra/result.rb +34 -9
  30. data/lib/cassandra/session.rb +6 -0
  31. data/lib/cassandra/statements/prepared.rb +5 -1
  32. data/lib/cassandra/table.rb +5 -0
  33. data/lib/cassandra/util.rb +130 -0
  34. data/lib/cassandra/version.rb +1 -1
  35. metadata +40 -50
  36. data/lib/cassandra/client.rb +0 -144
  37. data/lib/cassandra/client/batch.rb +0 -212
  38. data/lib/cassandra/client/client.rb +0 -591
  39. data/lib/cassandra/client/column_metadata.rb +0 -54
  40. data/lib/cassandra/client/connector.rb +0 -273
  41. data/lib/cassandra/client/execute_options_decoder.rb +0 -59
  42. data/lib/cassandra/client/peer_discovery.rb +0 -50
  43. data/lib/cassandra/client/prepared_statement.rb +0 -314
  44. data/lib/cassandra/client/query_result.rb +0 -230
  45. data/lib/cassandra/client/request_runner.rb +0 -70
  46. data/lib/cassandra/client/result_metadata.rb +0 -48
  47. data/lib/cassandra/client/void_result.rb +0 -78
@@ -18,9 +18,9 @@
18
18
 
19
19
  module Cassandra
20
20
  module Auth
21
- # An auth provider is a factory for {Cassandra::Auth::Authenticator} instances
22
- # (or objects matching that interface). Its {#create_authenticator} will be
23
- # called once for each connection that requires authentication.
21
+ # An auth provider is a factory for {Cassandra::Auth::Authenticator authenticator} instances (or objects matching that interface). Its
22
+ # {#create_authenticator} will be called once for each connection that
23
+ # requires authentication.
24
24
  #
25
25
  # If the authentication requires keeping state, keep that in the
26
26
  # authenticator instances, not in the auth provider.
@@ -17,8 +17,7 @@
17
17
  #++
18
18
 
19
19
  module Cassandra
20
- # Cluster represents a cassandra cluster. It serves as a {Cassandra::Session}
21
- # factory and a collection of metadata.
20
+ # Cluster represents a cassandra cluster. It serves as a {Cassandra::Session session factory} factory and a collection of metadata.
22
21
  #
23
22
  # @see Cassandra::Cluster#connect Creating a new session
24
23
  # @see Cassandra::Cluster#each_host Getting all peers in the cluster
@@ -26,46 +25,11 @@ module Cassandra
26
25
  class Cluster
27
26
  extend Forwardable
28
27
 
29
- # @!method host(address)
30
- # Find a host by its address
31
- # @param address [IPAddr, String] ip address
32
- # @return [Cassandra::Host, nil] host or nil
33
- #
34
- # @!method has_host?(address)
35
- # Determine if a host by a given address exists
36
- # @param address [IPAddr, String] ip address
37
- # @return [Boolean] true or false
38
- def_delegators :@registry, :host, :has_host?
39
-
40
- # @!method keyspace(name)
41
- # Find a keyspace by name
42
- # @param name [String] keyspace name
43
- # @return [Cassandra::Keyspace, nil] keyspace or nil
44
- #
45
- # @!method has_keyspace?(name)
46
- # Determine if a keyspace by a given name exists
47
- # @param name [String] keyspace name
48
- # @return [Boolean] true or false
49
- def_delegators :@schema, :keyspace, :has_keyspace?
50
-
51
- # @!method name
52
- # Return cluster's name
53
- # @return [String] cluster's name
54
- #
55
- # @!method find_replicas(keyspace, statement)
56
- # Return replicas for a given statement and keyspace
57
- # @note an empty list is returned when statement/keyspace information is
58
- # not enough to determine replica list.
59
- # @param keyspace [String] keyspace name
60
- # @param statement [Cassandra::Statement] statement for which to find
61
- # replicas
62
- # @return [Array<Cassandra::Host>] a list of replicas
63
- def_delegators :@metadata, :name, :find_replicas
64
-
65
28
  # @private
66
- def initialize(logger, io_reactor, control_connection, cluster_registry, cluster_schema, cluster_metadata, execution_options, connection_options, load_balancing_policy, reconnection_policy, retry_policy, address_resolution_policy, connector, futures_factory)
29
+ def initialize(logger, io_reactor, executor, control_connection, cluster_registry, cluster_schema, cluster_metadata, execution_options, connection_options, load_balancing_policy, reconnection_policy, retry_policy, address_resolution_policy, connector, futures_factory)
67
30
  @logger = logger
68
31
  @io_reactor = io_reactor
32
+ @executor = executor
69
33
  @control_connection = control_connection
70
34
  @registry = cluster_registry
71
35
  @schema = cluster_schema
@@ -78,8 +42,26 @@ module Cassandra
78
42
  @address_resolver = address_resolution_policy
79
43
  @connector = connector
80
44
  @futures = futures_factory
45
+
46
+ @control_connection.on_close do |cause|
47
+ @load_balancing_policy.teardown(self) rescue nil
48
+ end
81
49
  end
82
50
 
51
+ # @!method name
52
+ # Return cluster's name
53
+ # @return [String] cluster's name
54
+ #
55
+ # @!method find_replicas(keyspace, statement)
56
+ # Return replicas for a given statement and keyspace
57
+ # @note an empty list is returned when statement/keyspace information is
58
+ # not enough to determine replica list.
59
+ # @param keyspace [String] keyspace name
60
+ # @param statement [Cassandra::Statement] statement for which to find
61
+ # replicas
62
+ # @return [Array<Cassandra::Host>] a list of replicas
63
+ def_delegators :@metadata, :name, :find_replicas
64
+
83
65
  # Register a cluster state listener. State listener will start receiving
84
66
  # notifications about topology and schema changes
85
67
  #
@@ -115,6 +97,17 @@ module Cassandra
115
97
  end
116
98
  alias :hosts :each_host
117
99
 
100
+ # @!method host(address)
101
+ # Find a host by its address
102
+ # @param address [IPAddr, String] ip address
103
+ # @return [Cassandra::Host, nil] host or nil
104
+ #
105
+ # @!method has_host?(address)
106
+ # Determine if a host by a given address exists
107
+ # @param address [IPAddr, String] ip address
108
+ # @return [Boolean] true or false
109
+ def_delegators :@registry, :host, :has_host?
110
+
118
111
  # Yield or enumerate each keyspace defined in this cluster
119
112
  # @overload each_keyspace
120
113
  # @yieldparam keyspace [Cassandra::Keyspace] current keyspace
@@ -128,6 +121,35 @@ module Cassandra
128
121
  end
129
122
  alias :keyspaces :each_keyspace
130
123
 
124
+ # @!method keyspace(name)
125
+ # Find a keyspace by name
126
+ # @param name [String] keyspace name
127
+ # @return [Cassandra::Keyspace, nil] keyspace or nil
128
+ #
129
+ # @!method has_keyspace?(name)
130
+ # Determine if a keyspace by a given name exists
131
+ # @param name [String] keyspace name
132
+ # @return [Boolean] true or false
133
+ def_delegators :@schema, :keyspace, :has_keyspace?
134
+
135
+ # @!method refresh_schema_async
136
+ # Trigger an asynchronous schema metadata refresh
137
+ # @return [Cassandra::Future<nil>] a future that will be fulfilled when
138
+ # schema metadata has been refreshed
139
+ def_delegator :@control_connection, :refresh_schema_async_maybe_retry, \
140
+ :refresh_schema_async
141
+
142
+ # Synchronously refresh schema metadata
143
+ #
144
+ # @return [nil] nothing
145
+ # @raise [Cassandra::Errors::ClientError] when cluster is disconnected
146
+ # @raise [Cassandra::Error] other unexpected errors
147
+ #
148
+ # @see Cassandra::Cluster#refresh_schema_async
149
+ def refresh_schema
150
+ refresh_schema_async.get
151
+ end
152
+
131
153
  # Asynchronously create a new session, optionally scoped to a keyspace
132
154
  #
133
155
  # @param keyspace [String] optional keyspace to scope session to
@@ -195,6 +217,8 @@ module Cassandra
195
217
  else
196
218
  f.on_failure {|e| promise.break(e)}
197
219
  end
220
+
221
+ @executor.shutdown
198
222
  end
199
223
 
200
224
  promise.future
@@ -217,8 +241,10 @@ module Cassandra
217
241
  end
218
242
 
219
243
  require 'cassandra/cluster/client'
244
+ require 'cassandra/cluster/connection_pool'
220
245
  require 'cassandra/cluster/connector'
221
246
  require 'cassandra/cluster/control_connection'
247
+ require 'cassandra/cluster/failed_connection'
222
248
  require 'cassandra/cluster/metadata'
223
249
  require 'cassandra/cluster/options'
224
250
  require 'cassandra/cluster/registry'
@@ -63,11 +63,12 @@ module Cassandra
63
63
  @connected_future = begin
64
64
  @logger.info('Creating session')
65
65
  @registry.add_listener(self)
66
+ @schema.add_listener(self)
66
67
 
67
68
  futures = @connecting_hosts.map do |(host, distance)|
68
69
  f = connect_to_host(host, distance)
69
70
  f.recover do |error|
70
- Cassandra::Client::FailedConnection.new(error, host)
71
+ FailedConnection.new(error, host)
71
72
  end
72
73
  end
73
74
 
@@ -100,6 +101,7 @@ module Cassandra
100
101
 
101
102
  @closed_future = begin
102
103
  @registry.remove_listener(self)
104
+ @schema.remove_listener(self)
103
105
 
104
106
  if state == :connecting
105
107
  f = @connected_future.recover.flat_map { close_connections }
@@ -138,7 +140,7 @@ module Cassandra
138
140
  end
139
141
 
140
142
  def host_down(host)
141
- manager = nil
143
+ pool = nil
142
144
 
143
145
  synchronize do
144
146
  return Ione::Future.resolved if !@connections.has_key?(host) && !@connecting_hosts.include?(host)
@@ -147,18 +149,30 @@ module Cassandra
147
149
  @prepared_statements.delete(host)
148
150
  @preparing_statements.delete(host)
149
151
 
150
- manager = @connections.delete(host)
152
+ pool = @connections.delete(host)
151
153
  end
152
154
 
153
- if manager
154
- Ione::Future.all(*manager.snapshot.map! {|c| c.close}).map(nil)
155
+ if pool
156
+ Ione::Future.all(*pool.snapshot.map! {|c| c.close}).map(nil)
155
157
  else
156
158
  Ione::Future.resolved
157
159
  end
158
160
  end
159
161
 
160
- def query(statement, options, paging_state = nil)
161
- request = Protocol::QueryRequest.new(statement.cql, statement.params, nil, options.consistency, options.serial_consistency, options.page_size, paging_state, options.trace?)
162
+ def keyspace_created(keyspace)
163
+ end
164
+
165
+ def keyspace_changed(keyspace)
166
+ end
167
+
168
+ def keyspace_dropped(keyspace)
169
+ @keyspace = nil if @keyspace == keyspace.name
170
+ nil
171
+ end
172
+
173
+
174
+ def query(statement, options)
175
+ request = Protocol::QueryRequest.new(statement.cql, statement.params, nil, options.consistency, options.serial_consistency, options.page_size, options.paging_state, options.trace?)
162
176
  timeout = options.timeout
163
177
  promise = @futures.promise
164
178
 
@@ -184,10 +198,10 @@ module Cassandra
184
198
  promise.future
185
199
  end
186
200
 
187
- def execute(statement, options, paging_state = nil)
201
+ def execute(statement, options)
188
202
  timeout = options.timeout
189
203
  result_metadata = statement.result_metadata
190
- request = Protocol::ExecuteRequest.new(nil, statement.params_metadata, statement.params, result_metadata.nil?, options.consistency, options.serial_consistency, options.page_size, paging_state, options.trace?)
204
+ request = Protocol::ExecuteRequest.new(nil, statement.params_metadata, statement.params, result_metadata.nil?, options.consistency, options.serial_consistency, options.page_size, options.paging_state, options.trace?)
191
205
  promise = @futures.promise
192
206
 
193
207
  keyspace = @keyspace
@@ -331,19 +345,46 @@ module Cassandra
331
345
  return NO_CONNECTIONS
332
346
  end
333
347
 
334
- f = @connector.connect_many(host, pool_size)
348
+ pool = nil
349
+ existing_connections = 0
350
+
351
+ synchronize do
352
+ pool = @connections[host]
353
+ end
354
+
355
+ existing_connections = pool.size if pool
356
+ pool = nil
357
+ missing_connections = (pool_size - existing_connections)
358
+ return Ione::Future.resolved if missing_connections <= 0
359
+
360
+ f = @connector.connect_many(host, missing_connections)
335
361
 
336
362
  f.on_value do |connections|
337
- manager = nil
363
+ pool = nil
338
364
 
339
365
  synchronize do
340
366
  @connecting_hosts.delete(host)
341
367
  @prepared_statements[host] = {}
342
368
  @preparing_statements[host] = {}
343
- manager = @connections[host] ||= Cassandra::Client::ConnectionManager.new
369
+ pool = @connections[host] ||= ConnectionPool.new
344
370
  end
345
371
 
346
- manager.add_connections(connections)
372
+ pool.add_connections(connections)
373
+
374
+ connections.each do |connection|
375
+ connection.on_closed do
376
+ distance = nil
377
+
378
+ synchronize do
379
+ if !(@state == :closed || @state == :closing) && !@connecting_hosts.include?(host) && @connections.include?(host)
380
+ distance = @load_balancing_policy.distance(host)
381
+ @connecting_hosts[host] = distance unless distance == :ignore
382
+ end
383
+ end
384
+
385
+ connect_to_host_maybe_retry(host, distance).map(nil) if distance
386
+ end
387
+ end
347
388
  end
348
389
 
349
390
  f
@@ -356,16 +397,16 @@ module Cassandra
356
397
  end
357
398
 
358
399
  hosts << host = plan.next
359
- manager = nil
360
- synchronize { manager = @connections[host] }
400
+ pool = nil
401
+ synchronize { pool = @connections[host] }
361
402
 
362
- unless manager
403
+ unless pool
363
404
  errors ||= {}
364
405
  errors[host] = NOT_CONNECTED
365
406
  return execute_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
366
407
  end
367
408
 
368
- connection = manager.random_connection
409
+ connection = pool.random_connection
369
410
 
370
411
  if keyspace && connection.keyspace != keyspace
371
412
  switch = switch_keyspace(connection, keyspace, timeout)
@@ -430,16 +471,16 @@ module Cassandra
430
471
  end
431
472
 
432
473
  hosts << host = plan.next
433
- manager = nil
434
- synchronize { manager = @connections[host] }
474
+ pool = nil
475
+ synchronize { pool = @connections[host] }
435
476
 
436
- unless manager
477
+ unless pool
437
478
  errors ||= {}
438
479
  errors[host] = NOT_CONNECTED
439
480
  return batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors, hosts)
440
481
  end
441
482
 
442
- connection = manager.random_connection
483
+ connection = pool.random_connection
443
484
 
444
485
  if keyspace && connection.keyspace != keyspace
445
486
  switch = switch_keyspace(connection, keyspace, timeout)
@@ -529,16 +570,16 @@ module Cassandra
529
570
  end
530
571
 
531
572
  hosts << host = plan.next
532
- manager = nil
533
- synchronize { manager = @connections[host] }
573
+ pool = nil
574
+ synchronize { pool = @connections[host] }
534
575
 
535
- unless manager
576
+ unless pool
536
577
  errors ||= {}
537
578
  errors[host] = NOT_CONNECTED
538
579
  return send_request_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
539
580
  end
540
581
 
541
- connection = manager.random_connection
582
+ connection = pool.random_connection
542
583
 
543
584
  if keyspace && connection.keyspace != keyspace
544
585
  switch = switch_keyspace(connection, keyspace, timeout)
@@ -671,9 +712,7 @@ module Cassandra
671
712
  when Protocol::RowsResultResponse
672
713
  promise.fulfill(Results::Paged.new(r.rows, r.paging_state, r.trace_id, keyspace, statement, options, hosts, request.consistency, retries, self, @futures))
673
714
  when Protocol::SchemaChangeResultResponse
674
- if r.change == 'DROPPED' && r.keyspace == @keyspace && r.table.empty?
675
- @keyspace = nil
676
- end
715
+ @schema.delete_keyspace(r.keyspace) if r.change == 'DROPPED' && r.table.empty?
677
716
 
678
717
  @logger.debug('Waiting for schema to propagate to all hosts after a change')
679
718
  wait_for_schema_agreement(connection, @reconnection_policy.schedule).on_complete do |f|
@@ -17,14 +17,14 @@
17
17
  #++
18
18
 
19
19
  module Cassandra
20
- module Client
20
+ class Cluster
21
21
  # @private
22
- class ConnectionManager
22
+ class ConnectionPool
23
23
  include Enumerable
24
24
 
25
25
  def initialize
26
26
  @connections = []
27
- @lock = Mutex.new
27
+ @lock = ::Mutex.new
28
28
  end
29
29
 
30
30
  def add_connections(connections)
@@ -59,6 +59,12 @@ module Cassandra
59
59
  end
60
60
  end
61
61
 
62
+ def size
63
+ @lock.synchronize do
64
+ @connections.size
65
+ end
66
+ end
67
+
62
68
  def each_connection(&callback)
63
69
  return self unless block_given?
64
70
  raise Errors::IOError, 'Not connected' unless connected?
@@ -22,13 +22,14 @@ module Cassandra
22
22
  class Connector
23
23
  include MonitorMixin
24
24
 
25
- def initialize(logger, io_reactor, cluster_registry, connection_options)
26
- @logger = logger
27
- @reactor = io_reactor
28
- @registry = cluster_registry
29
- @options = connection_options
30
- @connections = ::Hash.new
31
- @open_connections = ::Hash.new
25
+ def initialize(logger, io_reactor, cluster_registry, connection_options, execution_options)
26
+ @logger = logger
27
+ @reactor = io_reactor
28
+ @registry = cluster_registry
29
+ @connection_options = connection_options
30
+ @execution_options = execution_options
31
+ @connections = ::Hash.new
32
+ @open_connections = ::Hash.new
32
33
 
33
34
  mon_initialize
34
35
  end
@@ -115,13 +116,33 @@ module Cassandra
115
116
  UNCLAIMED_TIMEOUT = 5 # close unclaimed connections in five seconds
116
117
 
117
118
  def do_connect(host)
118
- create_connector.connect(host.ip.to_s).fallback do |error|
119
+ f = @reactor.connect(host.ip.to_s, @connection_options.port, {:timeout => @connection_options.connect_timeout, :ssl => @connection_options.ssl}) do |connection|
120
+ raise Errors::ClientError, 'Not connected, reactor stopped' unless connection
121
+ Protocol::CqlProtocolHandler.new(connection, @reactor, @connection_options.protocol_version, @connection_options.compressor, @connection_options.heartbeat_interval, @connection_options.idle_timeout)
122
+ end
123
+ f = f.flat_map do |connection|
124
+ request_options(connection).flat_map do |options|
125
+ compression = @connection_options.compression
126
+ supported_algorithms = options['COMPRESSION']
127
+
128
+ if compression && !supported_algorithms.include?(compression)
129
+ @logger.warn("Compression with #{compression.inspect} is not supported by host at #{host.ip}, supported algorithms are #{supported_algorithms.inspect}")
130
+ compression = nil
131
+ end
132
+
133
+ supported_cql_versions = options['CQL_VERSION']
134
+ cql_version = (supported_cql_versions && !supported_cql_versions.empty?) ? supported_cql_versions.first : '3.1.0'
135
+
136
+ startup_connection(connection, cql_version, compression)
137
+ end
138
+ end
139
+ f.fallback do |error|
119
140
  case error
120
141
  when Errors::ProtocolError
121
142
  synchronize do
122
- if @options.protocol_version > 1
123
- @logger.info("Host #{host.ip} doesn't support protocol version #{@options.protocol_version}, downgrading")
124
- @options.protocol_version -= 1
143
+ if @connection_options.protocol_version > 1
144
+ @logger.info("Host #{host.ip} doesn't support protocol version #{@connection_options.protocol_version}, downgrading")
145
+ @connection_options.protocol_version -= 1
125
146
  do_connect(host)
126
147
  else
127
148
  Ione::Future.failed(error)
@@ -137,32 +158,82 @@ module Cassandra
137
158
  end
138
159
  end
139
160
 
140
- def create_connector
141
- authentication_step = @options.protocol_version == 1 ? Cassandra::Client::CredentialsAuthenticationStep.new(@options.credentials) : Cassandra::Client::SaslAuthenticationStep.new(@options.auth_provider)
142
- protocol_handler_factory = lambda do |connection|
143
- raise Errors::ClientError, 'Not connected, reactor stopped' unless connection
144
- Protocol::CqlProtocolHandler.new(connection, @reactor, @options.protocol_version, @options.compressor, @options.heartbeat_interval, @options.idle_timeout)
161
+ def startup_connection(connection, cql_version, compression)
162
+ connection.send_request(Protocol::StartupRequest.new(cql_version, compression), @execution_options.timeout).flat_map do |r|
163
+ case r
164
+ when Protocol::AuthenticateResponse
165
+ if @connection_options.protocol_version == 1
166
+ credentials = @connection_options.credentials
167
+ if credentials
168
+ send_credentials(connection, credentials)
169
+ else
170
+ Ione::Future.failed(Errors::AuthenticationError.new('Server requested authentication, but client was not configured to authenticate'))
171
+ end
172
+ else
173
+ authenticator = @connection_options.create_authenticator(r.authentication_class)
174
+ if authenticator
175
+ challenge_response_cycle(connection, authenticator, authenticator.initial_response)
176
+ else
177
+ Ione::Future.failed(Errors::AuthenticationError.new('Server requested authentication, but client was not configured to authenticate'))
178
+ end
179
+ end
180
+ when Protocol::ReadyResponse
181
+ ::Ione::Future.resolved(connection)
182
+ when Protocol::ErrorResponse
183
+ ::Ione::Future.failed(r.to_error(VOID_STATEMENT))
184
+ else
185
+ ::Ione::Future.failed(Errors::InternalError.new("Unexpected response #{r.inspect}"))
186
+ end
187
+ end
188
+ end
189
+
190
+ def request_options(connection)
191
+ connection.send_request(Protocol::OptionsRequest.new, @execution_options.timeout).map do |r|
192
+ case r
193
+ when Protocol::SupportedResponse
194
+ r.options
195
+ when Protocol::ErrorResponse
196
+ raise r.to_error(VOID_STATEMENT)
197
+ else
198
+ raise Errors::InternalError, "Unexpected response #{r.inspect}"
199
+ end
145
200
  end
201
+ end
146
202
 
147
- Cassandra::Client::Connector.new([
148
- Cassandra::Client::ConnectStep.new(
149
- @reactor,
150
- protocol_handler_factory,
151
- @options.port,
152
- {:timeout => @options.connect_timeout, :ssl => @options.ssl},
153
- @logger
154
- ),
155
- Cassandra::Client::CacheOptionsStep.new(@options.connect_timeout),
156
- Cassandra::Client::InitializeStep.new(@options.compressor, @logger),
157
- authentication_step,
158
- Cassandra::Client::CachePropertiesStep.new,
159
- ])
203
+ def send_credentials(connection, credentials)
204
+ connection.send_request(Protocol::CredentialsRequest.new(credentials), @execution_options.timeout).map do |r|
205
+ case r
206
+ when Protocol::ReadyResponse
207
+ connection
208
+ when Protocol::ErrorResponse
209
+ raise r.to_error(VOID_STATEMENT)
210
+ else
211
+ raise Errors::InternalError, "Unexpected response #{r.inspect}"
212
+ end
213
+ end
214
+ end
215
+
216
+ def challenge_response_cycle(connection, authenticator, token)
217
+ connection.send_request(Protocol::AuthResponseRequest.new(token), @execution_options.timeout).flat_map do |r|
218
+ case r
219
+ when Protocol::AuthChallengeResponse
220
+ token = authenticator.challenge_response(r.token)
221
+ challenge_response_cycle(pending_connection, authenticator, token)
222
+ when Protocol::AuthSuccessResponse
223
+ authenticator.authentication_successful(r.token) rescue nil
224
+ ::Ione::Future.resolved(connection)
225
+ when Protocol::ErrorResponse
226
+ ::Ione::Future.failed(r.to_error(VOID_STATEMENT))
227
+ else
228
+ ::Ione::Future.failed(Errors::InternalError.new("Unexpected response #{r.inspect}"))
229
+ end
230
+ end
160
231
  end
161
232
 
162
233
  def create_additional_connections(host, count, established_connections, error = nil)
163
234
  futures = count.times.map do
164
235
  connect(host).recover do |e|
165
- Cassandra::Client::FailedConnection.new(e, host)
236
+ FailedConnection.new(e, host)
166
237
  end
167
238
  end
168
239