esse 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/exec/esse +2 -0
  3. data/lib/esse/cli/event_listener.rb +4 -5
  4. data/lib/esse/cli/extensions_loader.rb +22 -0
  5. data/lib/esse/cli/generate.rb +14 -16
  6. data/lib/esse/cli/index/close.rb +1 -1
  7. data/lib/esse/cli/index/create.rb +1 -1
  8. data/lib/esse/cli/index/delete.rb +1 -1
  9. data/lib/esse/cli/index/import.rb +2 -2
  10. data/lib/esse/cli/index/open.rb +1 -1
  11. data/lib/esse/cli/index/reset.rb +1 -1
  12. data/lib/esse/cli/index/update_aliases.rb +2 -2
  13. data/lib/esse/cli/index/update_mapping.rb +8 -3
  14. data/lib/esse/cli/index/update_settings.rb +1 -1
  15. data/lib/esse/cli/index.rb +9 -4
  16. data/lib/esse/cli/templates/collection.rb.erb +6 -6
  17. data/lib/esse/cli/templates/{serializer.rb.erb → document.rb.erb} +6 -6
  18. data/lib/esse/cli/templates/index.rb.erb +39 -34
  19. data/lib/esse/cli.rb +6 -0
  20. data/lib/esse/cluster.rb +44 -12
  21. data/lib/esse/core.rb +7 -3
  22. data/lib/esse/deprecations/cluster.rb +5 -5
  23. data/lib/esse/deprecations/deprecate.rb +29 -0
  24. data/lib/esse/deprecations/index.rb +21 -3
  25. data/lib/esse/deprecations/index_backend_delegator.rb +217 -0
  26. data/lib/esse/deprecations/repository.rb +19 -4
  27. data/lib/esse/deprecations/repository_backend_delegator.rb +110 -0
  28. data/lib/esse/deprecations/serializer.rb +14 -0
  29. data/lib/esse/deprecations.rb +4 -0
  30. data/lib/esse/{serializer.rb → document.rb} +17 -2
  31. data/lib/esse/dynamic_template.rb +4 -0
  32. data/lib/esse/errors.rb +8 -1
  33. data/lib/esse/events.rb +13 -5
  34. data/lib/esse/hash_document.rb +1 -1
  35. data/lib/esse/import/bulk.rb +21 -11
  36. data/lib/esse/index/aliases.rb +50 -0
  37. data/lib/esse/index/attributes.rb +14 -5
  38. data/lib/esse/index/base.rb +17 -53
  39. data/lib/esse/index/documents.rb +236 -0
  40. data/lib/esse/index/indices.rb +171 -0
  41. data/lib/esse/index/object_document_mapper.rb +0 -59
  42. data/lib/esse/index/search.rb +8 -1
  43. data/lib/esse/index/type.rb +2 -3
  44. data/lib/esse/index.rb +4 -3
  45. data/lib/esse/null_document.rb +1 -1
  46. data/lib/esse/primitives/hash_utils.rb +11 -0
  47. data/lib/esse/repository/{backend.rb → documents.rb} +2 -3
  48. data/lib/esse/repository/object_document_mapper.rb +20 -20
  49. data/lib/esse/repository.rb +1 -2
  50. data/lib/esse/search/query/dsl.rb +61 -0
  51. data/lib/esse/search/query.rb +15 -17
  52. data/lib/esse/template_loader.rb +1 -1
  53. data/lib/esse/transport/aliases.rb +36 -0
  54. data/lib/esse/transport/documents.rb +199 -0
  55. data/lib/esse/transport/health.rb +30 -0
  56. data/lib/esse/transport/indices.rb +192 -0
  57. data/lib/esse/{client_proxy → transport}/search.rb +9 -5
  58. data/lib/esse/transport.rb +44 -0
  59. data/lib/esse/version.rb +1 -1
  60. metadata +30 -28
  61. data/lib/esse/backend/index/aliases.rb +0 -73
  62. data/lib/esse/backend/index/close.rb +0 -54
  63. data/lib/esse/backend/index/create.rb +0 -67
  64. data/lib/esse/backend/index/delete.rb +0 -39
  65. data/lib/esse/backend/index/documents.rb +0 -270
  66. data/lib/esse/backend/index/existance.rb +0 -22
  67. data/lib/esse/backend/index/open.rb +0 -54
  68. data/lib/esse/backend/index/refresh.rb +0 -45
  69. data/lib/esse/backend/index/reset.rb +0 -33
  70. data/lib/esse/backend/index/update.rb +0 -143
  71. data/lib/esse/backend/index.rb +0 -56
  72. data/lib/esse/backend/repository_backend.rb +0 -105
  73. data/lib/esse/client_proxy.rb +0 -32
  74. data/lib/esse/index/backend.rb +0 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a9a18ea9cc75f6e98edecd0c151fe3077dc362529dc562e380855ec651b898e
