esse 0.2.2 → 0.2.3

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/lib/esse/cli/event_listener.rb +4 -5
  3. data/lib/esse/cli/generate.rb +14 -16
  4. data/lib/esse/cli/index/close.rb +1 -1
  5. data/lib/esse/cli/index/create.rb +1 -1
  6. data/lib/esse/cli/index/delete.rb +1 -1
  7. data/lib/esse/cli/index/import.rb +2 -2
  8. data/lib/esse/cli/index/open.rb +1 -1
  9. data/lib/esse/cli/index/reset.rb +1 -1
  10. data/lib/esse/cli/index/update_aliases.rb +2 -2
  11. data/lib/esse/cli/index/update_mapping.rb +8 -3
  12. data/lib/esse/cli/index/update_settings.rb +1 -1
  13. data/lib/esse/cli/index.rb +9 -4
  14. data/lib/esse/cli/templates/collection.rb.erb +6 -6
  15. data/lib/esse/cli/templates/{serializer.rb.erb → document.rb.erb} +6 -6
  16. data/lib/esse/cli/templates/index.rb.erb +39 -34
  17. data/lib/esse/cli.rb +5 -0
  18. data/lib/esse/cluster.rb +38 -12
  19. data/lib/esse/core.rb +7 -3
  20. data/lib/esse/deprecations/cluster.rb +5 -5
  21. data/lib/esse/deprecations/deprecate.rb +29 -0
  22. data/lib/esse/deprecations/index.rb +21 -3
  23. data/lib/esse/deprecations/index_backend_delegator.rb +217 -0
  24. data/lib/esse/deprecations/repository.rb +19 -4
  25. data/lib/esse/deprecations/repository_backend_delegator.rb +110 -0
  26. data/lib/esse/deprecations/serializer.rb +14 -0
  27. data/lib/esse/deprecations.rb +4 -0
  28. data/lib/esse/{serializer.rb → document.rb} +17 -2
  29. data/lib/esse/dynamic_template.rb +4 -0
  30. data/lib/esse/errors.rb +8 -1
  31. data/lib/esse/events.rb +13 -5
  32. data/lib/esse/hash_document.rb +1 -1
  33. data/lib/esse/import/bulk.rb +21 -11
  34. data/lib/esse/index/aliases.rb +50 -0
  35. data/lib/esse/index/attributes.rb +14 -5
  36. data/lib/esse/index/base.rb +17 -53
  37. data/lib/esse/index/documents.rb +236 -0
  38. data/lib/esse/index/indices.rb +171 -0
  39. data/lib/esse/index/object_document_mapper.rb +0 -59
  40. data/lib/esse/index/type.rb +2 -3
  41. data/lib/esse/index.rb +4 -3
  42. data/lib/esse/null_document.rb +1 -1
  43. data/lib/esse/repository/{backend.rb → documents.rb} +2 -3
  44. data/lib/esse/repository/object_document_mapper.rb +20 -20
  45. data/lib/esse/repository.rb +1 -2
  46. data/lib/esse/search/query.rb +8 -8
  47. data/lib/esse/template_loader.rb +1 -1
  48. data/lib/esse/transport/aliases.rb +36 -0
  49. data/lib/esse/transport/documents.rb +199 -0
  50. data/lib/esse/transport/health.rb +30 -0
  51. data/lib/esse/transport/indices.rb +192 -0
  52. data/lib/esse/{client_proxy → transport}/search.rb +9 -5
  53. data/lib/esse/transport.rb +44 -0
  54. data/lib/esse/version.rb +1 -1
  55. metadata +28 -28
  56. data/lib/esse/backend/index/aliases.rb +0 -73
  57. data/lib/esse/backend/index/close.rb +0 -54
  58. data/lib/esse/backend/index/create.rb +0 -67
  59. data/lib/esse/backend/index/delete.rb +0 -39
  60. data/lib/esse/backend/index/documents.rb +0 -270
  61. data/lib/esse/backend/index/existance.rb +0 -22
  62. data/lib/esse/backend/index/open.rb +0 -54
  63. data/lib/esse/backend/index/refresh.rb +0 -45
  64. data/lib/esse/backend/index/reset.rb +0 -33
  65. data/lib/esse/backend/index/update.rb +0 -143
  66. data/lib/esse/backend/index.rb +0 -56
  67. data/lib/esse/backend/repository_backend.rb +0 -105
  68. data/lib/esse/client_proxy.rb +0 -32
  69. 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: 30ce86d71e0cf9b67506dd0caf1651b91ae836c9e7981e46a238446c8afde078
4
+ data.tar.gz: 9ec1069cbb8106743d5832f94fbce5d2c937037a62a746350e736385f3b78cdc
5
5
  SHA512:
6
- metadata.gz: a70c285401ed1f1d3c43ebb73970339d9c48344d1872a8f5c8391ead77c75a3aeabbc8391acd88971e8bdfcc370abafdab726884deb86d713aabe75bf553c3da
7
- data.tar.gz: 6ca5282a53d4e7b29bbe29e149fd5405c9a25a6bd561bc803969e173955f83625c33a6f5b1116280f5a327b54ad4ec5923b58844543da63c51ff029e805e64ec
6
+ metadata.gz: f2a5012e3d3dab0b3894f8e8fb1665be2a57c8538a3fc02bce2ac089510bd63b982f8f919554a9f16d6e8dafe5d93d9f5614d99ca4f170d82cc41e413fec0209
7
+ data.tar.gz: 034b15fd5cfc4f6ebdd97ba9d73ed284f50c209225b2c6a43b27216a57578ca1b91d9c92d4e020c4a1c7910038cf5978054bfa4b491bafb431bcfc1dcbc0a706
@@ -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
@@ -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
@@ -32,6 +32,7 @@ module Esse
32
32
  def initialize(*)
