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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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