class Elastomer::Client

inject our instrument method into the Client class

Constants

ConnectionFailed
DEFAULT_OPTS
DocumentAlreadyExistsError
IVAR_BLACK_LIST
IVAR_NOISY_LIST
IllegalArgument

Exception for client-detected and server-raised invalid Elasticsearch request parameter.

IncompatibleVersionException

Exception for operations that are unsupported with the version of Elasticsearch being used.

IndexNotFoundError

Provide some nice errors for common Elasticsearch exceptions. These are all subclasses of the more general RequestError

MAX_REQUEST_SIZE
OpaqueIdError

Error raised when a conflict is detected between the UUID sent in the 'X-Opaque-Id' request header and the one received in the response header.

ParsingError
QueryParsingError
RETRYABLE_METHODS
RejectedExecutionError
RequestError
RequestSizeError
ResourceNotFound
SSLError
SearchContextMissing
ServerError
TimeoutError

Wrapper classes for specific Faraday errors.

Attributes

compress_body[R]
compression[R]
es_version[R]
host[R]
max_request_size[R]
max_retries[R]
open_timeout[R]
port[R]
read_timeout[R]
retry_delay[R]
strict_params[R]
strict_params?[R]
url[R]

Public Class Methods

new(host: "localhost", port: 9200, url: nil, read_timeout: 5, open_timeout: 2, max_retries: 0, retry_delay: 0.075, opaque_id: false, adapter: Faraday.default_adapter, max_request_size: MAX_REQUEST_SIZE, strict_params: false, es_version: nil, compress_body: false, compression: Zlib::DEFAULT_COMPRESSION, basic_auth: nil, token_auth: nil) click to toggle source

Create a new client that can be used to make HTTP requests to the Elasticsearch server. If you use `:max_retries`, then any GET or HEAD request will be retried up to this many times with a 75ms delay between the retry attempts. Only non-fatal exceptions will retried automatically.

see lib/elastomer/client/errors.rb#L92-L94

Method params:

:host - the host as a String
:port - the port number of the server
:url  - the URL as a String (overrides :host and :port)
:read_timeout - the timeout in seconds when reading from an HTTP connection
:open_timeout - the timeout in seconds when opening an HTTP connection
:adapter      - the Faraday adapter to use (defaults to :excon)
:opaque_id    - set to `true` to use the 'X-Opaque-Id' request header
:max_request_size - the maximum allowed request size in bytes (defaults to 250 MB)
:max_retries      - the maximum number of request retires (defaults to 0)
:retry_delay      - delay in seconds between retries (defaults to 0.075)
:strict_params    - set to `true` to raise exceptions when invalid request params are used
:es_version       - set to the Elasticsearch version (example: "5.6.6") to avoid an HTTP request to get the version.
:compress_body    - set to true to enable request body compression (default: false)
:compression      - The compression level (0-9) when request body compression is enabled (default: Zlib::DEFAULT_COMPRESSION)
:basic_auth       - a Hash containing basic authentication :username and :password values to use on connections
:token_auth       - an authentication token as a String to use on connections (overrides :basic_auth)
# File lib/elastomer/client.rb, line 46
def initialize(host: "localhost", port: 9200, url: nil,
               read_timeout: 5, open_timeout: 2, max_retries: 0, retry_delay: 0.075,
               opaque_id: false, adapter: Faraday.default_adapter, max_request_size: MAX_REQUEST_SIZE,
               strict_params: false, es_version: nil, compress_body: false, compression: Zlib::DEFAULT_COMPRESSION,
               basic_auth: nil, token_auth: nil)

  @url = url || "http://#{host}:#{port}"

  uri = Addressable::URI.parse @url
  @host = uri.host
  @port = uri.port

  @read_timeout     = read_timeout
  @open_timeout     = open_timeout
  @max_retries      = max_retries
  @retry_delay      = retry_delay
  @adapter          = adapter
  @opaque_id        = opaque_id
  @max_request_size = max_request_size
  @strict_params    = strict_params
  @es_version       = es_version
  @compress_body    = compress_body
  @compression      = compression
  @basic_auth       = basic_auth
  @token_auth       = token_auth
end