4
- data.tar.gz: 3d1a96c3ba0a088e2a88b5e7aa3c1440662877d6ab2dc3e1edbd7276fe39611e
3
+ metadata.gz: 0a099bc1faa2e68ba9683a7a578ea9138414986771c8a0487e905f6e2f83f492
4
+ data.tar.gz: ee9d1e6e77c80eaa1c69f984c8b03cdfc61176d9d38298ec0b67bce4e0d7e229
5
5
  SHA512:
6
- metadata.gz: a70c285401ed1f1d3c43ebb73970339d9c48344d1872a8f5c8391ead77c75a3aeabbc8391acd88971e8bdfcc370abafdab726884deb86d713aabe75bf553c3da
7
- data.tar.gz: 6ca5282a53d4e7b29bbe29e149fd5405c9a25a6bd561bc803969e173955f83625c33a6f5b1116280f5a327b54ad4ec5923b58844543da63c51ff029e805e64ec
6
+ metadata.gz: be3d90b078ccf2a0df311e57cb0a1d4da0726343ce0cb704b527b3d1ec663c42a4ee4d039b5d1c9776d76ca39ee9784aae225d11e9f932c9f7364f52fae1d8b7
7
+ data.tar.gz: 859626e5330adec7013b992271ccf72cb08a7c91d0cdad64447c192b712621779592ecf64d27f0a1d2d6962af0da0c03ac155850f3cc2a222e390d027baee732
data/exec/esse CHANGED
@@ -6,6 +6,8 @@ $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
6
6
  require 'esse'
7
7
  require 'esse/cli'
8
8
 
9
+ Esse::CLI::ExtensionsLoader.load!
10
+
9
11
  Esse::CLI.with_friendly_errors do
10
12
  Esse::CLI.start(ARGV)
11
13
  end
@@ -84,17 +84,16 @@ module Esse
84
84
  end
85
85
 
86
86
  def elasticsearch_bulk(event)
87
- print_message("[%<runtime>s] Bulk index %<name>s%<type>s%<wait_interval>s: ",
87
+ print_message('[%<runtime>s] Bulk index %<name>s%<type>s%<wait_interval>s: ',
88
88
  runtime: formatted_runtime(event[:runtime]),
89
89
  name: colorize(event[:request][:index], :bold),
90
90
  type: (event[:request][:type] ? " for type #{colorize(event[:request][:type], :bold)}" : ''),
91
91
  wait_interval: (event[:wait_interval].nonzero? ? " (wait interval #{event[:wait_interval]}s)" : ''),
92
- newline: false,
93
- )
94
- stats = event[:request][:body_stats].select {|_, v| v.nonzero? }.map do |type, count|
92
+ newline: false,)
93
+ stats = event[:request][:body_stats].select { |_, v| v.nonzero? }.map do |type, count|
95
94
  "#{colorize(type, :bold)}: #{count} docs"
96
95
  end
97
- print_message(stats.join(", ") + ".")
96
+ print_message(stats.join(', ') + '.')
98
97
  end
99
98
  end
100
99
  end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Esse
4
+ module CLI
5
+ class ExtensionsLoader
6
+ GEMS = %w[
7
+ esse-rails
8
+ esse-active_record
9
+ esse-sequel
10
+ esse-kaminari
11
+ ].freeze
12
+
13
+ def self.load!
14
+ GEMS.each do |gem_name|
15
+ require gem_name
16
+ rescue LoadError
17
+ # do nothing
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -16,19 +16,17 @@ module Esse
16
16
  desc 'index NAME *TYPES', 'Creates a new index'