33
33
  super
34
34
 
35
+ after_initialize
35
36
  load_app_config(options[:require])
36
37
  setup_listeners if !options[:silent] && Esse.config.cli_event_listeners?
37
38
  end
@@ -71,6 +72,10 @@ module Esse
71
72
 
72
73
  private
73
74
 
75
+ def after_initialize
76
+ # esse plugins may override this method
77
+ end
78
+
74
79
  def setup_listeners
75
80
  Esse::Events.__bus__.events.keys.grep(/^elasticsearch/).each do |event_name|
76
81
  Esse::Events.subscribe(event_name) do |event|
data/lib/esse/cluster.rb CHANGED
@@ -1,11 +1,11 @@
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
7
  class Cluster
8
- ATTRIBUTES = %i[index_prefix settings mappings client wait_for_status].freeze
8
+ ATTRIBUTES = %i[index_prefix settings mappings client wait_for_status readonly].freeze
9
9
  WAIT_FOR_STATUSES = %w[green yellow red].freeze
10
10
 
11
11
  # The index prefix. For example an index named UsersIndex.
@@ -28,12 +28,17 @@ module Esse
28
28
  # wait_for_status: green
29
29
  attr_accessor :wait_for_status
30
30
 
31
+ # Disable all writes from the application to the underlying Elasticsearch instance while keeping the
32
+ # application running and handling search requests.
33
+ attr_writer :readonly
34
+
31
35
  attr_reader :id
32
36
 
33
37
  def initialize(id:, **options)
34
38
  @id = id.to_sym
35
39
  @settings = {}
36
40
  @mappings = {}
41
+ @readonly = false
37
42
  assign(options)
38
43
  end
39
44
 
@@ -61,6 +66,17 @@ module Esse
61
66
  end
62
67
  end
63
68
 
69
+ # @return [Boolean] Return true if the cluster is readonly
70
+ def readonly?
71
+ !!@readonly
72
+ end
73
+
74
+ # @raise [Esse::Transport::ReadonlyClusterError] if the cluster is readonly
75
+ # @return [void]
76
+ def throw_error_when_readonly!
77
+ raise Esse::Transport::ReadonlyClusterError if readonly?
78
+ end
79
+
64
80
  # Define the elasticsearch client connection
65
81
  # @param es_client [Elasticsearch::Client, OpenSearch::Client, Hash] an instance of elasticsearch/api client or an hash
66
82
  # with the settings that will be used to initialize the Client
@@ -77,24 +93,33 @@ module Esse
77
93
  end
78
94
 
79
95
  def inspect
80
- attrs = ([:id] + ATTRIBUTES - [:client]).map do |method|
96
+ attrs = ([:id] + ATTRIBUTES - [:client, :readonly]).map do |method|
81
97
  value = public_send(method)
82
98
  format('%<k>s=%<v>p', k: method, v: value) if value
83
99
  end.compact
100
+ attrs << 'readonly=true' if readonly?
84
101
  attrs << format('client=%p', @client)
85
102
  format('#<Esse::Cluster %<attrs>s>', attrs: attrs.join(' '))
86
103
  end
87
104
 
88
- def wait_for_status!(status: wait_for_status)
105
+ # Wait until cluster is in a specific state
106
+ #
107
+ # @option [String] :status Wait until cluster is in a specific state (options: green, yellow, red)
108
+ # @option [String] :index Limit the information returned to a specific index
109
+ def wait_for_status!(status: nil, **kwargs)
110
+ status ||= wait_for_status
89
111
  return unless WAIT_FOR_STATUSES.include?(status.to_s)
90
112
 
91
- client.cluster.health(wait_for_status: status.to_s)
113
+ api.health(**kwargs, wait_for_status: status.to_s)
92
114
  end
93
115
 
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')
116
+ # @return [void]
117
+ def may_update_type!(hash, key: :type)
118
+ if (single_type = engine.mapping_default_type)
119
+ hash[key] = single_type
120
+ return
121
+ end
122
+ hash.delete(key) if engine.mapping_single_type?
98
123
  end
99
124
 
100
125
  def info
@@ -108,8 +133,9 @@ module Esse
108
133
  end
109
134
 
110
135
  def engine
111
- ClusterEngine.new(**info)
136
+ @engine ||=ClusterEngine.new(**info)
112
137
  end
138
+ alias_method :warm_up!, :engine
113
139
 
114
140
  # Build a search query for the given indices
115
141
  #
@@ -121,9 +147,9 @@ module Esse
121
147
 
122
148
  # Return the proxy object used to perform low level actions on the elasticsearch cluster through the official api client
123
149
  #
124
- # @return [Esse::ClientProxy] The cluster api instance
150
+ # @return [Esse::Transport] The cluster api instance
125
151
  def api
126
- Esse::ClientProxy.new(self)
152
+ Esse::Transport.new(self)
127
153
  end
128
154
  end
129
155
  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
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Esse
4
+ module Deprecations
5
+ module Deprecate
6
+ def self.extended(base)
7
+ base.extend Gem::Deprecate
8
+ base.include InstanceMethods
9
+ end
10
+
11
+ module InstanceMethods
12
+ def warning(method, repl, year, month)
13
+ msg = ["NOTE: #{method} is deprecated"]
14
+ msg << if repl == :none
15
+ ' with no replacement'
16
+ elsif repl.respond_to?(:call)
17
+ "; use #{repl.call} instead"
18
+ else
19
+ "; use #{repl} instead"
20
+ end
21
+ msg << '. It will be removed on or after %4d-%02d-01.' % [year, month]
22
+ msg << "\n#{method} called from #{Gem.location_of_caller(2).join(':')}"
23
+
24
+ warn "#{msg.join}." unless Gem::Deprecate.skip
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end