Public Instance Methods

add_sort_by_doc(query) click to toggle source

Internal: Add sort by doc to query.

Raises an exception if the query contains a sort already. Returns the query as a hash

# File lib/elastomer/client/scroller.rb, line 124
def add_sort_by_doc(query)
  if query.nil?
    query = {}
  elsif query.is_a? String
    query = MultiJson.load(query)
  end

  if query.has_key? :sort
     raise ArgumentError, "Query cannot contain a sort (found sort '#{query[:sort]}' in query: #{query})"
  end

  query.merge(sort: [:_doc])
end
api_spec() click to toggle source

Returns the ApiSpec for the specific version of Elasticsearch that this Client is connected to.

# File lib/elastomer/client.rb, line 129
def api_spec
  @api_spec ||= RestApiSpec.api_spec(version)
end
app_delete_by_query(query, params = {}) click to toggle source

DEPRECATED: Delete documents from one or more indices and one or more types based on a query.

The return value follows the format returned by the Elasticsearch Delete by Query plugin: github.com/elastic/elasticsearch/blob/v2.4.6/docs/plugins/delete-by-query.asciidoc

Internally, this method uses a combination of scroll and bulk delete instead of the Delete by Query API, which was removed in Elasticsearch 2.0.

For native _delete_by_query functionality in Elasticsearch 5+, see the native_delete_by_query method.

query - The query body as a Hash params - Parameters Hash

Examples

# request body query
app_delete_by_query({:query => {:match_all => {}}}, :type => 'tweet')

# same thing but using the URI request method
app_delete_by_query(nil, { :q => '*:*', :type => 'tweet' })

See www.elastic.co/guide/en/elasticsearch/plugins/current/delete-by-query-usage.html

Returns a Hash of statistics about the delete operations, for example:

{
  "took" : 639,
  "_indices" : {
    "_all" : {
      "found" : 5901,
      "deleted" : 5901,
      "missing" : 0,
      "failed" : 0
    },
    "twitter" : {
      "found" : 5901,
      "deleted" : 5901,
      "missing" : 0,
      "failed" : 0
    }
  },
  "failures" : [ ]
}
# File lib/elastomer/client/app_delete_by_query.rb, line 50
def app_delete_by_query(query, params = {})
  AppDeleteByQuery.new(self, query, params).execute
end
assert_param_presence( param, name = "input value" ) click to toggle source

Internal: Ensure that the parameter has a valid value. Strings, Symbols, Numerics, and Arrays of those things are valid. Things like `nil` and empty strings are right out. This method also performs a little formating on the parameter:

  • leading and trailing whitespace is removed

  • arrays are flattend

  • and then joined into a String

  • numerics are converted to their string equivalents

param - The param Object to validate name - Optional param name as a String (used in exception messages)

Returns the validated param as a String. Raises an ArgumentError if the param is not valid.

# File lib/elastomer/client.rb, line 456
def assert_param_presence( param, name = "input value" )
  case param
  when String, Symbol, Numeric
    param = param.to_s.strip
    raise ArgumentError, "#{name} cannot be blank: #{param.inspect}" if param =~ /\A\s*\z/
    param

  when Array
    param.flatten.map { |item| assert_param_presence(item, name) }.join(",")

  when nil
    raise ArgumentError, "#{name} cannot be nil"

  else
    raise ArgumentError, "#{name} is invalid: #{param.inspect}"
  end
end
available?()
Alias for: ping
bulk( body = nil, params = nil ) { |bulk_obj = bulk| ... } click to toggle source

The `bulk` method can be used in two ways. Without a block the method will perform an API call, and it requires a bulk request body and optional request parameters. If given a block, the method will use a Bulk instance to assemble the operations called in the block into a bulk request and dispatch it at the end of the block.

See www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html

body - Request body as a String (required if a block is not given) params - Optional request parameters as a Hash

:request_size - Optional maximum request size in bytes
:action_count - Optional maximum action size

block - Passed to a Bulk instance which assembles the operations

into one or more bulk requests.

Examples

bulk(request_body, :index => 'default-index')

bulk(:index => 'default-index') do |b|
  b.index(document1)
  b.index(document2, :_type => 'default-type')
  b.delete(document3)
  ...