17
17
  option :settings, type: :boolean, default: false, desc: 'Generate settings'
18
18
  option :mappings, type: :boolean, default: false, desc: 'Generate mappings'
19
- option :serializers, type: :boolean, default: false, desc: 'Generate serializers'
19
+ option :documents, type: :boolean, default: false, desc: 'Generate documents'
20
20
  option :collections, type: :boolean, default: false, desc: 'Generate collections'
21
21
  option :active_record, type: :boolean, default: false, desc: 'Generate ActiveRecord models'
22
22
  option :cluster_id, type: :string, desc: 'Elasticsearch cluster ID'
23
- def index(name, *types)
23
+ def index(name, *repos)
24
24
  ns_path = name.split(NAMESPACE_PATTERN_RE).tap(&:pop)
25
25
  @index_name = Hstring.new(name.to_s).modulize.sub(/Index$/, '') + 'Index'
26
26
  @index_name = Hstring.new(@index_name)
27
- @types = types.map { |type| Hstring.new(type) }
27
+ @repos = repos.map { |repo| Hstring.new(repo) }
28
28
  @base_class = base_index_class(*ns_path)
29
- if options[:cluster_id]
30
- @base_class += format('(:%s)', options[:cluster_id])
31
- end
29
+ @index_cluster_id = options[:cluster_id]
32
30
  @cli_options = options
33
31
 
34
32
  base_dir = Esse.config.indices_directory.join(*ns_path.map { |n| Hstring.new(n).underscore.to_s })
@@ -52,11 +50,11 @@ module Esse
52
50
  )
53
51
  end
54
52
 
55
- if @types.empty?
56
- if options[:serializers]
53
+ if @repos.empty?
54
+ if options[:documents]
57
55
  template(
58
- 'templates/serializer.rb.erb',
59
- base_dir.join(index_name, 'serializers', 'serializer.rb'),
56
+ 'templates/document.rb.erb',
57
+ base_dir.join(index_name, 'documents', 'document.rb'),
60
58
  )
61
59
  end
62
60
  if options[:collections] && !options[:active_record]
@@ -67,19 +65,19 @@ module Esse
67
65
  end
68
66
  end
69
67
 
70
- @types.each do |type|
71
- @type = Hstring.new(type).underscore
68
+ @repos.each do |type|
69
+ @repo = Hstring.new(type).underscore
72
70
 
73
- if options[:serializers]
71
+ if options[:documents]
74
72
  template(
75
- 'templates/serializer.rb.erb',
76
- base_dir.join(index_name, 'serializers', "#{@type}_serializer.rb"),
73
+ 'templates/document.rb.erb',
74
+ base_dir.join(index_name, 'documents', "#{@repo}_document.rb"),
77
75
  )
78
76
  end
79
77
  if options[:collections] && !options[:active_record]
80
78
  template(
81
79
  'templates/collection.rb.erb',
82
- base_dir.join(index_name, 'collections', "#{@type}_collection.rb"),
80
+ base_dir.join(index_name, 'collections', "#{@repo}_collection.rb"),
83
81
  )
84
82
  end
85
83
  end
@@ -8,7 +8,7 @@ module Esse
8
8
  def run
9
9
  validate_options!
10
10
  indices.each do |index|
11
- index.elasticsearch.close!(**options)
11
+ index.close(**options)
12
12
  end
13
13
  end
14
14
 
@@ -8,7 +8,7 @@ module Esse
8
8
  def run
9
9
  validate_options!
10
10
  indices.each do |index|
11
- index.elasticsearch.create_index!(**options)
11
+ index.create_index(**options)
12
12
  end
13
13
  end
14
14
 
@@ -8,7 +8,7 @@ module Esse
8
8
  def run
9
9
  validate_options!
10
10
  indices.each do |index|
11
- index.elasticsearch.delete_index!(**options)
11
+ index.delete_index(**options)
12
12
  end
13
13
  end
14
14
 
@@ -9,9 +9,9 @@ module Esse
9
9
  validate_options!
