class Waistband::Index

Constants

BODY_SIZE_LIMIT

Public Class Methods

new(index_name, options = {}) click to toggle source
# File lib/waistband/index.rb, line 14
def initialize(index_name, options = {})
  options = options.stringify_keys

  @index_name = index_name
  @stringify  = config['stringify']
  @log_level  = config['log_level']

  # subindexes checks
  if options['version'].present?
    # version
    @version  = options['version']
    @subs     = ['version', @version]
  elsif options['subs'].present?
    # subs
    @subs = [options['subs']] if options['subs'].present?
    @subs = @subs.flatten     if @subs.is_a?(Array)
  end

end

Public Instance Methods

alias(alias_name) click to toggle source
# File lib/waistband/index.rb, line 248
def alias(alias_name)
  alias_name = full_alias_name alias_name
  client.indices.put_alias(
    index: config_name,
    name: alias_name
  )
end
alias_exists?(alias_name) click to toggle source
# File lib/waistband/index.rb, line 256
def alias_exists?(alias_name)
  alias_name = full_alias_name alias_name
  client.indices.exists_alias(
    index: config_name,
    name: alias_name
  )
end
client() click to toggle source
# File lib/waistband/index.rb, line 268
def client
  @client ||= begin

    _client = if client_config_hash
      ::Waistband::Client.from_config(client_config_hash)
    else
      ::Waistband.config.client
    end

    if @log_level && Waistband.config.logger
      _client.transport.logger       = Waistband.config.logger
      _client.transport.logger.level = @log_level
    end

    _client

  end
end
config() click to toggle source
# File lib/waistband/index.rb, line 264
def config
  ::Waistband.config.index @index_name
end
create() click to toggle source
# File lib/waistband/index.rb, line 73
def create
  create!
rescue ::Waistband::Errors::IndexExists => ex
  true
end
create!() click to toggle source
# File lib/waistband/index.rb, line 79
def create!
  check_permission!('create')

  client.indices.create index: config_name, body: config.except('name', 'permissions', 'stringify', 'log_level')
rescue Elasticsearch::Transport::Transport::Errors::BadRequest => ex
  raise ex unless ex.message.to_s =~ /already_exists_exception/
  raise ::Waistband::Errors::IndexExists.new("Index already exists")
end
delete() click to toggle source
# File lib/waistband/index.rb, line 88
def delete
  delete!
rescue ::Waistband::Errors::IndexNotFound => ex
  true
end
delete!() click to toggle source
# File lib/waistband/index.rb, line 94
def delete!
  check_permission!('delete_index')

  client.indices.delete index: config_name
rescue Elasticsearch::Transport::Transport::Errors::NotFound => ex
  raise ex unless ex.message.to_s =~ /index_not_found_exception/
  raise ::Waistband::Errors::IndexNotFound.new("Index not found")
end
delete_by_query(query) click to toggle source
# File lib/waistband/index.rb, line 244
def delete_by_query(query)
  ::Waistband::DeleteByQueryResult.new(client.delete_by_query(index: config_name, body: query))
end
destroy(id, options = {}) click to toggle source
# File lib/waistband/index.rb, line 210
def destroy(id, options = {})
  destroy!(id, options)
rescue Elasticsearch::Transport::Transport::Errors::NotFound
  nil
end
destroy!(id, options = {}) click to toggle source
# File lib/waistband/index.rb, line 216
def destroy!(id, options = {})
  check_permission!('destroy')

  options = options.with_indifferent_access
  type = options[:_type] || default_type_name

  client.delete(
    index: config_name,
    id: id,
    type: type
  )
end
exists?() click to toggle source
# File lib/waistband/index.rb, line 34
def exists?
  client.indices.exists index: config_name
end
find(id, options = {}) click to toggle source
# File lib/waistband/index.rb, line 169
def find(id, options = {})
  find!(id, options)
rescue Elasticsearch::Transport::Transport::Errors::NotFound
  nil
end
find!(id, options = {}) click to toggle source
# File lib/waistband/index.rb, line 175
def find!(id, options = {})
  doc = read!(id, options)
  doc['_source']
