esse 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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