10
10
  indices.each do |index|
11
11
  if (repo = @options[:repo])
12
- index.elasticsearch.import!(repo, **options)
12
+ index.import(repo, **options)
13
13
  else
14
- index.elasticsearch.import!(**options)
14
+ index.import(**options)
15
15
  end
16
16
  end
17
17
  end
@@ -8,7 +8,7 @@ module Esse
8
8
  def run
9
9
  validate_options!
10
10
  indices.each do |index|
11
- index.elasticsearch.open!(**options)
11
+ index.open(**options)
12
12
  end
13
13
  end
14
14
 
@@ -8,7 +8,7 @@ module Esse
8
8
  def run
9
9
  validate_options!
10
10
  indices.each do |index|
11
- index.elasticsearch.reset_index!(**options)
11
+ index.reset_index(**options)
12
12
  end
13
13
  end
14
14
 
@@ -8,7 +8,7 @@ module Esse
8
8
  def run
9
9
  validate_options!
10
10
  indices.each do |index|
11
- index.elasticsearch.update_aliases!(**options)
11
+ index.update_aliases(**options)
12
12
  end
13
13
  end
14
14
 
@@ -21,7 +21,7 @@ module Esse
21
21
  def validate_options!
22
22
  validate_indices_option!
23
23
 
24
- if @options[:suffix].nil?
24
+ if @options[:suffix].nil? || @options[:suffix].empty?
25
25
  raise InvalidOption.new(<<~END)
26
26
  You must specify a suffix to update the aliases.
27
27
  END
@@ -9,11 +9,16 @@ module Esse
9
9
  validate_options!
10
10
  indices.each do |index|
11
11
  if !index.mapping_single_type?
12
- index.repo_hash.values.map(&:document_type).uniq.each do |doc_type|
13
- index.elasticsearch.update_mapping!(type: doc_type, **options)
12
+ # Elasticsearch 6.x and older have multiple types per index.
13
+ # This gem supports multiple types per index for backward compatibility, but we recommend to update
14
+ # your elasticsearch to a at least 7.x version and use a single type per index.
15
+ #
16
+ # Note that the repository name will be used as the document type.
17
+ index.repo_hash.keys.each do |doc_type|
18
+ index.update_mapping(type: doc_type, **options)
14
19
  end
15
20
  else
16
- index.elasticsearch.update_mapping!(**options)
21
+ index.update_mapping(**options)
17
22
  end
18
23
  end
19
24
  end
@@ -8,7 +8,7 @@ module Esse
8
8
  def run
9
9
  validate_options!
10
10
  indices.each do |index|
11
- index.elasticsearch.update_settings!(**options)
11
+ index.update_settings(**options)
12
12
  end
13
13
  end
14
14
 
@@ -21,12 +21,14 @@ module Esse
21
21
  Reset.new(indices: index_classes, **options.to_h.transform_keys(&:to_sym)).run
22
22
  end
23
23
 
24
+ # @TODO Add reindex task to create a new index and import documents from the old index using _reindex API
25
+
24
26
  desc 'create *INDEX_CLASSES', 'Creates indices for the given classes'
25
27
  long_desc <<-DESC
26
28
  Creates index and applies mapping and settings for the given classes.
27
29
 
28
30
  Indices are created with the following naming convention:
29
- <cluster.index_prefix>_<index_class.index_name>_<index_class.index_version>.
31
+ <cluster.index_prefix>_<index_class.index_name>_<index_class.index_suffix>.
30
32
  DESC
31
33
  option :suffix, type: :string, default: nil, aliases: '-s', desc: 'Suffix to append to index name'
32
34
  option :alias, type: :boolean, default: false, aliases: '-a', desc: 'Update alias after create index'
@@ -42,11 +44,14 @@ module Esse
42
44
  Delete.new(indices: index_classes, **options.to_h.transform_keys(&:to_sym)).run
43
45
  end
44
46
 
