From e370f09c56940b30391e69f6dd78d93ec017e214 Mon Sep 17 00:00:00 2001 From: "Marcos G. Zimmermann" Date: Fri, 2 Aug 2024 12:11:49 -0300 Subject: [PATCH] chore: add --settings to the reset, create and update_settings index cli (#20) --- lib/esse/cli/index.rb | 16 ++- lib/esse/cli/templates/config.rb.erb | 6 +- lib/esse/config.rb | 7 +- lib/esse/index/indices.rb | 25 +++-- lib/esse/index/settings.rb | 25 ++++- lib/esse/primitives/hash_utils.rb | 10 ++ spec/esse/cli/index/create_spec.rb | 5 + spec/esse/cli/index/reset_spec.rb | 5 + spec/esse/cli/index/update_settings_spec.rb | 5 + spec/esse/index/settings_spec.rb | 106 ++++++++++++++---- .../index/create_index_spec.rb | 6 +- .../transport/update_mapping_spec.rb | 2 +- .../index/create_index_spec.rb | 6 +- .../transport/update_mapping_spec.rb | 2 +- .../index/create_index_spec.rb | 6 +- .../transport/update_mapping_spec.rb | 2 +- .../index/create_index_spec.rb | 6 +- .../transport/update_mapping_spec.rb | 2 +- .../index/create_index_spec.rb | 6 +- .../transport/create_index_spec.rb | 6 +- spec/esse/primitives/hash_utils_spec.rb | 24 ++++ spec/fixtures/config/esse_with_clusters.yml | 10 +- spec/support/config_helpers.rb | 6 +- .../shared_examples/index_create_index.rb | 4 +- .../shared_examples/index_delete_index.rb | 2 +- .../shared_examples/transport_aliases.rb | 4 +- .../shared_examples/transport_close.rb | 2 +- .../shared_examples/transport_create_index.rb | 6 +- .../shared_examples/transport_delete_index.rb | 2 +- .../transport_documents_bulk.rb | 6 +- .../transport_documents_count.rb | 4 +- .../transport_documents_delete.rb | 4 +- .../transport_documents_exist.rb | 4 +- .../transport_documents_get.rb | 4 +- .../transport_documents_index.rb | 2 +- .../transport_documents_update.rb | 4 +- .../support/shared_examples/transport_open.rb | 2 +- .../shared_examples/transport_refresh.rb | 2 +- .../transport_update_aliases.rb | 6 +- .../transport_update_mapping.rb | 2 +- 40 files changed, 258 insertions(+), 96 deletions(-) diff --git a/lib/esse/cli/index.rb b/lib/esse/cli/index.rb index 5a44796..8650fc5 100644 --- a/lib/esse/cli/index.rb +++ b/lib/esse/cli/index.rb @@ -17,9 +17,11 @@ class Index < Base option :suffix, type: :string, default: nil, aliases: '-s', desc: 'Suffix to append to index name' option :import, type: :boolean, default: true, desc: 'Import documents before point alias to the new index' option :optimize, type: :boolean, default: true, desc: 'Optimize index before import documents by disabling refresh_interval and setting number_of_replicas to 0' + option :settings, type: :hash, default: nil, desc: 'List of settings to pass to the index class. Example: --settings=refresh_interval:1s,number_of_replicas:0' def reset(*index_classes) require_relative 'index/reset' - Reset.new(indices: index_classes, **options.to_h.transform_keys(&:to_sym)).run + opts = HashUtils.deep_transform_keys(options.to_h, &:to_sym) + Reset.new(indices: index_classes, **opts).run end # @TODO Add reindex task to create a new index and import documents from the old index using _reindex API @@ -33,9 +35,11 @@ def reset(*index_classes) DESC option :suffix, type: :string, default: nil, aliases: '-s', desc: 'Suffix to append to index name' option :alias, type: :boolean, default: false, aliases: '-a', desc: 'Update alias after create index' + option :settings, type: :hash, default: nil, desc: 'List of settings to pass to the index class. Example: --settings=index.refresh_interval:-1,index.number_of_replicas:0' def create(*index_classes) require_relative 'index/create' - Create.new(indices: index_classes, **options.to_h.transform_keys(&:to_sym)).run + opts = HashUtils.deep_transform_keys(options.to_h, &:to_sym) + Create.new(indices: index_classes, **opts).run end desc 'delete *INDEX_CLASSES', 'Deletes indices for the given classes' @@ -58,9 +62,11 @@ def update_aliases(*index_classes) desc 'update_settings *INDEX_CLASS', 'Closes the index for read/write operations, updates the index settings, and open it again' option :suffix, type: :string, default: nil, aliases: '-s', desc: 'Suffix to append to index name' option :type, type: :string, default: nil, aliases: '-t', desc: 'Document Type to update mapping for' + option :settings, type: :hash, default: nil, desc: 'List of settings to pass to the index class. Example: --settings=index.refresh_interval:-1,index.number_of_replicas:0' def update_settings(*index_classes) require_relative 'index/update_settings' - UpdateSettings.new(indices: index_classes, **options.to_h.transform_keys(&:to_sym)).run + opts = HashUtils.deep_transform_keys(options.to_h, &:to_sym) + UpdateSettings.new(indices: index_classes, **opts).run end desc 'update_mapping *INDEX_CLASS', 'Create or update a mapping' @@ -89,8 +95,8 @@ def open(*index_classes) option :suffix, type: :string, default: nil, aliases: '-s', desc: 'Suffix to append to index name' option :context, type: :hash, default: {}, required: true, desc: 'List of options to pass to the index class' option :repo, type: :string, default: nil, alias: '-r', desc: 'Repository to use for import' - option :eager_include_document_attributes, type: :string, default: nil, desc: 'Comma separated list of lazy document attributes to include to the bulk index request' - option :lazy_update_document_attributes, type: :string, default: nil, desc: 'Comma separated list of lazy document attributes to bulk update after the bulk index request' + option :eager_include_document_attributes, type: :string, default: nil, desc: 'Comma separated list of lazy document attributes to include to the bulk index request. Or pass `true` to include all lazy attributes' + option :lazy_update_document_attributes, type: :string, default: nil, desc: 'Comma separated list of lazy document attributes to bulk update after the bulk index request Or pass `true` to include all lazy attributes' def import(*index_classes) require_relative 'index/import' opts = HashUtils.deep_transform_keys(options.to_h, &:to_sym) diff --git a/lib/esse/cli/templates/config.rb.erb b/lib/esse/cli/templates/config.rb.erb index a0907b1..9adbdaf 100644 --- a/lib/esse/cli/templates/config.rb.erb +++ b/lib/esse/cli/templates/config.rb.erb @@ -13,8 +13,10 @@ Esse.configure do |config| # Global index settings # cluster.settings = { - # number_of_shards: 5, - # number_of_replicas: 0, + # index: { + # number_of_shards: 5, + # number_of_replicas: 0, + # } # } # Global index mappings diff --git a/lib/esse/config.rb b/lib/esse/config.rb index 2aab3bf..214243b 100644 --- a/lib/esse/config.rb +++ b/lib/esse/config.rb @@ -10,8 +10,11 @@ module Esse # cluster.index_prefix = 'backend' # cluster.client = Elasticsearch::Client.new # cluster.settings = { - # number_of_shards: 2, - # number_of_replicas: 0 + # index: { + # number_of_shards: 2, + # number_of_replicas: 1 + # }, + # analysis: { ... } # } # cluster.mappings = { # dynamic_templates: [...] diff --git a/lib/esse/index/indices.rb b/lib/esse/index/indices.rb index 7512691..2b9fa09 100644 --- a/lib/esse/index/indices.rb +++ b/lib/esse/index/indices.rb @@ -26,10 +26,10 @@ module ClassMethods # # @see http://www.elasticsearch.org/blog/changing-mapping-with-zero-downtime/ # @see Esse::Transport#create_index - def create_index(suffix: nil, body: nil, **options) + def create_index(suffix: nil, body: nil, settings: nil, **options) options = CREATE_INDEX_RESERVED_KEYWORDS.merge(options) name = build_real_index_name(suffix) - definition = body || [settings_hash, mappings_hash].reduce(&:merge) + definition = body || [settings_hash(settings: settings), mappings_hash].reduce(&:merge) if options.delete(:alias) && name != index_name definition[:aliases] = { index_name => {} } @@ -48,21 +48,21 @@ def create_index(suffix: nil, body: nil, **options) # @return [Hash] the elasticsearch response # # @see https://www.elastic.co/guide/en/elasticsearch/reference/master/indices-open-close.html - def reset_index(suffix: index_suffix, optimize: true, import: true, reindex: false, **options) + def reset_index(suffix: index_suffix, settings: nil, optimize: true, import: true, reindex: false, **options) cluster.throw_error_when_readonly! suffix ||= Esse.timestamp suffix = Esse.timestamp while index_exist?(suffix: suffix) if optimize && import - definition = [settings_hash, mappings_hash].reduce(&:merge) + definition = [settings_hash(settings: settings), mappings_hash].reduce(&:merge) number_of_replicas = definition.dig(Esse::SETTING_ROOT_KEY, :index, :number_of_replicas) refresh_interval = definition.dig(Esse::SETTING_ROOT_KEY, :index, :refresh_interval) new_number_of_replicas = ((definition[Esse::SETTING_ROOT_KEY] ||= {})[:index] ||= {})[:number_of_replicas] = 0 new_refresh_interval = ((definition[Esse::SETTING_ROOT_KEY] ||= {})[:index] ||= {})[:refresh_interval] = '-1' create_index(**options, suffix: suffix, alias: false, body: definition) else - create_index(**options, suffix: suffix, alias: false) + create_index(**options, suffix: suffix, alias: false, settings: settings) end if index_exist? && aliases.none? @@ -75,7 +75,7 @@ def reset_index(suffix: index_suffix, optimize: true, import: true, reindex: fal end if optimize && import && number_of_replicas != new_number_of_replicas || refresh_interval != new_refresh_interval - update_settings(suffix: suffix) + update_settings(suffix: suffix, settings: settings) refresh(suffix: suffix) end @@ -152,16 +152,17 @@ def update_mapping(suffix: nil, **options) # # @param :suffix [String, nil] :suffix The index suffix # @see Esse::Transport#update_settings - def update_settings(suffix: nil, **options) + def update_settings(suffix: nil, settings: nil, **options) response = nil - settings = HashUtils.deep_transform_keys(settings_hash.fetch(Esse::SETTING_ROOT_KEY), &:to_s) + settings = HashUtils.deep_transform_keys(settings_hash(settings: settings).fetch(Esse::SETTING_ROOT_KEY), &:to_sym) if options[:body] - settings = settings.merge(HashUtils.deep_transform_keys(options.delete(:body), &:to_s)) + body = HashUtils.deep_transform_keys(options.delete(:body), &:to_sym) + settings = HashUtils.deep_merge(settings, body) end - settings.delete('number_of_shards') # Can't change number of shards for an index - settings['index']&.delete('number_of_shards') - analysis = settings.delete('analysis') + settings.delete(:number_of_shards) # Can't change number of shards for an index + settings[:index]&.delete(:number_of_shards) + analysis = settings.delete(:analysis) if settings.any? response = cluster.api.update_settings(index: index_name(suffix: suffix), body: settings, **options) diff --git a/lib/esse/index/settings.rb b/lib/esse/index/settings.rb index 29f9890..94a4464 100644 --- a/lib/esse/index/settings.rb +++ b/lib/esse/index/settings.rb @@ -4,9 +4,28 @@ module Esse # https://github.com/elastic/elasticsearch-ruby/blob/master/elasticsearch-api/lib/elasticsearch/api/actions/indices/put_settings.rb class Index module ClassMethods - def settings_hash + # Elasticsearch supports passing index.* related settings directly in the body of the request. + # We are moving it to the index key to make it more explicit and to be the source-of-truth when merging settings. + # So the settings `{ number_of_shards: 1 }` will be transformed to `{ index: { number_of_shards: 1 } }` + INDEX_SIMPLIFIED_SETTINGS = %i[ + number_of_shards + number_of_replicas + refresh_interval + ].freeze + + def settings_hash(settings: nil) hash = setting.body - { Esse::SETTING_ROOT_KEY => (hash.key?(Esse::SETTING_ROOT_KEY) ? hash[Esse::SETTING_ROOT_KEY] : hash) } + values = (hash.key?(Esse::SETTING_ROOT_KEY) ? hash[Esse::SETTING_ROOT_KEY] : hash) + values = HashUtils.explode_keys(values) + if settings.is_a?(Hash) + values = HashUtils.deep_merge(values, HashUtils.explode_keys(settings)) + end + INDEX_SIMPLIFIED_SETTINGS.each do |key| + next unless values.key?(key) + + (values[:index] ||= {}).merge!(key => values.delete(key)) + end + { Esse::SETTING_ROOT_KEY => values } end # Define /_settings definition by each index. @@ -18,7 +37,7 @@ def settings_hash # # class UserIndex < Esse::Index # settings { - # number_of_replicas: 4, + # index: { number_of_replicas: 4 } # } # end # diff --git a/lib/esse/primitives/hash_utils.rb b/lib/esse/primitives/hash_utils.rb index 42ac4ea..1e92128 100644 --- a/lib/esse/primitives/hash_utils.rb +++ b/lib/esse/primitives/hash_utils.rb @@ -47,5 +47,15 @@ def deep_merge!(target, source) end end end + + def explode_keys(hash, separator = '.') + hash.each_with_object({}) do |(key, value), result| + is_symbol = key.is_a?(Symbol) + keys = key.to_s.split(separator) + last_key = keys.pop + current = keys.reduce(result) { |memo, k| memo[is_symbol ? k.to_sym : k] ||= {} } + current[is_symbol ? last_key.to_sym : last_key] = value + end + end end end diff --git a/spec/esse/cli/index/create_spec.rb b/spec/esse/cli/index/create_spec.rb index 2cd3987..fb6d9cc 100644 --- a/spec/esse/cli/index/create_spec.rb +++ b/spec/esse/cli/index/create_spec.rb @@ -49,6 +49,11 @@ expect(CitiesIndex).to receive(:create_index).with(alias: false).and_return(true) cli_exec(%w[index create CountiesIndex CitiesIndex]) end + + it 'allows to pass --settings as a hash with imploded values' do + expect(CountiesIndex).to receive(:create_index).with(alias: false, settings: { 'index.refresh_interval': '1s' }).and_return(true) + cli_exec(%w[index create CountiesIndex --settings=index.refresh_interval:1s]) + end end end end diff --git a/spec/esse/cli/index/reset_spec.rb b/spec/esse/cli/index/reset_spec.rb index 09d9030..172fffe 100644 --- a/spec/esse/cli/index/reset_spec.rb +++ b/spec/esse/cli/index/reset_spec.rb @@ -55,6 +55,11 @@ expect(CountiesIndex).to receive(:reset_index).with(import: true, optimize: false).and_return(true) cli_exec(%w[index reset CountiesIndex --no-optimize]) end + + it 'allows to pass --settings as a hash with imploded values' do + expect(CountiesIndex).to receive(:reset_index).with(import: true, optimize: true, settings: { 'index.refresh_interval': '-1' }).and_return(true) + cli_exec(%w[index reset CountiesIndex --settings=index.refresh_interval:-1]) + end end end end diff --git a/spec/esse/cli/index/update_settings_spec.rb b/spec/esse/cli/index/update_settings_spec.rb index db578ef..9085d0a 100644 --- a/spec/esse/cli/index/update_settings_spec.rb +++ b/spec/esse/cli/index/update_settings_spec.rb @@ -44,6 +44,11 @@ expect(CitiesIndex).to receive(:update_settings).and_return(true) cli_exec(%w[index update_settings CountiesIndex CitiesIndex]) end + + it 'allows to pass --settings as a hash with imploded values' do + expect(CountiesIndex).to receive(:update_settings).with(settings: { 'index.refresh_interval': '1s' }).and_return(true) + cli_exec(%w[index update_settings CountiesIndex --settings=index.refresh_interval:1s]) + end end end end diff --git a/spec/esse/index/settings_spec.rb b/spec/esse/index/settings_spec.rb index 2434874..aed6561 100644 --- a/spec/esse/index/settings_spec.rb +++ b/spec/esse/index/settings_spec.rb @@ -20,18 +20,18 @@ context 'with a hash definition' do before do - stub_index(:events) { settings(number_of_replicas: 4) } + stub_index(:events) { settings(index: { number_of_replicas: 4 }) } end - specify do + it 'returns the settings hash form index settings' do with_cluster_config(settings: {}) do - expect(subject).to eq(number_of_replicas: 4) + expect(subject).to eq(index: { number_of_replicas: 4 }) end end - specify do - with_cluster_config(settings: { number_of_replicas: 3, refresh_interval: '1s' }) do - expect(subject).to eq(number_of_replicas: 4, refresh_interval: '1s') + it 'merges the settings with the cluster settings' do + with_cluster_config(settings: { index: { number_of_replicas: 3, refresh_interval: '1s' } }) do + expect(subject).to eq(index: { number_of_replicas: 4, refresh_interval: '1s' }) end end end @@ -40,57 +40,121 @@ before do stub_index(:events) do settings do - { number_of_replicas: '4'.to_i } + { index: { number_of_replicas: '4'.to_i } } end end end - specify do - expect(subject).to eq(number_of_replicas: 4) + it 'returns the settings hash form index settings' do + expect(subject).to eq(index: { number_of_replicas: 4 }) end - specify do - with_cluster_config(settings: { number_of_replicas: 3, refresh_interval: '1s' }) do - expect(subject).to eq(number_of_replicas: 4, refresh_interval: '1s') + it 'merges the settings with the cluster settings' do + with_cluster_config(settings: { index: { number_of_replicas: 3, refresh_interval: '1s' } }) do + expect(subject).to eq(index: { number_of_replicas: 4, refresh_interval: '1s' }) end end end end describe '.settings_hash' do - context 'without the settings node' do + context 'with imploded settings' do + before do + stub_index(:geos) do + settings do + { 'index.number_of_replicas' => '4'.to_i } + end + end + end + + it 'explodes the settings' do + expect(GeosIndex.settings_hash).to eq( + settings: { index: { number_of_replicas: 4 } }, + ) + end + end + + context 'with simplified settings' do + before do + stub_index(:geos) do + settings do + { + number_of_shards: 1, + number_of_replicas: 4, + refresh_interval: '1s', + } + end + end + end + + it 'moves the simplified settings to the :index key' do + expect(GeosIndex.settings_hash).to eq( + settings: { index: { + number_of_shards: 1, + number_of_replicas: 4, + refresh_interval: '1s' + } }, + ) + end + end + + context 'without the settings root key' do before do stub_index(:geos) do settings do - { 'number_of_replicas' => '4'.to_i } + { 'index' => { 'number_of_replicas' => '4'.to_i } } end end end specify do expect(GeosIndex.settings_hash).to eq( - settings: { number_of_replicas: 4 }, + settings: { index: { number_of_replicas: 4 } }, ) end specify do - with_cluster_config(settings: { refresh_interval: '1s', number_of_replicas: 2 }) do + with_cluster_config(settings: { index: { refresh_interval: '1s', number_of_replicas: 2 } }) do expect(GeosIndex.settings_hash).to eq( settings: { - refresh_interval: '1s', - number_of_replicas: 4, + index: { + refresh_interval: '1s', + number_of_replicas: 4, + } }, ) end end + + it 'merges the given settings with the index settings' do + expect(GeosIndex.settings_hash(settings: { index: { refresh_interval: '-1' } })).to eq( + settings: { + index: { + refresh_interval: '-1', + number_of_replicas: 4, + } + } + ) + end + + it 'merges the given imploded settings with the index settings' do + expect(GeosIndex.settings_hash(settings: { 'index.refresh_interval': '-1' })).to eq( + settings: { + index: { + refresh_interval: '-1', + number_of_replicas: 4, + } + } + ) + end end - context 'with the settings node' do + context 'with the settings root key' do before do stub_index(:geos) do settings do { - 'settings' => { 'number_of_replicas' => '6'.to_i }, + 'settings' => { 'index' => { 'number_of_replicas' => '6'.to_i } }, } end end @@ -98,7 +162,7 @@ specify do expect(GeosIndex.settings_hash).to eq( - settings: { number_of_replicas: 6 }, + settings: { index: { number_of_replicas: 6 } }, ) end end diff --git a/spec/esse/integrations/elasticsearch-1/index/create_index_spec.rb b/spec/esse/integrations/elasticsearch-1/index/create_index_spec.rb index f1aba09..080c9d5 100644 --- a/spec/esse/integrations/elasticsearch-1/index/create_index_spec.rb +++ b/spec/esse/integrations/elasticsearch-1/index/create_index_spec.rb @@ -11,8 +11,10 @@ stub_index(:dummies) do settings do { - number_of_shards: 1, - number_of_replicas: 0, + index: { + number_of_shards: 1, + number_of_replicas: 0, + } } end mappings do diff --git a/spec/esse/integrations/elasticsearch-1/transport/update_mapping_spec.rb b/spec/esse/integrations/elasticsearch-1/transport/update_mapping_spec.rb index 489fcad..037ef19 100644 --- a/spec/esse/integrations/elasticsearch-1/transport/update_mapping_spec.rb +++ b/spec/esse/integrations/elasticsearch-1/transport/update_mapping_spec.rb @@ -15,7 +15,7 @@ es_client do |client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_v1" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) expect { diff --git a/spec/esse/integrations/elasticsearch-2/index/create_index_spec.rb b/spec/esse/integrations/elasticsearch-2/index/create_index_spec.rb index c818332..5b970aa 100644 --- a/spec/esse/integrations/elasticsearch-2/index/create_index_spec.rb +++ b/spec/esse/integrations/elasticsearch-2/index/create_index_spec.rb @@ -11,8 +11,10 @@ stub_index(:dummies) do settings do { - number_of_shards: 1, - number_of_replicas: 0, + index: { + number_of_shards: 1, + number_of_replicas: 0, + } } end mappings do diff --git a/spec/esse/integrations/elasticsearch-2/transport/update_mapping_spec.rb b/spec/esse/integrations/elasticsearch-2/transport/update_mapping_spec.rb index 5cafe73..496d5c2 100644 --- a/spec/esse/integrations/elasticsearch-2/transport/update_mapping_spec.rb +++ b/spec/esse/integrations/elasticsearch-2/transport/update_mapping_spec.rb @@ -15,7 +15,7 @@ es_client do |client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_v1" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) cluster.api.refresh(index: index_name) diff --git a/spec/esse/integrations/elasticsearch-5/index/create_index_spec.rb b/spec/esse/integrations/elasticsearch-5/index/create_index_spec.rb index b9a2085..3a1d033 100644 --- a/spec/esse/integrations/elasticsearch-5/index/create_index_spec.rb +++ b/spec/esse/integrations/elasticsearch-5/index/create_index_spec.rb @@ -11,8 +11,10 @@ stub_index(:dummies) do settings do { - number_of_shards: 1, - number_of_replicas: 0, + index: { + number_of_shards: 1, + number_of_replicas: 0, + } } end mappings do diff --git a/spec/esse/integrations/elasticsearch-5/transport/update_mapping_spec.rb b/spec/esse/integrations/elasticsearch-5/transport/update_mapping_spec.rb index 0712546..2c595e5 100644 --- a/spec/esse/integrations/elasticsearch-5/transport/update_mapping_spec.rb +++ b/spec/esse/integrations/elasticsearch-5/transport/update_mapping_spec.rb @@ -15,7 +15,7 @@ es_client do |client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_v1" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) expect { diff --git a/spec/esse/integrations/elasticsearch-6/index/create_index_spec.rb b/spec/esse/integrations/elasticsearch-6/index/create_index_spec.rb index 0a9024d..0b78df9 100644 --- a/spec/esse/integrations/elasticsearch-6/index/create_index_spec.rb +++ b/spec/esse/integrations/elasticsearch-6/index/create_index_spec.rb @@ -11,8 +11,10 @@ stub_index(:dummies) do settings do { - number_of_shards: 1, - number_of_replicas: 0, + index: { + number_of_shards: 1, + number_of_replicas: 0, + } } end mappings do diff --git a/spec/esse/integrations/elasticsearch-6/transport/update_mapping_spec.rb b/spec/esse/integrations/elasticsearch-6/transport/update_mapping_spec.rb index de39809..9f3eec5 100644 --- a/spec/esse/integrations/elasticsearch-6/transport/update_mapping_spec.rb +++ b/spec/esse/integrations/elasticsearch-6/transport/update_mapping_spec.rb @@ -15,7 +15,7 @@ es_client do |client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_v1" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) expect { diff --git a/spec/esse/integrations/elasticsearch-7/index/create_index_spec.rb b/spec/esse/integrations/elasticsearch-7/index/create_index_spec.rb index 20124c1..5740c78 100644 --- a/spec/esse/integrations/elasticsearch-7/index/create_index_spec.rb +++ b/spec/esse/integrations/elasticsearch-7/index/create_index_spec.rb @@ -11,8 +11,10 @@ stub_index(:dummies) do settings do { - number_of_shards: 1, - number_of_replicas: 0 + index: { + number_of_shards: 1, + number_of_replicas: 0 + } } end mappings do diff --git a/spec/esse/integrations/elasticsearch-8/transport/create_index_spec.rb b/spec/esse/integrations/elasticsearch-8/transport/create_index_spec.rb index c9f9387..97eb1b2 100644 --- a/spec/esse/integrations/elasticsearch-8/transport/create_index_spec.rb +++ b/spec/esse/integrations/elasticsearch-8/transport/create_index_spec.rb @@ -11,8 +11,10 @@ stub_index(:dummies) do settings do { - number_of_shards: 1, - number_of_replicas: 0 + index: { + number_of_shards: 1, + number_of_replicas: 0 + } } end mappings do diff --git a/spec/esse/primitives/hash_utils_spec.rb b/spec/esse/primitives/hash_utils_spec.rb index 568201b..e1d9f37 100644 --- a/spec/esse/primitives/hash_utils_spec.rb +++ b/spec/esse/primitives/hash_utils_spec.rb @@ -8,4 +8,28 @@ expect(described_class.deep_transform_keys({'a' => {'b' => 'c'}}, &:to_sym)).to eq(a: {b: 'c'}) end end + + describe '#deep_merge' do + specify do + expect(described_class.deep_merge({a: {b: 'c'}}, {a: {d: 'e'}})).to eq(a: {b: 'c', d: 'e'}) + end + end + + describe '#deep_merge!' do + specify do + hash = {a: {b: 'c'}} + described_class.deep_merge!(hash, {a: {d: 'e'}}) + expect(hash).to eq(a: {b: 'c', d: 'e'}) + end + end + + describe '#explode_keys' do + specify do + expect(described_class.explode_keys({'a.b' => 'c'})).to eq('a' => {'b' => 'c'}) + end + + specify do + expect(described_class.explode_keys({'a.b.c': 'd'})).to eq(a: {b: {c: 'd'}}) + end + end end diff --git a/spec/fixtures/config/esse_with_clusters.yml b/spec/fixtures/config/esse_with_clusters.yml index ce4f3d1..6a58ae6 100644 --- a/spec/fixtures/config/esse_with_clusters.yml +++ b/spec/fixtures/config/esse_with_clusters.yml @@ -4,10 +4,12 @@ clusters: v1: index_prefix: esse_test_v1 settings: - number_of_shards: 1 - number_of_replicas: 1 + index: + number_of_shards: 5 + number_of_replicas: 1 v2: index_prefix: esse_test_v2 settings: - number_of_shards: 2 - number_of_replicas: 2 + index: + number_of_shards: 3 + number_of_replicas: 1 diff --git a/spec/support/config_helpers.rb b/spec/support/config_helpers.rb index e893fc5..67e9ab3 100644 --- a/spec/support/config_helpers.rb +++ b/spec/support/config_helpers.rb @@ -8,8 +8,10 @@ module ConfigHelpers client: { url: ENV.fetch('ESSE_URL', ENV.fetch('ELASTICSEARCH_URL', 'http://localhost:9200')) }, index_prefix: 'esse_test', settings: { - number_of_shards: 1, - number_of_replicas: 0, + index: { + number_of_shards: 1, + number_of_replicas: 0, + } }, mappings: {}, readonly: false, diff --git a/spec/support/shared_examples/index_create_index.rb b/spec/support/shared_examples/index_create_index.rb index ea9d87a..afeac4e 100644 --- a/spec/support/shared_examples/index_create_index.rb +++ b/spec/support/shared_examples/index_create_index.rb @@ -51,7 +51,7 @@ it 'uses the settings_hash and settings_hash as default definition' do es_client do |client, _conf, cluster| - expect(GeosIndex).to receive(:settings_hash).and_return({ settings: { number_of_shards: 1 } }) + expect(GeosIndex).to receive(:settings_hash).and_return({ settings: { index: { number_of_shards: 1 } } }) expect(GeosIndex).to receive(:mappings_hash).and_return({ mappings: { } }) allow(Esse).to receive(:timestamp).and_return('20220101') @@ -59,7 +59,7 @@ allow(cluster).to receive(:api).and_return(api) expect(api).to receive(:create_index).with( index: GeosIndex.index_name(suffix: '20220101'), - body: { aliases: { GeosIndex.index_name => {} }, settings: { number_of_shards: 1 }, mappings: { } }, + body: { aliases: { GeosIndex.index_name => {} }, settings: { index: { number_of_shards: 1 } }, mappings: { } }, ).and_call_original expect { diff --git a/spec/support/shared_examples/index_delete_index.rb b/spec/support/shared_examples/index_delete_index.rb index 28dda09..cbfa508 100644 --- a/spec/support/shared_examples/index_delete_index.rb +++ b/spec/support/shared_examples/index_delete_index.rb @@ -53,7 +53,7 @@ it 'deletes the index created with root naming' do es_client do |client, _conf, cluster| cluster.api.create_index(index: VenuesIndex.index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) resp = nil diff --git a/spec/support/shared_examples/transport_aliases.rb b/spec/support/shared_examples/transport_aliases.rb index cfa5f1c..a007af9 100644 --- a/spec/support/shared_examples/transport_aliases.rb +++ b/spec/support/shared_examples/transport_aliases.rb @@ -5,7 +5,7 @@ es_client do |client, _conf, cluster| cluster.api.create_index(index: "#{cluster.index_prefix}_dummies_v1", body: { aliases: { "#{cluster.index_prefix}_dummies" => {} }, - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) expect(cluster.api.aliases(index: "#{cluster.index_prefix}_dummies", name: '*')).to eq( @@ -18,7 +18,7 @@ es_client do |client, _conf, cluster| cluster.api.create_index(index: "#{cluster.index_prefix}_dummies_v1", body: { aliases: { "#{cluster.index_prefix}_dummies" => {} }, - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) cluster.readonly = true diff --git a/spec/support/shared_examples/transport_close.rb b/spec/support/shared_examples/transport_close.rb index 81ae168..da58e20 100644 --- a/spec/support/shared_examples/transport_close.rb +++ b/spec/support/shared_examples/transport_close.rb @@ -26,7 +26,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{index_suffix}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) cluster.wait_for_status!(index: index_name) diff --git a/spec/support/shared_examples/transport_create_index.rb b/spec/support/shared_examples/transport_create_index.rb index dc0629f..8e3a468 100644 --- a/spec/support/shared_examples/transport_create_index.rb +++ b/spec/support/shared_examples/transport_create_index.rb @@ -4,8 +4,10 @@ let(:body) do { settings: { - number_of_shards: 1, - number_of_replicas: 0 + index: { + number_of_shards: 1, + number_of_replicas: 0 + } } } end diff --git a/spec/support/shared_examples/transport_delete_index.rb b/spec/support/shared_examples/transport_delete_index.rb index c813386..3b260f5 100644 --- a/spec/support/shared_examples/transport_delete_index.rb +++ b/spec/support/shared_examples/transport_delete_index.rb @@ -24,7 +24,7 @@ es_client do |client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_v1" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) resp = nil diff --git a/spec/support/shared_examples/transport_documents_bulk.rb b/spec/support/shared_examples/transport_documents_bulk.rb index 954aa99..4fe1379 100644 --- a/spec/support/shared_examples/transport_documents_bulk.rb +++ b/spec/support/shared_examples/transport_documents_bulk.rb @@ -18,7 +18,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{index_suffix}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) payload = <<~PAYLOAD @@ -44,7 +44,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{index_suffix}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) payload = [ @@ -70,7 +70,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{index_suffix}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) payload = [ diff --git a/spec/support/shared_examples/transport_documents_count.rb b/spec/support/shared_examples/transport_documents_count.rb index 82fde0c..e572fc4 100644 --- a/spec/support/shared_examples/transport_documents_count.rb +++ b/spec/support/shared_examples/transport_documents_count.rb @@ -10,7 +10,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{index_suffix}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) cluster.api.index(index: index_name, id: 1, body: { name: 'Illinois', pk: 1 }, refresh: true, **params) @@ -26,7 +26,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{index_suffix}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) cluster.readonly = true diff --git a/spec/support/shared_examples/transport_documents_delete.rb b/spec/support/shared_examples/transport_documents_delete.rb index 74194f7..24f2274 100644 --- a/spec/support/shared_examples/transport_documents_delete.rb +++ b/spec/support/shared_examples/transport_documents_delete.rb @@ -21,7 +21,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{index_suffix}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) cluster.api.index(index: index_name, id: 1, body: { name: 'Illinois', pk: 1 }, **params) @@ -38,7 +38,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{index_suffix}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) expect { diff --git a/spec/support/shared_examples/transport_documents_exist.rb b/spec/support/shared_examples/transport_documents_exist.rb index aa201ab..ff8fcd6 100644 --- a/spec/support/shared_examples/transport_documents_exist.rb +++ b/spec/support/shared_examples/transport_documents_exist.rb @@ -10,7 +10,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{index_suffix}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) cluster.api.index(index: index_name, id: 1, body: { name: 'Illinois', pk: 1 }, refresh: true, **params) @@ -26,7 +26,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{index_suffix}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) cluster.api.refresh(index: index_name) diff --git a/spec/support/shared_examples/transport_documents_get.rb b/spec/support/shared_examples/transport_documents_get.rb index 0ab1d56..03d1df7 100644 --- a/spec/support/shared_examples/transport_documents_get.rb +++ b/spec/support/shared_examples/transport_documents_get.rb @@ -10,7 +10,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{index_suffix}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) cluster.api.index(index: index_name, id: 1, body: { name: 'Illinois', pk: 1 }, refresh: true, **params) @@ -39,7 +39,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{index_suffix}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) cluster.api.index(index: index_name, id: 1, body: { name: 'Illinois', pk: 1 }, refresh: true, **params) diff --git a/spec/support/shared_examples/transport_documents_index.rb b/spec/support/shared_examples/transport_documents_index.rb index 5251c8e..e3a77f7 100644 --- a/spec/support/shared_examples/transport_documents_index.rb +++ b/spec/support/shared_examples/transport_documents_index.rb @@ -20,7 +20,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{SecureRandom.hex(8)}}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) resp = nil expect { diff --git a/spec/support/shared_examples/transport_documents_update.rb b/spec/support/shared_examples/transport_documents_update.rb index 652ee40..17b41aa 100644 --- a/spec/support/shared_examples/transport_documents_update.rb +++ b/spec/support/shared_examples/transport_documents_update.rb @@ -25,7 +25,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{SecureRandom.hex(8)}}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) cluster.api.index(index: index_name, id: 1, body: { name: 'Illinois', pk: 1 }, refresh: true, **params) @@ -43,7 +43,7 @@ es_client do |_client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{SecureRandom.hex(8)}}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) expect { diff --git a/spec/support/shared_examples/transport_open.rb b/spec/support/shared_examples/transport_open.rb index 36d0767..cdaac0c 100644 --- a/spec/support/shared_examples/transport_open.rb +++ b/spec/support/shared_examples/transport_open.rb @@ -26,7 +26,7 @@ es_client do |client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_#{index_suffix}" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) cluster.wait_for_status!(index: index_name) if %w[1.x 2.x].include?(example.metadata[:es_version]) diff --git a/spec/support/shared_examples/transport_refresh.rb b/spec/support/shared_examples/transport_refresh.rb index a580074..dbea2f3 100644 --- a/spec/support/shared_examples/transport_refresh.rb +++ b/spec/support/shared_examples/transport_refresh.rb @@ -24,7 +24,7 @@ es_client do |client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_v1" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) resp = nil diff --git a/spec/support/shared_examples/transport_update_aliases.rb b/spec/support/shared_examples/transport_update_aliases.rb index fb88c85..d904d06 100644 --- a/spec/support/shared_examples/transport_update_aliases.rb +++ b/spec/support/shared_examples/transport_update_aliases.rb @@ -23,7 +23,7 @@ it 'adds an alias to an index' do es_client do |client, _conf, cluster| cluster.api.create_index(index: "#{cluster.index_prefix}_dummies_v1", body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) expect { @@ -42,10 +42,10 @@ es_client do |client, _conf, cluster| cluster.api.create_index(index: "#{cluster.index_prefix}_dummies_v1", body: { aliases: { "#{cluster.index_prefix}_dummies" => {} }, - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) cluster.api.create_index(index: "#{cluster.index_prefix}_dummies_v2", body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) expect { diff --git a/spec/support/shared_examples/transport_update_mapping.rb b/spec/support/shared_examples/transport_update_mapping.rb index 14f7b81..fa09808 100644 --- a/spec/support/shared_examples/transport_update_mapping.rb +++ b/spec/support/shared_examples/transport_update_mapping.rb @@ -24,7 +24,7 @@ es_client do |client, _conf, cluster| index_name = "#{cluster.index_prefix}_dummies_v1" cluster.api.create_index(index: index_name, body: { - settings: { number_of_shards: 1, number_of_replicas: 0 }, + settings: { index: { number_of_shards: 1, number_of_replicas: 0 } }, }) expect {