end

Returns the response body as a Hash

# File lib/elastomer/client/bulk.rb, line 31
def bulk( body = nil, params = nil )
  if block_given?
    params, body = (body || {}), nil
    yield bulk_obj = Bulk.new(self, params)
    bulk_obj.call

  else
    raise "bulk request body cannot be nil" if body.nil?
    params ||= {}

    response = self.post "{/index}{/type}/_bulk", params.merge(body: body, action: "bulk", rest_api: "bulk")
    response.body
  end
end
bulk_stream_items(ops, params = {}) { |item| ... } click to toggle source

Stream bulk actions from an Enumerator and passes the response items to the given block.

Examples

ops = [
  [:index, document1, {:_type => "foo", :_id => 1}],
  [:create, document2],
  [:delete, {:_type => "bar", :_id => 42}]
]
bulk_stream_items(ops, :index => 'default-index') do |item|
  puts item
end

# return value:
# {
#   "took" => 256,
#   "errors" => false,
#   "success" => 3,
#   "failure" => 0
# }

# sample response item:
# {
#   "delete": {
#     "_index": "foo",
#     "_type": "bar",
#     "_id": "42",
#     "_version": 3,
#     "status": 200,
#     "found": true
#   }
# }

Returns a Hash of stats about items from the responses.

# File lib/elastomer/client/bulk.rb, line 119
def bulk_stream_items(ops, params = {})
  stats = {
    "took" => 0,
    "errors" => false,
    "success" => 0,
    "failure" => 0
  }

  bulk_stream_responses(ops, params).each do |response|
    stats["took"] += response["took"]
    stats["errors"] |= response["errors"]

    response["items"].each do |item|
      if is_ok?(item)
        stats["success"] += 1
      else
        stats["failure"] += 1
      end
      yield item
    end
  end

  stats
end
bulk_stream_responses(ops, params = {}) click to toggle source

Stream bulk actions from an Enumerator.

Examples

ops = [
  [:index, document1, {:_type => "foo", :_id => 1}],
  [:create, document2],
  [:delete, {:_type => "bar", :_id => 42}]
]
bulk_stream_responses(ops, :index => 'default-index').each do |response|
  puts response
end

Returns an Enumerator of responses.

# File lib/elastomer/client/bulk.rb, line 60
def bulk_stream_responses(ops, params = {})
  bulk_obj = Bulk.new(self, params)

  Enumerator.new do |yielder|
    ops.each do |action, *args|
      response = bulk_obj.send(action, *args)
      yielder.yield response unless response.nil?
    end

    response = bulk_obj.call
    yielder.yield response unless response.nil?
  end
end
clear_scroll( scroll_ids ) click to toggle source

Delete one or more scroll IDs. see www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html#_clear_scroll_api

scroll_id - One or more scroll IDs

Returns the response body as a Hash.

# File lib/elastomer/client/scroller.rb, line 115
def clear_scroll( scroll_ids )
  response = delete "/_search/scroll", body: {scroll_id: Array(scroll_ids)}, action: "search.clear_scroll", rest_api: "clear_scroll"
  response.body
end
cluster() click to toggle source

Returns a Cluster instance.

# File lib/elastomer/client/cluster.rb, line 5
def cluster
  @cluster ||= Cluster.new self
end
connection() click to toggle source

Internal: Provides access to the Faraday::Connection used by this client for all requests to the server.

Returns a Faraday::Connection

# File lib/elastomer/client.rb, line 137
def connection
  @connection ||= Faraday.new(url) do |conn|
    conn.response(:parse_json)
    # Request compressed responses from ES and decompress them
    conn.use(:gzip)
    conn.request(:encode_json)
    conn.request(:opaque_id) if @opaque_id
    conn.request(:limit_size, max_request_size: max_request_size) if max_request_size
    conn.request(:elastomer_compress, compression: compression) if compress_body

    conn.options[:timeout]      = read_timeout
    conn.options[:open_timeout] = open_timeout

    if token_auth?
      conn.token_auth(@token_auth)
    elsif basic_auth?
      conn.basic_auth(@basic_auth[:username], @basic_auth[:password])
    end

    if @adapter.is_a?(Array)
      conn.adapter(*@adapter)
    else
      conn.adapter(@adapter)
    end
  end