45
- desc 'update_aliases *INDEX_CLASS', 'Replaces all existing aliases by the given suffix'
46
- option :suffix, type: :string, aliases: '-s', desc: 'Suffix to append to index name'
47
+ desc 'update_aliases *INDEX_CLASS', 'Replaces all existing aliases by the given suffix/suffixes'
48
+ option :suffix, type: :string, aliases: '-s', repeatable: true, desc: 'Suffix to append to index name'
47
49
  def update_aliases(*index_classes)
48
50
  require_relative 'index/update_aliases'
49
- UpdateAliases.new(indices: index_classes, **options.to_h.transform_keys(&:to_sym)).run
51
+
52
+ kwargs = options.to_h.transform_keys(&:to_sym)
53
+ kwargs[:suffix] = (kwargs[:suffix] || []).flat_map { |s| s.split(',') }.uniq
54
+ UpdateAliases.new(indices: index_classes, **kwargs).run
50
55
  end
51
56
 
52
57
  desc 'update_settings *INDEX_CLASS', 'Closes the index for read/write operations, updates the index settings, and open it again'
@@ -2,10 +2,10 @@
2
2
 
3
3
  class <%= @index_name %> < <%= @base_class %>
4
4
  module Collections
5
- class <%= @type.camelize if @type %>Collection < Esse::Collection
6
- <%- if @type -%>
7
- # @yield [Array<<%= @type.camelize %>>]
8
- # @see <%= @index_name %>::<%= @type.camelize %>#collection
5
+ class <%= @repo.camelize if @repo %>Collection < Esse::Collection
6
+ <%- if @repo -%>
7
+ # @yield [Array<<%= @repo.camelize %>>]
8
+ # @see <%= @index_name %>::<%= @repo.camelize %>#collection
9
9
  <%- end -%>
10
10
  def each
11
11
  offset = 0
@@ -13,7 +13,7 @@ class <%= @index_name %> < <%= @base_class %>
13
13
  break if rows.none?
14
14
  offset += 1
15
15
  yield(rows)
16
- # You may also preload associations here or add metadata useful for the serializer
16
+ # You may also preload associations here or add metadata useful for the document
17
17
  # yield(rows, **preload_associations(rows))
18
18
  end
19
19
  end
@@ -22,7 +22,7 @@ class <%= @index_name %> < <%= @base_class %>
22
22
 
23
23
  # @param offset [Number] Offset to start from
24
24
  def find_all(offset)
25
- # @TODO load data from persistent store
25
+ # @TODO load data from persistent storage
26
26
  end
27
27
  end
28
28
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class <%= @index_name %> < <%= @base_class %>
4
- module Serializers
5
- class <%= @type.camelize if @type %>Serializer < Esse::Serializer
4
+ module Documents
5
+ class <%= @repo.camelize if @repo %>Document < Esse::Document
6
6
  <%- if @cli_options[:active_record] -%>
7
7
  delegate :id, to: :object
8
8
  <%- else -%>
@@ -14,8 +14,8 @@ class <%= @index_name %> < <%= @base_class %>
14
14
  def source
15
15
  {
16
16
  name: object.name,
17
- <%- if @type -%>
18
- type: "<%= @type %>",
17
+ <%- if @repo && defined?(Elasticsearch::VERSION) && Elasticsearch::VERSION > '5' -%>
18
+ type: "<%= @repo %>",
19
19
  <%- end -%>
20
20
  <%- if @cli_options[:active_record] -%>
21
21
  created_at: object.created_at,
@@ -23,10 +23,10 @@ class <%= @index_name %> < <%= @base_class %>
23
23
  <%- end -%>
24
24
  }
25
25
  end
26
- <%- if @type && defined?(Elasticsearch::VERSION) && Elasticsearch::VERSION <= '5' -%>
26
+ <%- if @repo && defined?(Elasticsearch::VERSION) && Elasticsearch::VERSION <= '5' -%>
27
27
 
28
28
  def type
29
- '<%= @type %>'
29
+ '<%= @repo %>'
30
30
  end
31
31
  <%- end -%>
32
32
  end
@@ -1,43 +1,49 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- <%- @types.each do |type| -%>
3
+ <%- @repos.each do |type| -%>
4
4
  require_relative '<%= @index_name.demodulize.underscore.to_s %>/collections/<%= type.underscore %>_collection'
