dse-driver 1.0.1-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +13 -0
- data/README.md +72 -0
- data/lib/challenge_evaluator.jar +0 -0
- data/lib/dse.rb +104 -0
- data/lib/dse/auth/providers/gss_api.rb +160 -0
- data/lib/dse/auth/providers/password.rb +56 -0
- data/lib/dse/cluster.rb +99 -0
- data/lib/dse/geometry/line_string.rb +181 -0
- data/lib/dse/geometry/point.rb +179 -0
- data/lib/dse/geometry/polygon.rb +196 -0
- data/lib/dse/graph.rb +18 -0
- data/lib/dse/graph/duration.rb +131 -0
- data/lib/dse/graph/edge.rb +74 -0
- data/lib/dse/graph/options.rb +194 -0
- data/lib/dse/graph/path.rb +54 -0
- data/lib/dse/graph/result.rb +85 -0
- data/lib/dse/graph/result_set.rb +77 -0
- data/lib/dse/graph/statement.rb +118 -0
- data/lib/dse/graph/vertex.rb +107 -0
- data/lib/dse/graph/vertex_property.rb +66 -0
- data/lib/dse/load_balancing/policies/host_targeting.rb +102 -0
- data/lib/dse/session.rb +106 -0
- data/lib/dse/statements.rb +15 -0
- data/lib/dse/statements/host_targeting.rb +50 -0
- data/lib/dse/util.rb +12 -0
- data/lib/dse/util/endian_buffer.rb +37 -0
- data/lib/dse/version.rb +12 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 43d6f472d065e4e4d980d6402fe26da4ab2f8259
|
4
|
+
data.tar.gz: 182fd750d7dc29158fe46a1e1d7063c2a41622bc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 986c12a9a51f42ee91253bf7fe25120e04b8877fd92f4e52332892f819d21a5e9aef639b208f8cb7d53f35db3cff822c14c1291d1f3917f95a4f46dcaccda270
|
7
|
+
data.tar.gz: 4515f1d9fd062288aea8de3f755467e1c749e1a5e2284862293703c290c9246f2b897e64208971176f4cd2d51c43593e2bec330df1365ae561a0e49879d772be
|
data/.yardopts
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
--no-private
|
2
|
+
--markup markdown
|
3
|
+
--type-tag expected_errors:"Expected Errors"
|
4
|
+
--tag jira_ticket:"JIRA Ticket"
|
5
|
+
--type-tag expected_result:"Expected Result"
|
6
|
+
--tag test_assumptions:"Test Assumptions"
|
7
|
+
--tag test_category:"Test Category"
|
8
|
+
|
9
|
+
lib/**/*.rb
|
10
|
+
integration/**/*.rb
|
11
|
+
-- README
|
12
|
+
|
13
|
+
load_plugins: true
|
data/README.md
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# DataStax Enterprise Ruby Driver
|
2
|
+
|
3
|
+
*NOTE: The DataStax Enterprise Ruby Driver can be used solely with DataStax Enterprise. Please consult [the license](http://www.datastax.com/terms/datastax-dse-driver-license-terms).*
|
4
|
+
|
5
|
+
This driver is built on top of the [DataStax Ruby driver for Apache Cassandra](http://docs.datastax.com/en/latest-ruby-driver/ruby-driver/whatsNew.html)
|
6
|
+
and enhanced for the adaptive data management and mixed workload capabilities
|
7
|
+
provided by DSE. Therefore a lot of the underlying concepts are the same.
|
8
|
+
|
9
|
+
## Documentation
|
10
|
+
Driver documentation can be found [here](http://docs.datastax.com/en/latest-dse-ruby-driver/ruby-driver/whatsNew.html).
|
11
|
+
|
12
|
+
In particular, you'll find our [Features](http://docs.datastax.com/en/latest-dse-ruby-driver/supplemental/features) and
|
13
|
+
[API](http://docs.datastax.com/en/latest-dse-ruby-driver/supplemental/api) sections very enlightening.
|
14
|
+
|
15
|
+
## Feedback Requested
|
16
|
+
*Help us focus our efforts!* [Provide your input](http://goo.gl/forms/pCs8PTpHLf) on the Ruby Driver
|
17
|
+
Platform and Runtime Survey (we kept it short).
|
18
|
+
|
19
|
+
If you find an issue, please file an issue in our [public JIRA](https://datastax-oss.atlassian.net/browse/RUBY).
|
20
|
+
*Please be sure to specify the affects-version (DSE-1.X.Y).*
|
21
|
+
|
22
|
+
You can also post questions in [our forum](https://groups.google.com/a/lists.datastax.com/forum/#!forum/ruby-driver-user).
|
23
|
+
|
24
|
+
## Features
|
25
|
+
|
26
|
+
This driver exposes the following features of DSE 5.0:
|
27
|
+
|
28
|
+
* <a href="features/graph#graph">Graph</a>
|
29
|
+
* <a href="features/authentication#authentication">Authentication</a> with nodes running DSE
|
30
|
+
* <a href="features/geospatial#geospatial-types">Geospatial types</a>
|
31
|
+
|
32
|
+
Note that this driver is fully compatible with previous versions of DataStax Enterprise.
|
33
|
+
|
34
|
+
## Installation
|
35
|
+
The driver is named dse-driver on rubygems.org and can easily be installed with Bundler or the gem program. It will
|
36
|
+
download the appropriate Cassandra driver as well.
|
37
|
+
|
38
|
+
## Upgrade
|
39
|
+
The driver is intended to have the same look and feel as the core driver to make upgrading from the core driver
|
40
|
+
trivial. The only change is to replace references to the <code>Cassandra</code> module with <code>Dse</code> when
|
41
|
+
creating the cluster object:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
require 'dse'
|
45
|
+
|
46
|
+
# This returns a Dse::Cluster instance
|
47
|
+
cluster = Dse.cluster
|
48
|
+
|
49
|
+
# This returns a Dse::Session instance
|
50
|
+
session = cluster.connect
|
51
|
+
rs = session.execute('select * from system.local')
|
52
|
+
```
|
53
|
+
|
54
|
+
## Determining driver versions
|
55
|
+
Within a script or irb, you can determine the exact versions of the dse and core drivers by accessing the VERSION
|
56
|
+
constant of the appropriate module:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
require 'dse'
|
60
|
+
|
61
|
+
puts "Dse Driver Version: #{Dse::VERSION}"
|
62
|
+
puts "Cassandra Driver Version: #{Cassandra::VERSION}"
|
63
|
+
```
|
64
|
+
|
65
|
+
## Compatibility
|
66
|
+
Although this driver exposes new features introduced in DSE 5.0, it is fully compatible and supported for use with
|
67
|
+
previous versions of DSE.
|
68
|
+
|
69
|
+
## License
|
70
|
+
Copyright (C) 2016 DataStax Inc.
|
71
|
+
|
72
|
+
The full license terms are available at http://www.datastax.com/terms/datastax-dse-driver-license-terms
|
Binary file
|
data/lib/dse.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2016 DataStax Inc.
|
5
|
+
#
|
6
|
+
# This software can be used solely with DataStax Enterprise. Please consult the license at
|
7
|
+
# http://www.datastax.com/terms/datastax-dse-driver-license-terms
|
8
|
+
#++
|
9
|
+
|
10
|
+
require 'json'
|
11
|
+
|
12
|
+
if RUBY_ENGINE == 'jruby'
|
13
|
+
require 'challenge_evaluator'
|
14
|
+
else
|
15
|
+
require 'gss_api_context'
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'cassandra'
|
19
|
+
|
20
|
+
module Dse
|
21
|
+
# Creates a {Dse::Cluster Cluster instance}, which extends {http://dsdocs30/api/cassandra/cluster Cassandra::Cluster}.
|
22
|
+
# The API is identical, except that it returns a {Dse::Session Dse::Session} (see below). It takes all of the same
|
23
|
+
# options as Cassandra.cluster and the following extra options.
|
24
|
+
#
|
25
|
+
# @option options [Dse::Graph::Options] :graph_options options for the DSE graph statement handler. Takes
|
26
|
+
# priority over other `:graph_*` options specified below.
|
27
|
+
# @option options [String] :graph_name name of graph to use in graph statements
|
28
|
+
# @option options [String] :graph_source graph traversal source
|
29
|
+
# @option options [String] :graph_language language used in graph queries
|
30
|
+
# @option options [Cassandra::CONSISTENCIES] :graph_read_consistency read consistency level for graph statements.
|
31
|
+
# Overrides the standard statement consistency level
|
32
|
+
# @option options [Cassandra::CONSISTENCIES] :graph_write_consistency write consistency level for graph statements.
|
33
|
+
# Overrides the standard statement consistency level
|
34
|
+
#
|
35
|
+
# @example Connecting to localhost
|
36
|
+
# cluster = Dse.cluster
|
37
|
+
#
|
38
|
+
# @example Configuring {Dse::Cluster}
|
39
|
+
# cluster = Dse.cluster(
|
40
|
+
# username: username,
|
41
|
+
# password: password,
|
42
|
+
# hosts: ['10.0.1.1', '10.0.1.2', '10.0.1.3']
|
43
|
+
# )
|
44
|
+
#
|
45
|
+
# @return [Dse::Cluster] a cluster instance
|
46
|
+
def self.cluster(options = {})
|
47
|
+
cluster_async(options).get
|
48
|
+
end
|
49
|
+
|
50
|
+
# Creates a {Dse::Cluster Cluster instance}.
|
51
|
+
#
|
52
|
+
# @see Dse.cluster
|
53
|
+
#
|
54
|
+
# @return [Cassandra::Future<Dse::Cluster>] a future resolving to the
|
55
|
+
# cluster instance.
|
56
|
+
def self.cluster_async(options = {})
|
57
|
+
graph_options = if !options[:graph_options].nil?
|
58
|
+
Cassandra::Util.assert_instance_of(Dse::Graph::Options, options[:graph_options])
|
59
|
+
options[:graph_options]
|
60
|
+
else
|
61
|
+
Dse::Graph::Options.new(options)
|
62
|
+
end
|
63
|
+
username = options[:username]
|
64
|
+
password = options[:password]
|
65
|
+
options[:custom_types] ||= []
|
66
|
+
options[:custom_types] << Dse::Geometry::Point << Dse::Geometry::LineString << Dse::Geometry::Polygon
|
67
|
+
options, hosts = Cassandra.validate_and_massage_options(options)
|
68
|
+
|
69
|
+
# Use the DSE plain text authenticator if we have a username and password. The above validation already
|
70
|
+
# raises an error if one is given without the other.
|
71
|
+
options[:auth_provider] = Auth::Providers::Password.new(username, password) if username && password
|
72
|
+
rescue => e
|
73
|
+
futures = options.fetch(:futures_factory) { return Cassandra::Future::Error.new(e) }
|
74
|
+
futures.error(e)
|
75
|
+
else
|
76
|
+
options[:cluster_klass] = Dse::Cluster
|
77
|
+
driver = ::Cassandra::Driver.new(options)
|
78
|
+
|
79
|
+
# Wrap the load-balancing policy that we'd otherwise run with, with a host-targeting policy.
|
80
|
+
# We do this before driver.connect because driver.connect saves off the policy in the cluster
|
81
|
+
# registry and does a few other things.
|
82
|
+
|
83
|
+
lbp = driver.load_balancing_policy
|
84
|
+
driver.load_balancing_policy = Dse::LoadBalancing::Policies::HostTargeting.new(lbp)
|
85
|
+
future = driver.connect(hosts)
|
86
|
+
future.then do |cluster|
|
87
|
+
cluster.graph_options.merge!(graph_options)
|
88
|
+
cluster
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
require 'dse/cluster'
|
94
|
+
require 'dse/util/endian_buffer'
|
95
|
+
require 'dse/geometry/line_string'
|
96
|
+
require 'dse/geometry/point'
|
97
|
+
require 'dse/geometry/polygon'
|
98
|
+
require 'dse/session'
|
99
|
+
require 'dse/version'
|
100
|
+
require 'dse/graph'
|
101
|
+
require 'dse/load_balancing/policies/host_targeting'
|
102
|
+
require 'dse/statements'
|
103
|
+
require 'dse/auth/providers/gss_api'
|
104
|
+
require 'dse/auth/providers/password'
|
@@ -0,0 +1,160 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2016 DataStax Inc.
|
5
|
+
#
|
6
|
+
# This software can be used solely with DataStax Enterprise. Please consult the license at
|
7
|
+
# http://www.datastax.com/terms/datastax-dse-driver-license-terms
|
8
|
+
#++
|
9
|
+
|
10
|
+
module Dse
|
11
|
+
module Auth
|
12
|
+
module Providers
|
13
|
+
# Auth provider to authenticate with Kerberos. Whenever the client connects to a DSE node,
|
14
|
+
# this provider will perform Kerberos authentication operations with it. By default, the provider
|
15
|
+
# takes the ip address of the node and uses `Socket#getnameinfo` to find its name in order to construct
|
16
|
+
# the full service address (e.g. service@host).
|
17
|
+
#
|
18
|
+
# @see #initialize
|
19
|
+
class GssApi < Cassandra::Auth::Provider
|
20
|
+
# @private
|
21
|
+
class NameInfoResolver
|
22
|
+
def resolve(host)
|
23
|
+
Socket.getnameinfo(['AF_INET', 0, host])[0]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# @private
|
28
|
+
class NoOpResolver
|
29
|
+
def resolve(host)
|
30
|
+
host
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# @private
|
35
|
+
class Authenticator
|
36
|
+
# Copied from kerberosgss.h
|
37
|
+
AUTH_GSS_COMPLETE = 1
|
38
|
+
|
39
|
+
def initialize(authentication_class, host, service, principal, ticket_cache)
|
40
|
+
@authentication_class = authentication_class
|
41
|
+
@host = host
|
42
|
+
@service = service
|
43
|
+
@principal = principal
|
44
|
+
@ticket_cache = ticket_cache
|
45
|
+
|
46
|
+
if RUBY_ENGINE == 'jruby'
|
47
|
+
@sasl_client = javax.security.sasl.Sasl.createSaslClient(['GSSAPI'],
|
48
|
+
nil,
|
49
|
+
service,
|
50
|
+
host,
|
51
|
+
{javax.security.sasl.Sasl::SERVER_AUTH => 'true',
|
52
|
+
javax.security.sasl.Sasl::QOP => 'auth'},
|
53
|
+
nil)
|
54
|
+
config = Dse::Auth::Providers::ChallengeEvaluator.make_configuration(principal, ticket_cache)
|
55
|
+
login = javax.security.auth.login.LoginContext.new('DseClient', nil, nil, config)
|
56
|
+
login.login
|
57
|
+
@subject = login.getSubject
|
58
|
+
else
|
59
|
+
@gss_context = GssApiContext.new("#{@service}@#{@host}", @principal, @ticket_cache)
|
60
|
+
end
|
61
|
+
rescue => e
|
62
|
+
raise Cassandra::Errors::AuthenticationError.new(
|
63
|
+
"Failed to authenticate: #{e.message}",
|
64
|
+
nil,
|
65
|
+
nil,
|
66
|
+
nil,
|
67
|
+
nil,
|
68
|
+
nil,
|
69
|
+
nil,
|
70
|
+
:one,
|
71
|
+
0
|
72
|
+
)
|
73
|
+
end
|
74
|
+
|
75
|
+
def initial_response
|
76
|
+
@authentication_class == 'com.datastax.bdp.cassandra.auth.DseAuthenticator' ?
|
77
|
+
'GSSAPI' :
|
78
|
+
challenge_response('GSSAPI-START')
|
79
|
+
end
|
80
|
+
|
81
|
+
if RUBY_ENGINE == 'jruby'
|
82
|
+
def challenge_response(token)
|
83
|
+
if token == 'GSSAPI-START'
|
84
|
+
return '' unless @sasl_client.hasInitialResponse
|
85
|
+
token = ''
|
86
|
+
end
|
87
|
+
|
88
|
+
Dse::Auth::Providers::ChallengeEvaluator.evaluate(@sasl_client, @subject, token)
|
89
|
+
end
|
90
|
+
else
|
91
|
+
def challenge_response(token)
|
92
|
+
if token == 'GSSAPI-START'
|
93
|
+
response = @gss_context.step('')[1]
|
94
|
+
elsif !@is_gss_complete
|
95
|
+
# Process the challenge as a next step in authentication until we have gotten
|
96
|
+
# AUTH_GSS_COMPLETE.
|
97
|
+
rc, response = @gss_context.step(token)
|
98
|
+
@is_gss_complete = true if rc == AUTH_GSS_COMPLETE
|
99
|
+
response ||= ''
|
100
|
+
else
|
101
|
+
# Ok, we went through all initial phases of auth and now the server is giving us a message
|
102
|
+
# to decode.
|
103
|
+
data = @gss_context.unwrap(token)
|
104
|
+
|
105
|
+
raise 'Bad response from server' if data.length != 4
|
106
|
+
parsed = data.unpack('>L').first
|
107
|
+
max_length = [parsed & 0xffffff, 65536].min
|
108
|
+
|
109
|
+
# Set up a response like this:
|
110
|
+
# byte 0: the selected qop. 1==auth
|
111
|
+
# byte 1-3: the max length for any buffer sent back and forth on this connection. (big endian)
|
112
|
+
# the rest of the buffer: the authorization user name in UTF-8 - not null terminated.
|
113
|
+
|
114
|
+
user_name = @gss_context.user_name
|
115
|
+
out = [max_length | 1 << 24].pack('>L') + user_name
|
116
|
+
response = @gss_context.wrap(out)
|
117
|
+
end
|
118
|
+
response
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def authentication_successful(token)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
# @param service [String] name of the kerberos service; defaults to 'dse'.
|
127
|
+
# @param host_resolver [Boolean, Object] whether to use a host-resolver. By default,
|
128
|
+
# `Socket#getnameinfo` is used. To disable host-resolution, specify a `false` value. You may also
|
129
|
+
# provide a custom resolver, which is an object that implements the `resolve(host_ip)` method.
|
130
|
+
# @param principal [String] The principal whose cached credentials are used to authenticate. Defaults
|
131
|
+
# to the first principal stored in the ticket cache.
|
132
|
+
# @param ticket_cache [String] The ticket cache containing the cached credential we seek. Defaults
|
133
|
+
# *on Linux* to /tmp/krb5cc_<uid> (where uid is the numeric uid of the user running the
|
134
|
+
# client program). In MRI only, the `KRB5CCNAME` environment variable supercedes this. On Mac,
|
135
|
+
# the default is a symbolic reference to a ticket-cache server process.
|
136
|
+
def initialize(service = 'dse', host_resolver = true, principal = nil, ticket_cache = nil)
|
137
|
+
@service = service
|
138
|
+
@host_resolver = case host_resolver
|
139
|
+
when false
|
140
|
+
NoOpResolver.new
|
141
|
+
when true
|
142
|
+
NameInfoResolver.new
|
143
|
+
else
|
144
|
+
host_resolver
|
145
|
+
end
|
146
|
+
Cassandra::Util.assert_responds_to(:resolve, @host_resolver,
|
147
|
+
'invalid host_resolver: it must have the :resolve method')
|
148
|
+
@principal = principal
|
149
|
+
@ticket_cache = ticket_cache
|
150
|
+
end
|
151
|
+
|
152
|
+
# @private
|
153
|
+
def create_authenticator(authentication_class, host)
|
154
|
+
Authenticator.new(authentication_class, @host_resolver.resolve(host.ip.to_s),
|
155
|
+
@service, @principal, @ticket_cache)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2016 DataStax Inc.
|
5
|
+
#
|
6
|
+
# This software can be used solely with DataStax Enterprise. Please consult the license at
|
7
|
+
# http://www.datastax.com/terms/datastax-dse-driver-license-terms
|
8
|
+
#++
|
9
|
+
|
10
|
+
module Dse
|
11
|
+
module Auth
|
12
|
+
module Providers
|
13
|
+
# Auth provider to authenticate with username/password for DSE's built-in authentication as well as LDAP.
|
14
|
+
#
|
15
|
+
# @note No need to instantiate this class manually, use `:username` and
|
16
|
+
# `:password` options when calling {Dse.cluster} and one will be
|
17
|
+
# created automatically for you.
|
18
|
+
|
19
|
+
class Password < Cassandra::Auth::Provider
|
20
|
+
# @private
|
21
|
+
class Authenticator
|
22
|
+
def initialize(authentication_class, username, password)
|
23
|
+
@authentication_class = authentication_class
|
24
|
+
@username = username
|
25
|
+
@password = password
|
26
|
+
end
|
27
|
+
|
28
|
+
def initial_response
|
29
|
+
@authentication_class == 'com.datastax.bdp.cassandra.auth.DseAuthenticator' ?
|
30
|
+
'PLAIN' :
|
31
|
+
challenge_response('PLAIN-START')
|
32
|
+
end
|
33
|
+
|
34
|
+
def challenge_response(token)
|
35
|
+
"\x00#{@username}\x00#{@password}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def authentication_successful(token)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# @param username [String] username to use for authentication to Cassandra
|
43
|
+
# @param password [String] password to use for authentication to Cassandra
|
44
|
+
def initialize(username, password)
|
45
|
+
@username = username
|
46
|
+
@password = password
|
47
|
+
end
|
48
|
+
|
49
|
+
# @private
|
50
|
+
def create_authenticator(authentication_class, host)
|
51
|
+
Authenticator.new(authentication_class, @username, @password)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/dse/cluster.rb
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright (C) 2016 DataStax Inc.
|
5
|
+
#
|
6
|
+
# This software can be used solely with DataStax Enterprise. Please consult the license at
|
7
|
+
# http://www.datastax.com/terms/datastax-dse-driver-license-terms
|
8
|
+
#++
|
9
|
+
|
10
|
+
module Dse
|
11
|
+
# Cluster represents a DSE cluster. It serves as a {Dse::Session session factory} and a collection of metadata.
|
12
|
+
# It wraps a {http://dsdocs30/api/cassandra/cluster Cassandra::Cluster} and exposes all of its functionality.
|
13
|
+
class Cluster
|
14
|
+
# @return [Dse::Graph::Options] default graph options used by queries on this cluster.
|
15
|
+
attr_reader :graph_options
|
16
|
+
|
17
|
+
# @private
|
18
|
+
def initialize(logger,
|
19
|
+
io_reactor,
|
20
|
+
executor,
|
21
|
+
control_connection,
|
22
|
+
cluster_registry,
|
23
|
+
cluster_schema,
|
24
|
+
cluster_metadata,
|
25
|
+
execution_options,
|
26
|
+
connection_options,
|
27
|
+
load_balancing_policy,
|
28
|
+
reconnection_policy,
|
29
|
+
retry_policy,
|
30
|
+
address_resolution_policy,
|
31
|
+
connector,
|
32
|
+
futures_factory,
|
33
|
+
timestamp_generator)
|
34
|
+
@delegate_cluster = Cassandra::Cluster.new(logger,
|
35
|
+
io_reactor,
|
36
|
+
executor,
|
37
|
+
control_connection,
|
38
|
+
cluster_registry,
|
39
|
+
cluster_schema,
|
40
|
+
cluster_metadata,
|
41
|
+
execution_options,
|
42
|
+
connection_options,
|
43
|
+
load_balancing_policy,
|
44
|
+
reconnection_policy,
|
45
|
+
retry_policy,
|
46
|
+
address_resolution_policy,
|
47
|
+
connector,
|
48
|
+
futures_factory,
|
49
|
+
timestamp_generator)
|
50
|
+
@graph_options = Dse::Graph::Options.new
|
51
|
+
|
52
|
+
# We need the futures factory ourselves for async error reporting and potentially for our
|
53
|
+
# own async processing independent of the C* driver.
|
54
|
+
@futures = futures_factory
|
55
|
+
end
|
56
|
+
|
57
|
+
# Delegates to {http://docs.datastax.com/en/developer/ruby-driver/3.0/supplemental/api/cassandra/cluster/?local=true&nav=toc#connect_async-instance_method
|
58
|
+
# Cassandra::Cluster#connect_async}
|
59
|
+
# to connect asynchronously to a cluster, but returns a future that will resolve to a DSE session rather than
|
60
|
+
# Cassandra session.
|
61
|
+
#
|
62
|
+
# @param keyspace [String] optional keyspace to scope session to
|
63
|
+
#
|
64
|
+
# @return [Cassandra::Future<Dse::Session>]
|
65
|
+
def connect_async(keyspace = nil)
|
66
|
+
future = @delegate_cluster.connect_async(keyspace)
|
67
|
+
# We want to actually return a DSE session upon successful connection.
|
68
|
+
future.then do |cassandra_session|
|
69
|
+
Dse::Session.new(cassandra_session, @graph_options, @futures)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Synchronous variant of {#connect_async}.
|
74
|
+
#
|
75
|
+
# @param keyspace [String] optional keyspace to scope the session to
|
76
|
+
#
|
77
|
+
# @return [Dse::Session]
|
78
|
+
def connect(keyspace = nil)
|
79
|
+
connect_async(keyspace).get
|
80
|
+
end
|
81
|
+
|
82
|
+
#### The following methods handle arbitrary delegation to the underlying cluster object. ####
|
83
|
+
protected
|
84
|
+
|
85
|
+
# @private
|
86
|
+
def method_missing(method_name, *args, &block)
|
87
|
+
# If we get here, we don't have a method of our own. Forward the request to the delegate_cluster.
|
88
|
+
# If it returns itself, we will coerce the result to return our *self* instead.
|
89
|
+
|
90
|
+
result = @delegate_cluster.send(method_name, *args, &block)
|
91
|
+
(result == @delegate_cluster) ? self : result
|
92
|
+
end
|
93
|
+
|
94
|
+
# @private
|
95
|
+
def respond_to?(method, include_private = false)
|
96
|
+
super || @delegate_cluster.respond_to?(method, include_private)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|