end
continue_scroll( scroll_id, scroll = "5m" ) click to toggle source

Continue scrolling a query. See www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html

scroll_id - The current scroll ID as a String scroll - The keep alive time of the scrolling request (5 minutes by default)

Examples

scroll_id = client.start_scroll(body: '{"query":{"match_all":{}}}', index: 'test')['_scroll_id']

h = client.continue_scroll scroll_id   # scroll to get the next set of results
scroll_id = h['_scroll_id']            # and store the scroll_id to use later

h = client.continue_scroll scroll_id   # scroll again to get the next set of results
scroll_id = h['_scroll_id']            # and store the scroll_id to use later

# repeat until the results are empty

Returns the response body as a Hash.

# File lib/elastomer/client/scroller.rb, line 98
def continue_scroll( scroll_id, scroll = "5m" )
  response = get "/_search/scroll", body: {scroll_id: scroll_id}, scroll: scroll, action: "search.scroll", rest_api: "scroll"
  response.body
rescue RequestError => err
  if err.error && err.error["caused_by"]["type"] == "search_context_missing_exception"
    raise SearchContextMissing, "No search context found for scroll ID #{scroll_id.inspect}"
  else
    raise err
  end
end
delete( path, params = {} ) click to toggle source

Internal: Sends an HTTP DELETE request to the server.

path - The path as a String params - Parameters Hash

Returns a Faraday::Response Raises an Elastomer::Client::Error on 4XX and 5XX responses

# File lib/elastomer/client.rb, line 223
def delete( path, params = {} )
  request :delete, path, params
end
delete_by_query(query, params = {}) click to toggle source

Execute delete_by_query using the native _delete_by_query API if supported or the application-level implementation.

Warning: These implementations have different parameters and return types. If you want to use one or the other consistently, use Elastomer::Client#native_delete_by_query or Elastomer::Client#app_delete_by_query directly.

# File lib/elastomer/client/delete_by_query.rb, line 9
def delete_by_query(query, params = {})
  send(version_support.delete_by_query_method, query, params)
end
docs( name = nil, type = nil ) click to toggle source

Provides access to document-level API commands. Indexing documents and searching documents are both handled by this module.

name - The name of the index as a String (optional) type - The document type as a String (optional)

See www.elastic.co/guide/en/elasticsearch/reference/current/docs.html

Returns a Docs instance.

# File lib/elastomer/client/docs.rb, line 14
def docs( name = nil, type = nil )
  Docs.new self, name, type
end
dup() click to toggle source

Returns a duplicate of this Client connection configured in the exact same fashion.

# File lib/elastomer/client.rb, line 84
def dup
  self.class.new \
      url:              url,
      read_timeout:     read_timeout,
      open_timeout:     open_timeout,
      adapter:          @adapter,
      opaque_id:        @opaque_id,
      max_request_size: max_request_size,
      basic_auth:       @basic_auth,
      token_auth:       @token_auth
end
expand_path( path, params ) click to toggle source

Internal: Apply path expansions to the `path` and append query parameters to the `path`. We are using an Addressable::Template to replace '{expansion}' fields found in the path with the values extracted from the `params` Hash. Any remaining elements in the `params` hash are treated as query parameters and appended to the end of the path.

path - The path as a String params - Parameters Hash

Examples

expand_path('/foo{/bar}', {bar: 'hello', q: 'what', p: 2})
#=> '/foo/hello?q=what&p=2'