5
5
  <%- end if @cli_options[:collections] && !@cli_options[:active_record] -%>
6
- <%- @types.each do |type| -%>
7
- require_relative '<%= @index_name.demodulize.underscore.to_s %>/serializers/<%= type.underscore %>_serializer'
8
- <%- end if @cli_options[:serializers] -%>
6
+ <%- @repos.each do |type| -%>
7
+ require_relative '<%= @index_name.demodulize.underscore.to_s %>/documents/<%= type.underscore %>_document'
8
+ <%- end if @cli_options[:documents] -%>
9
9
  class <%= @index_name %> < <%= @base_class %>
10
+ <%-if @index_cluster_id -%>
11
+ self.cluster_id = :<%= @index_cluster_id %>
12
+ <%- end -%>
10
13
  <%- if @cli_options[:active_record] -%>
11
14
  plugin :active_record
12
15
 
13
16
  <%- end -%>
14
- <%- if @types.empty? -%>
15
- <%- if @cli_options[:active_record] -%>
16
- collection ::<%= @index_name.camelize %>.all
17
- <%- elsif @cli_options[:collections] -%>
18
- collection Collections::Collection
19
- <%- else -%>
20
- collection do |**context, &block|
21
- query = <%= @index_name.camelize.sub(/Index$/, '') %>.all
22
- query = query.where(id: context[:id]) if context[:id]
23
- query.find_in_batches(batch_size: 1_000) do |batch|
24
- block.call(batch)
17
+ <%- if @repos.empty? -%>
18
+ repository :default do
19
+ <%- if @cli_options[:active_record] -%>
20
+ collection ::<%= @index_name.camelize %>.all
21
+ <%- elsif @cli_options[:collections] -%>
22
+ collection Collections::Collection
23
+ <%- else -%>
24
+ collection do |**context, &block|
25
+ query = <%= @index_name.camelize.sub(/Index$/, '') %>.all
26
+ query = query.where(id: context[:id]) if context[:id]
27
+ query.find_in_batches(batch_size: 1_000) do |batch|
28
+ block.call(batch, **context)
29
+ end
25
30
  end
31
+ <%- end -%>
32
+
33
+ <%- if @cli_options[:documents] -%>
34
+ document Documents::Document
35
+ <%- else -%>
36
+ document do |object, **_context|
37
+ {
38
+ id: object.id,
39
+ name: object.name,
40
+ }
41
+ end
42
+ <%- end # if @cli_options[:documents] -%>
26
43
  end
27
- <%- end -%>
28
- <%- if @cli_options[:serializers] -%>
29
- serializer Serializers::Serializer
30
- <%- else -%>
31
- serializer do |object, **_context|
32
- {
33
- id: object.id,
34
- name: object.name,
35
- }
36
- end
37
- <%- end # if @cli_options[:serializers] -%>
38
- <%- end # /@types.empty?-%>
44
+ <%- end # /@repos.empty?-%>
45
+ <%- @repos.each do |type| -%>
39
46
 
40
- <%- @types.each do |type| -%>
41
47
  repository :<%= type.underscore %> do
42
48
  <%- if @cli_options[:active_record] -%>
43
49
  collection ::<%= type.camelize %>.all
@@ -48,14 +54,14 @@ class <%= @index_name %> < <%= @base_class %>
48
54
  query = <%= type.camelize %>.all
49
55
  query = query.where(id: context[:id]) if context[:id]
50
56
  query.find_in_batches(batch_size: 1_000) do |batch|
51
- block.call(batch)
57
+ block.call(batch, **context)
52
58
  end
53
59
  end
54
60
  <%- end -%>
55
- <%- if @cli_options[:serializers] -%>
56
- serializer Serializers::<%= type.camelize %>Serializer
61
+ <%- if @cli_options[:documents] -%>
62
+ document Documents::<%= type.camelize %>Document
57
63
  <%- else -%>