end
read(id, options = {}) click to toggle source
# File lib/waistband/index.rb, line 191
def read(id, options = {})
  read!(id, options)
rescue Elasticsearch::Transport::Transport::Errors::NotFound
  nil
end
read!(id, options = {}) click to toggle source
# File lib/waistband/index.rb, line 197
def read!(id, options = {})
  check_permission!('read')

  options = options.with_indifferent_access
  type = options[:_type] || default_type_name

  client.get(
    index: config_name,
    type: type,
    id: id
  ).with_indifferent_access
end
read_result(id, options = {}) click to toggle source
# File lib/waistband/index.rb, line 180
def read_result(id, options = {})
  read_result!(id, options)
rescue Elasticsearch::Transport::Transport::Errors::NotFound
  nil
end
read_result!(id, options = {}) click to toggle source
# File lib/waistband/index.rb, line 186
def read_result!(id, options = {})
  hit = read!(id, options)
  ::Waistband::Result.new(hit)
end
refresh() click to toggle source
# File lib/waistband/index.rb, line 38
def refresh
  client.indices.refresh index: config_name
end
save(*args) click to toggle source
# File lib/waistband/index.rb, line 129
def save(*args)
  save!(*args)
rescue ::Waistband::Errors::UnableToSave => ex
  false
end
save!(*args) click to toggle source
# File lib/waistband/index.rb, line 103
def save!(*args)
  check_permission!('write')

  body_hash = args.extract_options!
  id = args.first
  _type = body_hash.delete(:_type) || body_hash.delete('_type') || default_type_name

  # map everything to strings if need be
  body_hash = stringify_all(body_hash) if @stringify

  verify_body_size(config_name, _type, id, body_hash)

  saved = client.index(
    index: config_name,
    type: _type,
    id: id,
    body: body_hash
  )

  unless saved['_id'].present?
    raise ::Waistband::Errors::UnableToSave.new("Unable to save to index: #{config_name}, type: #{_type}, id: #{id}: result: #{saved}")
  end

  saved
end
update(*args) click to toggle source
# File lib/waistband/index.rb, line 163
def update(*args)
  update!(*args)
rescue ::Waistband::Errors::UnableToUpdate
  false
end
update!(*args) click to toggle source
# File lib/waistband/index.rb, line 135
def update!(*args)
  check_permission!('write')

  body_hash = args.extract_options!
  id = args.first
  _type = body_hash.delete(:_type) || body_hash.delete('_type') || default_type_name

  # map everything to strings if need be
  body_hash = stringify_all(body_hash) if @stringify

  verify_body_size(config_name, _type, id, body_hash)

  body_hash = { doc: body_hash }

  saved = client.update(
    index: config_name,
    type: _type,
    id: id,
    body: body_hash
  )

  unless saved['_id'].present?
    raise ::Waistband::Errors::UnableToUpdate.new("Unable to update to index: #{config_name}, type: #{_type}, id: #{id}: result: #{saved}")
  end

  saved
end
update_all_mappings() click to toggle source
# File lib/waistband/index.rb, line 42
def update_all_mappings
  check_permission!('create')

  responses = types.map do |type|
    update_mapping(type).merge('_type' => type)
  end
end
update_mapping(type) click to toggle source
# File lib/waistband/index.rb, line 50
def update_mapping(type)
  check_permission!('create')

  properties = config['mappings'][type]['properties'] || {}

  mapping_hash = {type => {properties: properties}}

  client.indices.put_mapping(
    index: config_name,
    type: type,
    body: mapping_hash
  )
end
update_settings() click to toggle source
# File lib/waistband/index.rb, line 64
def update_settings
  check_permission!('create')

  client.indices.put_settings(
    index: config_name,
    body: settings
  )
end

Private Instance Methods

base_config_name() click to toggle source
# File lib/waistband/index.rb, line 387
def base_config_name
  return config['name'] if config['name']
  "#{@index_name}_#{::Waistband.config.env}"