expand_path('/foo{/bar}{/baz}', {baz: 'no bar'}
#=> '/foo/no%20bar'

Returns an Addressable::Uri

# File lib/elastomer/client.rb, line 363
def expand_path( path, params )
  template = Addressable::Template.new path

  expansions = {}
  query_values = params.dup
  query_values.delete :action
  query_values.delete :context
  query_values.delete :retries

  rest_api = query_values.delete :rest_api

  template.keys.map(&:to_sym).each do |key|
    value = query_values.delete key
    value = assert_param_presence(value, key) unless path =~ /{\/#{key}}/ && value.nil?
    expansions[key] = value
  end

  if rest_api
    query_values = if strict_params?
      api_spec.validate_params!(api: rest_api, params: query_values)
    else
      api_spec.select_params(api: rest_api, from: query_values)
    end
  end

  uri = template.expand(expansions)
  uri.query_values = query_values unless query_values.empty?
  uri.to_s
end
extract_body( params ) click to toggle source

Internal: Extract the :body from the params Hash and convert it to a JSON String format. If the params Hash does not contain a :body then no action is taken and `nil` is returned.

If a :body is present and is a String then it is assumed to a JSON String and returned “as is”.

If a :body is present and is an Array then we join the values together with newlines and append a trailing newline. This is a special case for dealing with ES `bulk` imports and `multi_search` methods.

Otherwise we convert the :body to a JSON string and return.

params - Parameters Hash

Returns the request body as a String or `nil` if no :body is present

# File lib/elastomer/client.rb, line 326
def extract_body( params )
  body = params.delete :body
  return if body.nil?

  body =
    case body
    when String
      body
    when Array
      body << nil unless body.last.nil?
      body.join "\n"
    else
      MultiJson.dump body
    end

  # Prevent excon from changing the encoding (see https://github.com/github/elastomer-client/issues/138)
  body.freeze
end
get( path, params = {} ) click to toggle source

Internal: Sends an HTTP GET request to the server.

path - The path as a String params - Parameters Hash

Returns a Faraday::Response Raises an Elastomer::Client::Error on 4XX and 5XX responses

# File lib/elastomer/client.rb, line 190
def get( path, params = {} )
  request :get, path, params
end
handle_errors( response ) click to toggle source

Internal: Inspect the Faraday::Response and raise an error if the status is in the 5XX range or if the response body contains an 'error' field. In the latter case, the value of the 'error' field becomes our exception message. In the absence of an 'error' field the response body is used as the exception message.

The raised exception will contain the response object.

response - The Faraday::Response object.

Returns the response. Raises an Elastomer::Client::Error on 500 responses or responses containing and 'error' field.

# File lib/elastomer/client.rb, line 419
def handle_errors( response )
  raise ServerError, response if response.status >= 500

  if response.body.is_a?(Hash) && (error = response.body["error"])
    root_cause = Array(error["root_cause"]).first || error
    case root_cause["type"]
    when "index_not_found_exception"; raise IndexNotFoundError, response
    when "illegal_argument_exception"; raise IllegalArgument, response
    when "es_rejected_execution_exception"; raise RejectedExecutionError, response
    # Elasticsearch 2.x.x root_cause type for document already existing
    when "document_already_exists_exception"; raise DocumentAlreadyExistsError, response
    # Elasticsearch 5.x.x root_cause type for document already existing
    when "version_conflict_engine_exception"; raise DocumentAlreadyExistsError, response
    when *version_support.query_parse_exception; raise QueryParsingError, response
    end

    raise RequestError, response
  end

  response
end
head( path, params = {} ) click to toggle source

Internal: Sends an HTTP HEAD request to the server.

path - The path as a String params - Parameters Hash

Returns a Faraday::Response

# File lib/elastomer/client.rb, line 179
def head( path, params = {} )
  request :head, path, params
end
index( name = nil ) click to toggle source

Provides access to index-level API commands. An index name is required for these API calls. If you want to operate on all indices - flushing all indices, for example - then you will need to use the “_all” index name.

You can override the index name for one-off calls by passing in the desired index name via the `:index` option.

name - The name of the index as a String or an Array of names

Returns an Index instance.

# File lib/elastomer/client/index.rb, line 14
def index( name = nil )
  Index.new self, name
end
info() click to toggle source

Returns the information Hash from the attached Elasticsearch instance.

# File lib/elastomer/client.rb, line 122
def info
  response = get "/", action: "cluster.info"
  response.body
end
inspect() click to toggle source
# File lib/elastomer/client.rb, line 478
def inspect
  public_vars = self.instance_variables.reject do |var|
    IVAR_NOISY_LIST.include?(var)
  end.map do |var|
    "#{var}=#{IVAR_BLACK_LIST.include?(var) ? "[FILTERED]" : instance_variable_get(var).inspect}"
  end.join(", ")
  "<##{self.class}:#{self.object_id.to_s(16)} #{public_vars}>"
end
instrument( path, body, params ) { || ... } click to toggle source

Internal: A noop method that simply yields to the block. This method will be replaced when the 'elastomer/notifications' module is included.

path - The full request path as a String body - The request body as a String or `nil` params - The request params Hash block - The block that will be instrumented

Returns the response from the block

# File lib/elastomer/client.rb, line 402
def instrument( path, body, params )
  yield
end
is_ok?(item) click to toggle source

Internal: Determine whether or not a response item has an HTTP status code in the range 200 to 299.

item - The bulk response item

Returns a boolean

# File lib/elastomer/client/bulk.rb, line 80
def is_ok?(item)
  item.values.first["status"].between?(200, 299)
end
mpercolate(body = nil, params = nil)
Alias for: multi_percolate
msearch(body = nil, params = nil)
Alias for: multi_search
multi_percolate(body = nil, params = nil) { |mpercolate_obj = multi_percolate| ... } click to toggle source

Execute an array of percolate actions in bulk. Results are returned in an array in the order the actions were sent.

The `multi_percolate` method can be used in two ways. Without a block the method will perform an API call, and it requires a bulk request body and optional request parameters.

See www.elastic.co/guide/en/elasticsearch/reference/current/search-percolate.html#_multi_percolate_api

body - Request body as a String (required if a block is not given) params - Optional request parameters as a Hash block - Passed to a MultiPercolate instance which assembles the

percolate actions into a single request.

Examples

# index and type in request body
multi_percolate(request_body)

# index in URI
multi_percolate(request_body, index: 'default-index')

# block form
multi_percolate(index: 'default-index') do |m|
  m.percolate({ author: "pea53" }, { type: 'default-type' })
  m.count({ author: "pea53" }, { type: 'type2' })
  ...
end

Returns the response body as a Hash

# File lib/elastomer/client/multi_percolate.rb, line 34
def multi_percolate(body = nil, params = nil)
  if block_given?
    params, body = (body || {}), nil
    yield mpercolate_obj = MultiPercolate.new(self, params)
    mpercolate_obj.call
  else
    raise "multi_percolate request body cannot be nil" if body.nil?
    params ||= {}

    response = self.post "{/index}{/type}/_mpercolate", params.merge(body: body, action: "mpercolate", rest_api: "mpercolate")
    response.body
  end
end
Also aliased as: mpercolate
native_delete_by_query(query, parameters = {}) click to toggle source

Delete documents based on a query using the Elasticsearch _delete_by_query API.

query - The query body as a Hash params - Parameters Hash

Examples

# request body query
native_delete_by_query({query: {match_all: {}}}, type: 'tweet')

See www.elastic.co/guide/en/elasticsearch/reference/5.6/docs-delete-by-query.html

Returns a Hash containing the _delete_by_query response body.

# File lib/elastomer/client/native_delete_by_query.rb, line 16
def native_delete_by_query(query, parameters = {})
  NativeDeleteByQuery.new(self, query, parameters).execute
end
nodes( node_id = nil ) click to toggle source

Provides access to node-level API commands. The default node is set to nil which target all nodes. You can pass in “_all” (to get the same effect) or “_local” to target only the current node the client is connected to. And you can specify an individual node or multiple nodes.

node_id - The node ID as a String or an Array of node IDs

Returns a Nodes instance.

# File lib/elastomer/client/nodes.rb, line 13
def nodes( node_id = nil )
  Nodes.new self, node_id
end
ping() click to toggle source

Returns true if the server is available; returns false otherwise.

# File lib/elastomer/client.rb, line 97
def ping
  response = head "/", action: "cluster.ping"
  response.success?
rescue StandardError
  false
end
Also aliased as: available?
post( path, params = {} ) click to toggle source

Internal: Sends an HTTP POST request to the server.

path - The path as a String params - Parameters Hash

Returns a Faraday::Response Raises an Elastomer::Client::Error on 4XX and 5XX responses

# File lib/elastomer/client.rb, line 212
def post( path, params = {} )
  request :post, path, params
end
put( path, params = {} ) click to toggle source

Internal: Sends an HTTP PUT request to the server.

path - The path as a String params - Parameters Hash

Returns a Faraday::Response Raises an Elastomer::Client::Error on 4XX and 5XX responses

# File lib/elastomer/client.rb, line 201
def put( path, params = {} )
  request :put, path, params
end
repository(name = nil) click to toggle source

Returns a Repository instance.

# File lib/elastomer/client/repository.rb, line 5
def repository(name = nil)
  Repository.new(self, name)
end
request( method, path, params ) click to toggle source

Internal: Sends an HTTP request to the server. If the `params` Hash contains a :body key, it will be deleted from the Hash and the value will be used as the body of the request.

method - The HTTP method to send [:head, :get, :put, :post, :delete] path - The path as a String params - Parameters Hash

:body         - Will be used as the request body
:read_timeout - Optional read timeout (in seconds) for the request
:max_retires  - Optional retry number for the request

Returns a Faraday::Response Raises an Elastomer::Client::Error on 4XX and 5XX responses rubocop:disable Metrics/MethodLength

# File lib/elastomer/client.rb, line 241
def request( method, path, params )
  read_timeout = params.delete(:read_timeout)
  request_max_retries = params.delete(:max_retries) || max_retries
  body = extract_body(params)
  path = expand_path(path, params)

  params[:retries] = retries = 0
  instrument(path, body, params) do
    begin
      response =
        case method
        when :head
          connection.head(path) { |req| req.options[:timeout] = read_timeout if read_timeout }

        when :get
          connection.get(path) { |req|
            req.body = body if body
            req.options[:timeout] = read_timeout if read_timeout
          }

        when :put
          connection.put(path, body) { |req| req.options[:timeout] = read_timeout if read_timeout }

        when :post
          connection.post(path, body) { |req| req.options[:timeout] = read_timeout if read_timeout }

        when :delete
          connection.delete(path) { |req|
            req.body = body if body
            req.options[:timeout] = read_timeout if read_timeout
          }

        else
          raise ArgumentError, "unknown HTTP request method: #{method.inspect}"
        end

      handle_errors response

    # wrap Faraday errors with appropriate Elastomer::Client error classes
    rescue Faraday::Error::ClientError => boom
      error = wrap_faraday_error(boom, method, path)
      if error.retry? && RETRYABLE_METHODS.include?(method) && (retries += 1) <= request_max_retries
        params[:retries] = retries
        sleep retry_delay
        retry
      end
      raise error
    rescue OpaqueIdError => boom
      reset!
      raise boom
    end
  end
end
reset!() click to toggle source

Internal: Reset the client by removing the current Faraday::Connection. A new connection will be established on the next request.

Returns this Client instance.

# File lib/elastomer/client.rb, line 168
def reset!
  @connection = nil
  self
end
scan( query, opts = {} ) click to toggle source

Create a new Scroller instance for scrolling all results from a `query` via “scan” semantics by sorting by _doc.

query - The query to scan as a Hash or a JSON encoded String opts - Options Hash

:index  - the name of the index to search
:type   - the document type to search
:scroll - the keep alive time of the scrolling request (5 minutes by default)
:size   - the number of documents per shard to fetch per scroll

Examples

scan = client.scan('{"query":{"match_all":{}}}', index: 'test')
scan.each_document do |document|
  document['_id']
  document['_source']
end

Returns a new Scroller instance

# File lib/elastomer/client/scroller.rb, line 45
def scan( query, opts = {} )
  Scroller.new(self, add_sort_by_doc(query), opts)
end
scroll( query, opts = {} ) click to toggle source

Create a new Scroller instance for scrolling all results from a `query`.

query - The query to scroll as a Hash or a JSON encoded String opts - Options Hash

:index  - the name of the index to search
:type   - the document type to search
:scroll - the keep alive time of the scrolling request (5 minutes by default)
:size   - the number of documents per shard to fetch per scroll

Examples

scroll = client.scroll('{"query":{"match_all":{}}}', index: 'test')
scroll.each_document do |document|
  document['_id']
  document['_source']
end

Returns a new Scroller instance

# File lib/elastomer/client/scroller.rb, line 22
def scroll( query, opts = {} )
  Scroller.new(self, query, opts)
end
semantic_version() click to toggle source

Returns a Semantic::Version for the attached Elasticsearch instance. See rubygems.org/gems/semantic

# File lib/elastomer/client.rb, line 117
def semantic_version
  Semantic::Version.new(version)
end
snapshot(repository = nil, name = nil) click to toggle source

Provides access to snapshot API commands.

repository - The name of the repository as a String name - The name of the snapshot as a String

Returns a Snapshot instance.

# File lib/elastomer/client/snapshot.rb, line 10
def snapshot(repository = nil, name = nil)
  Snapshot.new self, repository, name
end
start_scroll( opts = {} ) click to toggle source

Begin scrolling a query. See www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html

opts - Options Hash

:body        - the query to scroll as a Hash or JSON encoded String
:index       - the name of the index to search
:type        - the document type to search
:scroll      - the keep alive time of the scrolling request (5 minutes by default)
:size        - the number of documents per shard to fetch per scroll
:search_type - set to 'scan' for scan semantics  # DEPRECATED in ES 2.1.0 - use a Scroll query sorted by _doc: https://www.elastic.co/guide/en/elasticsearch/reference/2.3/search-request-search-type.html#scan

Examples

h = client.start_scroll(body: '{"query":{"match_all":{}},"sort":{"created":"desc"}}', index: 'test')
scroll_id = h['_scroll_id']
h['hits']['hits'].each { |doc| ... }

h = client.continue_scroll(scroll_id)
scroll_id = h['_scroll_id']
h['hits']['hits'].each { |doc| ... }

# repeat until there are no more hits

Returns the response body as a Hash.

# File lib/elastomer/client/scroller.rb, line 73
def start_scroll( opts = {} )
  opts = opts.merge action: "search.start_scroll", rest_api: "search"
  response = get "{/index}{/type}/_search", opts
  response.body
end
tasks() click to toggle source

Returns a Tasks instance for querying the cluster bound to this client for metadata about internal tasks in flight, and to submit administrative requests (like cancellation) concerning those tasks.

Returns a new Tasks object associated with this client

# File lib/elastomer/client/tasks.rb, line 9
def tasks
  Tasks.new(self)
end
template( name ) click to toggle source

Returns a Template instance.

# File lib/elastomer/client/template.rb, line 6
def template( name )
  Template.new self, name
end
version() click to toggle source

Returns the version String of the attached Elasticsearch instance.

# File lib/elastomer/client.rb, line 106
def version
  return es_version unless es_version.nil?

  @version ||= begin
    response = get "/"
    response.body.dig("version", "number")
  end
end
version_support() click to toggle source
# File lib/elastomer/client.rb, line 474
def version_support
  @version_support ||= VersionSupport.new(version)
end
wrap_faraday_error(error, method, path) click to toggle source

Internal: Returns a new Elastomer::Client error that wraps the given Faraday error. A generic Error is returned if we cannot wrap the given Faraday error.

error  - The Faraday error
method - The request method
path   - The request path
# File lib/elastomer/client.rb, line 304
def wrap_faraday_error(error, method, path)
  error_name  = error.class.name.split("::").last
  error_class = Elastomer::Client.const_get(error_name) rescue Elastomer::Client::Error
  error_class.new(error, method.upcase, path)
end

Private Instance Methods

basic_auth?() click to toggle source
# File lib/elastomer/client.rb, line 493
def basic_auth?
  @basic_auth.is_a?(Hash) &&
    present_for_auth?(@basic_auth[:username]) &&
    present_for_auth?(@basic_auth[:password])
end
present_for_auth?(object) click to toggle source

Cheap implementation of ActiveSupport's Object#present?

# File lib/elastomer/client.rb, line 500
def present_for_auth?(object)
  object.respond_to?(:empty?) ? !object.empty? : !!object
end
token_auth?() click to toggle source
# File lib/elastomer/client.rb, line 489
def token_auth?
  present_for_auth?(@token_auth)
end