58
- serializer do |<%= type.underscore %>, **_context|
64
+ document do |<%= type.underscore %>, **_context|
59
65
  {
60
66
  id: <%= type.underscore %>.id,
61
67
  name: <%= @index_name.underscore %>.name,
@@ -63,6 +69,5 @@ class <%= @index_name %> < <%= @base_class %>
63
69
  end
64
70
  <%- end -%>
65
71
  end
66
-
67
- <%- end #@types.each do |type| -%>
72
+ <%- end #@repos.each do |type| -%>
68
73
  end
data/lib/esse/cli.rb CHANGED
@@ -6,6 +6,7 @@ require_relative 'primitives/output'
6
6
  require_relative 'cli/index'
7
7
  require_relative 'cli/generate'
8
8
  require_relative 'cli/event_listener'
9
+ require_relative 'cli/extensions_loader'
9
10
 
10
11
  module Esse
11
12
  module CLI
@@ -32,6 +33,7 @@ module Esse
32
33
  def initialize(*)
33
34
  super
34
35
 
36
+ after_initialize
35
37
  load_app_config(options[:require])
36
38
  setup_listeners if !options[:silent] && Esse.config.cli_event_listeners?
37
39
  end
@@ -71,6 +73,10 @@ module Esse
71
73
 
72
74
  private
73
75
 
76
+ def after_initialize
77
+ # esse plugins may override this method
78
+ end
79
+
74
80
  def setup_listeners
75
81
  Esse::Events.__bus__.events.keys.grep(/^elasticsearch/).each do |event_name|
76
82
  Esse::Events.subscribe(event_name) do |event|
data/lib/esse/cluster.rb CHANGED
@@ -1,11 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'cluster_engine'
4
- require_relative 'client_proxy'
4
+ require_relative 'transport'
5
5
 
6
6
  module Esse
7
+ class << self
8
+ extend Forwardable
9
+
10
+ def_delegators :config, :cluster
11
+ end
12
+
7
13
  class Cluster
8
- ATTRIBUTES = %i[index_prefix settings mappings client wait_for_status].freeze
14
+ ATTRIBUTES = %i[index_prefix settings mappings client wait_for_status readonly].freeze
9
15
  WAIT_FOR_STATUSES = %w[green yellow red].freeze
10
16
 
11
17
  # The index prefix. For example an index named UsersIndex.
@@ -28,12 +34,17 @@ module Esse
28
34
  # wait_for_status: green
29
35
  attr_accessor :wait_for_status
30
36
 
37
+ # Disable all writes from the application to the underlying Elasticsearch instance while keeping the
38
+ # application running and handling search requests.
39
+ attr_writer :readonly
40
+
31
41
  attr_reader :id
32
42
 
33
43
  def initialize(id:, **options)
34
44
  @id = id.to_sym
35
45
  @settings = {}
36
46
  @mappings = {}
47
+ @readonly = false
37
48
  assign(options)
38
49
  end
39
50
 
@@ -61,6 +72,17 @@ module Esse
61
72
  end
62
73
  end
63
74
 
75
+ # @return [Boolean] Return true if the cluster is readonly
76
+ def readonly?
77
+ !!@readonly
78
+ end
79
+
80
+ # @raise [Esse::Transport::ReadonlyClusterError] if the cluster is readonly
81
+ # @return [void]
82
+ def throw_error_when_readonly!
83
+ raise Esse::Transport::ReadonlyClusterError if readonly?
84
+ end
85
+
64
86
  # Define the elasticsearch client connection
65
87
  # @param es_client [Elasticsearch::Client, OpenSearch::Client, Hash] an instance of elasticsearch/api client or an hash
66
88
  # with the settings that will be used to initialize the Client
@@ -77,24 +99,33 @@ module Esse
77
99
  end
78
100
 
79
101
  def inspect
80
- attrs = ([:id] + ATTRIBUTES - [:client]).map do |method|
102
+ attrs = ([:id] + ATTRIBUTES - [:client, :readonly]).map do |method|
81
103
  value = public_send(method)
82
104
  format('%<k>s=%<v>p', k: method, v: value) if value
83
105
  end.compact
106
+ attrs << 'readonly=true' if readonly?
84
107
  attrs << format('client=%p', @client)
85
108
  format('#<Esse::Cluster %<attrs>s>', attrs: attrs.join(' '))
86
109
  end
87
110
 
88
- def wait_for_status!(status: wait_for_status)
111
+ # Wait until cluster is in a specific state
112
+ #
113
+ # @option [String] :status Wait until cluster is in a specific state (options: green, yellow, red)
114
+ # @option [String] :index Limit the information returned to a specific index
115
+ def wait_for_status!(status: nil, **kwargs)
116
+ status ||= wait_for_status
89
117
  return unless WAIT_FOR_STATUSES.include?(status.to_s)
90
118
 
91
- client.cluster.health(wait_for_status: status.to_s)
119
+ api.health(**kwargs, wait_for_status: status.to_s)
92
120
  end
93
121
 
94
- # @idea Change this to use the response from `GET /`
95
- def document_type?
96
- defined?(OpenSearch::VERSION) || \
97
- (defined?(Elasticsearch::VERSION) && Elasticsearch::VERSION < '7')
122
+ # @return [void]
123
+ def may_update_type!(hash, key: :type)
124
+ if (single_type = engine.mapping_default_type)
125
+ hash[key] = single_type
126
+ return
127
+ end
128
+ hash.delete(key) if engine.mapping_single_type?
98
129
  end
99
130
 
100
131
  def info
@@ -108,8 +139,9 @@ module Esse
108
139
  end
109
140
 
110
141
  def engine
111
- ClusterEngine.new(**info)
142
+ @engine ||= ClusterEngine.new(**info)
112
143
  end
144
+ alias_method :warm_up!, :engine
113
145
 
114
146
  # Build a search query for the given indices
115
147
  #
@@ -121,9 +153,9 @@ module Esse
121
153
 
122
154
  # Return the proxy object used to perform low level actions on the elasticsearch cluster through the official api client
123
155
  #
124
- # @return [Esse::ClientProxy] The cluster api instance
156
+ # @return [Esse::Transport] The cluster api instance
125
157
  def api
126
- Esse::ClientProxy.new(self)
158
+ Esse::Transport.new(self)
127
159
  end
128
160
  end
129
161
  end
data/lib/esse/core.rb CHANGED
@@ -5,7 +5,7 @@ module Esse
5
5
  require_relative 'cluster'
6
6
  require_relative 'primitives'
7
7
  require_relative 'collection'
8
- require_relative 'serializer'
8
+ require_relative 'document'
9
9
  require_relative 'hash_document'
10
10
  require_relative 'null_document'
11
11
  require_relative 'repository'
@@ -15,8 +15,6 @@ module Esse
15
15
  require_relative 'template_loader'
16
16
  require_relative 'import/request_body'
17
17
  require_relative 'import/bulk'
18
- require_relative 'backend/index'
19
- require_relative 'backend/repository_backend'
20
18
  require_relative 'version'
21
19
  require_relative 'logging'
22
20
  require_relative 'events'
@@ -85,4 +83,10 @@ module Esse
85
83
  end
86
84
  true
87
85
  end
86
+
87
+ def self.document?(object)
88
+ return false unless object
89
+
90
+ !!(object.is_a?(Esse::Document) && object.id)
91
+ end
88
92
  end
@@ -2,26 +2,26 @@
2
2
 
3
3
  module Esse
4
4
  class Cluster
5
- extend Gem::Deprecate
5
+ extend Esse::Deprecations::Deprecate
6
6
 
7
7
  def index_settings
8
8
  settings
9
9
  end
10
- deprecate :index_settings, :settings, 2022, 10
10
+ deprecate :index_settings, :settings, 2023, 12
11
11
 
12
12
  def index_settings=(value)
13
13
  self.settings = value
14
14
  end
15
- deprecate :index_settings=, :settings=, 2022, 10
15
+ deprecate :index_settings=, :settings=, 2023, 12
16
16
 
17
17
  def index_mappings
18
18
  mappings
19
19
  end
20
- deprecate :index_mappings, :mappings, 2022, 10
20
+ deprecate :index_mappings, :mappings, 2023, 12
21
21
 
22
22
  def index_mappings=(value)
23
23
  self.mappings = value
24
24
  end
25
- deprecate :index_mappings=, :mappings=, 2022, 10
25
+ deprecate :index_mappings=, :mappings=, 2023, 12
26
26
  end
27
27
  end