end
check_permission!(permission) click to toggle source
# File lib/waistband/index.rb, line 392
def check_permission!(permission)
  raise "::Waistband::Errors::Permissions::#{permission.classify}".constantize.new("Don't have enough permissions to #{permission} on index #{config_name}") unless check_permission?(permission)
end
check_permission?(permission) click to toggle source
# File lib/waistband/index.rb, line 396
def check_permission?(permission)
  !!permissions[permission]
end
client_config_hash() click to toggle source
# File lib/waistband/index.rb, line 312
def client_config_hash
  config['connection']
end
config_name() click to toggle source
# File lib/waistband/index.rb, line 383
def config_name
  @subs ? "#{base_config_name}__#{@subs.join('_')}" : base_config_name
end
custom_name?() click to toggle source
# File lib/waistband/index.rb, line 347
def custom_name?
  !!config['name']
end
default_type_name() click to toggle source
# File lib/waistband/index.rb, line 366
def default_type_name
  return default_type_name_from_mappings if default_type_name_from_mappings
  @index_name.singularize
end
default_type_name_from_mappings() click to toggle source
# File lib/waistband/index.rb, line 371
def default_type_name_from_mappings
  @default_type_name_from_mappings ||= begin
    mappings = (config['mappings'] || {})
    mappings.keys.first
  end
end
full_alias_name(alias_name) click to toggle source
# File lib/waistband/index.rb, line 339
def full_alias_name(alias_name)
  unless custom_name?
    "#{alias_name}_#{::Waistband.config.env}"
  else
    alias_name
  end
end
get_page_info(body_hash) click to toggle source
# File lib/waistband/index.rb, line 316
def get_page_info(body_hash)
  page = body_hash[:page]
  page_size = body_hash[:page_size]
  [page, page_size]
end
log_warning(msg) click to toggle source
# File lib/waistband/index.rb, line 302
def log_warning(msg)
  return unless logger

  logger.warn "[WAISTBAND :: WARNING] #{msg}"
end
logger() click to toggle source
# File lib/waistband/index.rb, line 308
def logger
  client.transport.logger
end
parse_search_body(body_hash) click to toggle source
# File lib/waistband/index.rb, line 322
def parse_search_body(body_hash)
  body_hash = body_hash.with_indifferent_access

  page = body_hash.delete(:page)
  page_size = body_hash.delete(:page_size)

  if page || page_size
    page ||= 1
    page = page.to_i
    page_size ||= 20
    body_hash[:from] = page_size * (page - 1) unless body_hash[:from]
    body_hash[:size] = page_size              unless body_hash[:size]
  end

  body_hash
end
permissions() click to toggle source
# File lib/waistband/index.rb, line 400
def permissions
  @permissions ||= (config['permissions'] || {}).reverse_merge({
    'create'       => true,
    'delete_index' => true,
    'destroy'      => true,
    'read'         => true,
    'write'        => true
  }).with_indifferent_access
end
settings() click to toggle source
# File lib/waistband/index.rb, line 378
def settings
  settings = config['settings']['index'].except('number_of_shards')
  {index: settings}
end
stringify_all(data) click to toggle source
# File lib/waistband/index.rb, line 351
def stringify_all(data)
  data = if data.is_a? Array
    ::Waistband::StringifiedArray.new data
  elsif data.is_a? Hash
    ::Waistband::StringifiedHash.new_from data
  end

  data = data.stringify_all if data.respond_to? :stringify_all
  data
end
types() click to toggle source
# File lib/waistband/index.rb, line 362
def types
  config.try(:[], 'mappings').try(:keys) || []
end
verify_body_size(index_config_name, type, id, body_hash) click to toggle source
# File lib/waistband/index.rb, line 289
def verify_body_size(index_config_name, type, id, body_hash)
  body_json = body_hash.to_json
  size = body_json.bytesize

  if size > BODY_SIZE_LIMIT
    msg  = "verify_body_size: Body size larger than limit.  "
    msg << "Current size: #{size}.  Limit: #{BODY_SIZE_LIMIT}.  "
    msg << "index_config_name: #{index_config_name}.  _type: #{type}.  id: #{id}.  "
    msg << "body: #{body_json[0, 1000]}"
    log_warning(msg)
  end
end