Module: DatastaxRails::Connection::ClassMethods

Defined in:
lib/datastax_rails/connection.rb

Overview

rubocop:disable Style/Documentation

Constant Summary collapse

DEFAULT_OPTIONS =
{
  servers:             ['127.0.0.1'],
  port:                9160,
  connection_options:  { timeout: 10 },
  ssl:                 false,
  server_max_requests: 500
}

Instance Method Summary collapse

Instance Method Details

#establish_connection(spec) ⇒ Object

Establish a Cassandra connection to DSE. datastax.yml will be read and the current environment's settings passed to this method.

The following is an example production configuration document. Assume that your setup consists of three datacenters each with three servers and RF=3 (i.e., you're storing your data 9 times)

servers: ["10.1.2.5"]
port: 9042
ssl:
  cert: config/datastax_rails.crt
  key: config/datastax_rails.key
  ca_cert: config/ca.crt
  keypass: changeme
keyspace: "datastax_rails_production"
strategy_class: "org.apache.cassandra.locator.NetworkTopologyStrategy"
strategy_options: {"DS1": "3", "DS2": "3", "DS3": "3"}
connection_options:
  timeout: 10
solr:
  port: 8983
  path: /solr

The servers entry should be a list of all seed nodes for servers you wish to connect to. DSR will automatically connect to all nodes in the cluster or in the datacenter if you are using multiple datacenters. You can safely just list all nodes in a particular datacenter if you would like.

The port to connect to, this port will be used for all nodes. Because the `system.peers` table does not contain the port that the nodes are listening on, the port must be the same for all nodes.

Since we're using the NetworkTopologyStrategy for our locator, it is important that you configure cassandra-topology.properties. See the DSE documentation at www.datastax.com for more information.

strategy_options lets us specify what our topology looks like. In this case, we have RF=3 in all three of our datacenters (DS1, DS2, and DS3).

connection_options are the options that are passed to the thrift layer for the connection to cassandra.

  • retries - Number of times a request will be retried. Should likely be the number of servers - 1. Defaults to 0.

  • server_retry_period - Amount of time to wait before retrying a down server. Defaults to 1.

  • server_max_requests - Number of requests to make to a server before moving to the next one (helps keep load balanced). Default to 500.

  • retry_overrides - Overrides retries option for individual exceptions.

  • connect_timeout - The connection timeout on the Thrift socket. Defaults to 0.1.

  • timeout - The timeout for the transport layer. Defaults to 1.

See solr_connection for a description of the solr options in datastax.yml


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/datastax_rails/connection.rb', line 77

def establish_connection(spec)
  DatastaxRails::Base.config = spec.with_indifferent_access
  spec.reverse_merge!(DEFAULT_OPTIONS)
  load_balancing_policy =
    DatastaxRails::LoadBalancing::Policies::StickyDcAwareRoundRobin.new(spec[:server_max_requests])
  cluster_options = { hosts:                 spec[:servers],
                      connection_timeout:    spec[:connection_options][:timeout],
                      timeout:               spec[:connection_options][:timeout],
                      load_balancing_policy: load_balancing_policy }
  if ssl_type
    ca_cert = Pathname.new(DatastaxRails::Base.config[:ssl][:ca_cert])
    ca_cert = Rails.root.join(ca_cert) unless ca_cert.absolute?
    ssl_context = OpenSSL::SSL::SSLContext.new
    ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
    ssl_context.ca_file = ca_cert.to_s
    if ssl_type == :two_way_ssl
      cert = Pathname.new(DatastaxRails::Base.config[:ssl][:cert])
      key = Pathname.new(DatastaxRails::Base.config[:ssl][:key])
      pass = DatastaxRails::Base.config[:ssl][:keypass]
      cert = Rails.root.join(cert) unless cert.absolute?
      key = Rails.root.join(key) unless key.absolute?
      if pass
        ssl_context.key = OpenSSL::PKey::RSA.new(key.read, pass)
      else
        ssl_context.key = OpenSSL::PKey::RSA.new(key.read)
      end
      ssl_context.cert = OpenSSL::X509::Certificate.new(cert.read)
    end
    cluster_options[:ssl] = ssl_context
  end

  self.current_server = spec[:servers].first

  self.cluster = Cassandra.cluster(cluster_options)
  self.connection = cluster.connect(spec[:keyspace])
end

#establish_solr_connectionRSolr::Client

Similar to establish_connection, this method creates a connection object for Solr. Since HTTP is stateless, this doesn't actually launch the connection, but it gets everything set up so that RSolr can do its work. It's important to note that unlike the cassandra connection which is global to all of DSR, each model will have its own solr_connection.


161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/datastax_rails/connection.rb', line 161

def establish_solr_connection
  opts = { url: "#{solr_base_url}/#{DatastaxRails::Base.connection.keyspace}.#{column_family}" }
  if ssl_type == :two_way_ssl
    ca_cert = Pathname.new(DatastaxRails::Base.config[:ssl][:ca_cert])
    cert = Pathname.new(DatastaxRails::Base.config[:ssl][:cert])
    key = Pathname.new(DatastaxRails::Base.config[:ssl][:key])
    pass = DatastaxRails::Base.config[:ssl][:keypass]
    ca_cert = Rails.root.join(ca_cert) unless ca_cert.absolute?
    cert = Rails.root.join(cert) unless cert.absolute?
    key = Rails.root.join(key) unless key.absolute?
    opts[:ssl_cert_file] = cert.to_s
    opts[:ssl_key_file] = key.to_s
    opts[:ssl_key_pass] = pass if pass
    opts[:ssl_ca_file] = ca_cert.to_s

    RSolr::ClientCert.connect opts
  else
    RSolr.connect opts
  end
end

#reconnectObject

rubocop:disable Style/RescueModifier


127
128
129
130
131
# File 'lib/datastax_rails/connection.rb', line 127

def reconnect
  connection.close rescue true
  self.connection = nil
  establish_connection(DatastaxRails::Base.config)
end

#solr_base_urlString

Returns the base portion of the URL for connecting to SOLR based on the current Cassandra server.


136
137
138
139
140
141
142
# File 'lib/datastax_rails/connection.rb', line 136

def solr_base_url
  DatastaxRails::Base.establish_connection unless connection
  port = DatastaxRails::Base.config[:solr][:port]
  path = DatastaxRails::Base.config[:solr][:path]
  protocol = ssl_type ? 'https' : 'http'
  "#{protocol}://#{current_server}:#{port}#{path}"
end

#solr_connection(reconnect = false) ⇒ DatastaxRails::RSolrClientWrapper

Wraps and caches a solr connection object


148
149
150
151
152
153
# File 'lib/datastax_rails/connection.rb', line 148

def solr_connection(reconnect = false)
  if !@rsolr || reconnect
    @rsolr = DatastaxRails::RSolrClientWrapper.new(establish_solr_connection, self)
  end
  @rsolr
end

#ssl_typeObject


114
115
116
117
118
119
120
121
122
123
124
# File 'lib/datastax_rails/connection.rb', line 114

def ssl_type
  return false unless DatastaxRails::Base.config && DatastaxRails::Base.config[:ssl]
  config = DatastaxRails::Base.config
  if config[:ssl][:key] && config[:ssl][:cert]
    :two_way_ssl
  elsif config[:ssl][:ca_cert]
    :one_way_ssl
  else
    false
  end
end