esse 0.2.0 → 0.2.2
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.
- checksums.yaml +4 -4
- data/lib/esse/backend/index/aliases.rb +8 -8
- data/lib/esse/backend/index/close.rb +3 -3
- data/lib/esse/backend/index/create.rb +4 -4
- data/lib/esse/backend/index/delete.rb +4 -4
- data/lib/esse/backend/index/documents.rb +253 -6
- data/lib/esse/backend/index/existance.rb +3 -3
- data/lib/esse/backend/index/open.rb +3 -3
- data/lib/esse/backend/index/refresh.rb +7 -5
- data/lib/esse/backend/index/reset.rb +4 -4
- data/lib/esse/backend/index/update.rb +7 -7
- data/lib/esse/backend/index.rb +16 -14
- data/lib/esse/backend/repository_backend.rb +105 -0
- data/lib/esse/cli/event_listener.rb +14 -0
- data/lib/esse/cli/generate.rb +53 -12
- data/lib/esse/cli/index/base_operation.rb +5 -13
- data/lib/esse/cli/index/import.rb +6 -2
- data/lib/esse/cli/index/update_mapping.rb +3 -4
- data/lib/esse/cli/index.rb +2 -0
- data/lib/esse/cli/templates/{type_collection.rb.erb → collection.rb.erb} +6 -18
- data/lib/esse/cli/templates/config.rb.erb +13 -3
- data/lib/esse/cli/templates/index.rb.erb +53 -109
- data/lib/esse/cli/templates/mappings.json +27 -0
- data/lib/esse/cli/templates/serializer.rb.erb +34 -0
- data/lib/esse/cli/templates/settings.json +62 -0
- data/lib/esse/client_proxy/search.rb +44 -0
- data/lib/esse/client_proxy.rb +32 -0
- data/lib/esse/cluster.rb +64 -9
- data/lib/esse/cluster_engine.rb +42 -0
- data/lib/esse/collection.rb +18 -0
- data/lib/esse/config.rb +14 -2
- data/lib/esse/core.rb +23 -6
- data/lib/esse/deprecations/cluster.rb +27 -0
- data/lib/esse/deprecations/index.rb +19 -0
- data/lib/esse/deprecations/repository.rb +19 -0
- data/lib/esse/deprecations.rb +3 -0
- data/lib/esse/dynamic_template.rb +39 -0
- data/lib/esse/errors.rb +53 -2
- data/lib/esse/events/event.rb +4 -19
- data/lib/esse/events.rb +3 -0
- data/lib/esse/hash_document.rb +38 -0
- data/lib/esse/import/bulk.rb +96 -0
- data/lib/esse/import/request_body.rb +60 -0
- data/lib/esse/index/attributes.rb +98 -0
- data/lib/esse/index/base.rb +1 -1
- data/lib/esse/index/inheritance.rb +30 -0
- data/lib/esse/index/mappings.rb +6 -19
- data/lib/esse/index/object_document_mapper.rb +95 -0
- data/lib/esse/index/plugins.rb +42 -0
- data/lib/esse/index/search.rb +27 -0
- data/lib/esse/index/settings.rb +2 -2
- data/lib/esse/index/type.rb +52 -11
- data/lib/esse/index.rb +10 -6
- data/lib/esse/index_mapping.rb +10 -2
- data/lib/esse/index_setting.rb +3 -1
- data/lib/esse/null_document.rb +35 -0
- data/lib/esse/plugins.rb +12 -0
- data/lib/esse/primitives/hstring.rb +1 -1
- data/lib/esse/{index_type → repository}/actions.rb +1 -1
- data/lib/esse/{index_type → repository}/backend.rb +2 -2
- data/lib/esse/repository/object_document_mapper.rb +157 -0
- data/lib/esse/repository.rb +18 -0
- data/lib/esse/search/query.rb +105 -0
- data/lib/esse/search/response.rb +46 -0
- data/lib/esse/serializer.rb +76 -0
- data/lib/esse/version.rb +1 -1
- data/lib/esse.rb +20 -5
- metadata +35 -30
- data/lib/esse/backend/index_type/documents.rb +0 -214
- data/lib/esse/backend/index_type.rb +0 -37
- data/lib/esse/cli/templates/type_mappings.json +0 -6
- data/lib/esse/cli/templates/type_serializer.rb.erb +0 -23
- data/lib/esse/index/naming.rb +0 -64
- data/lib/esse/index_type/mappings.rb +0 -42
- data/lib/esse/index_type.rb +0 -15
- data/lib/esse/object_document_mapper.rb +0 -110
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class ClientProxy
|
5
|
+
module InstanceMethods
|
6
|
+
# Returns results matching a query.
|
7
|
+
def search(index:, **options)
|
8
|
+
definition = options.merge(
|
9
|
+
index: index,
|
10
|
+
)
|
11
|
+
|
12
|
+
Esse::Events.instrument('elasticsearch.search') do |payload|
|
13
|
+
payload[:request] = definition
|
14
|
+
payload[:response] = coerce_exception { client.search(definition) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Allows to retrieve a large numbers of results from a single search request.
|
19
|
+
#
|
20
|
+
# @param [Time] :scroll Specify how long a consistent view of the index should be maintained for scrolled search
|
21
|
+
# @param [Boolean] :rest_total_hits_as_int Indicates whether hits.total should be rendered as an integer or an object in the rest search response
|
22
|
+
# @param [Hash] :body The scroll ID
|
23
|
+
def scroll(scroll:, **definition)
|
24
|
+
unless definition[:body]
|
25
|
+
raise ArgumentError, 'scroll search must have a :body with the :scroll_id'
|
26
|
+
end
|
27
|
+
Esse::Events.instrument('elasticsearch.search') do |payload|
|
28
|
+
payload[:request] = definition
|
29
|
+
payload[:response] = coerce_exception { client.scroll(scroll: scroll, **definition) }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Explicitly clears the search context for a scroll.
|
34
|
+
#
|
35
|
+
# @param [Hash] :body Body with the "scroll_id" (string or array of strings) Scroll IDs to clear.
|
36
|
+
# To clear all scroll IDs, use _all.
|
37
|
+
def clear_scroll(body:, **options)
|
38
|
+
coerce_exception { client.clear_scroll(body: body, **options) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
include InstanceMethods
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class ClientProxy
|
5
|
+
require_relative './client_proxy/search'
|
6
|
+
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
def_delegators :@cluster, :client
|
10
|
+
|
11
|
+
attr_reader :cluster
|
12
|
+
|
13
|
+
def initialize(cluster)
|
14
|
+
@cluster = cluster
|
15
|
+
end
|
16
|
+
|
17
|
+
# Elasticsearch::Transport was renamed to Elastic::Transport in 8.0
|
18
|
+
# This lib should support both versions that's why we are wrapping up the transport
|
19
|
+
# errors to local errors.
|
20
|
+
def coerce_exception
|
21
|
+
yield
|
22
|
+
rescue => exception
|
23
|
+
name = Hstring.new(exception.class.name)
|
24
|
+
if /^(Elasticsearch|Elastic|OpenSearch)?::Transport::Transport::Errors/.match?(name.value) && \
|
25
|
+
(exception_class = Esse::Backend::ERRORS[name.demodulize.value])
|
26
|
+
raise exception_class.new(exception.message)
|
27
|
+
else
|
28
|
+
raise exception
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/esse/cluster.rb
CHANGED
@@ -1,16 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'cluster_engine'
|
4
|
+
require_relative 'client_proxy'
|
5
|
+
|
3
6
|
module Esse
|
4
7
|
class Cluster
|
5
|
-
ATTRIBUTES = %i[index_prefix
|
8
|
+
ATTRIBUTES = %i[index_prefix settings mappings client wait_for_status].freeze
|
6
9
|
WAIT_FOR_STATUSES = %w[green yellow red].freeze
|
7
10
|
|
8
11
|
# The index prefix. For example an index named UsersIndex.
|
9
12
|
# With `index_prefix = 'app1'`. Final index/alias is: 'app1_users'
|
10
13
|
attr_accessor :index_prefix
|
11
14
|
|
12
|
-
# This settings will be passed through all indices
|
13
|
-
attr_accessor :
|
15
|
+
# This global settings will be passed through all indices
|
16
|
+
attr_accessor :settings
|
17
|
+
|
18
|
+
# This global mappings will be applied to all indices
|
19
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping.html
|
20
|
+
attr_accessor :mappings
|
14
21
|
|
15
22
|
# if this option set, actions such as creating or deleting index,
|
16
23
|
# importing data will wait for the status specified. Extremely useful
|
@@ -25,7 +32,8 @@ module Esse
|
|
25
32
|
|
26
33
|
def initialize(id:, **options)
|
27
34
|
@id = id.to_sym
|
28
|
-
@
|
35
|
+
@settings = {}
|
36
|
+
@mappings = {}
|
29
37
|
assign(options)
|
30
38
|
end
|
31
39
|
|
@@ -41,16 +49,28 @@ module Esse
|
|
41
49
|
end
|
42
50
|
|
43
51
|
def client
|
44
|
-
@client ||= Elasticsearch::Client
|
52
|
+
@client ||= if defined? Elasticsearch::Client
|
53
|
+
Elasticsearch::Client.new
|
54
|
+
elsif defined? OpenSearch::Client
|
55
|
+
OpenSearch::Client.new
|
56
|
+
else
|
57
|
+
raise Esse::Error, <<~ERROR
|
58
|
+
Elasticsearch::Client or OpenSearch::Client is not defined.
|
59
|
+
Please install elasticsearch or opensearch-ruby gem.
|
60
|
+
ERROR
|
61
|
+
end
|
45
62
|
end
|
46
63
|
|
47
|
-
# Define the elasticsearch client
|
48
|
-
# @param es_client [Elasticsearch::Client, Hash] an instance of elasticsearch/api client or an hash
|
49
|
-
# with the settings that will be used to initialize
|
64
|
+
# Define the elasticsearch client connection
|
65
|
+
# @param es_client [Elasticsearch::Client, OpenSearch::Client, Hash] an instance of elasticsearch/api client or an hash
|
66
|
+
# with the settings that will be used to initialize the Client
|
50
67
|
def client=(es_client)
|
51
|
-
@client = if es_client.is_a?(Hash)
|
68
|
+
@client = if es_client.is_a?(Hash) && defined?(Elasticsearch::Client)
|
52
69
|
settings = es_client.each_with_object({}) { |(k, v), r| r[k.to_sym] = v }
|
53
70
|
Elasticsearch::Client.new(settings)
|
71
|
+
elsif es_client.is_a?(Hash) && defined?(OpenSearch::Client)
|
72
|
+
settings = es_client.each_with_object({}) { |(k, v), r| r[k.to_sym] = v }
|
73
|
+
OpenSearch::Client.new(settings)
|
54
74
|
else
|
55
75
|
es_client
|
56
76
|
end
|
@@ -70,5 +90,40 @@ module Esse
|
|
70
90
|
|
71
91
|
client.cluster.health(wait_for_status: status.to_s)
|
72
92
|
end
|
93
|
+
|
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')
|
98
|
+
end
|
99
|
+
|
100
|
+
def info
|
101
|
+
@info ||= begin
|
102
|
+
resp = client.info
|
103
|
+
{
|
104
|
+
distribution: (resp.dig('version', 'distribution') || 'elasticsearch'),
|
105
|
+
version: resp.dig('version', 'number'),
|
106
|
+
}
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def engine
|
111
|
+
ClusterEngine.new(**info)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Build a search query for the given indices
|
115
|
+
#
|
116
|
+
# @param indices [Array<Esse::Index, String>] The indices class or the index name
|
117
|
+
# @return [Esse::Search::Query] The search query instance
|
118
|
+
def search(*indices, **kwargs, &block)
|
119
|
+
Esse::Search::Query.new(api, *indices, **kwargs, &block)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Return the proxy object used to perform low level actions on the elasticsearch cluster through the official api client
|
123
|
+
#
|
124
|
+
# @return [Esse::ClientProxy] The cluster api instance
|
125
|
+
def api
|
126
|
+
Esse::ClientProxy.new(self)
|
127
|
+
end
|
73
128
|
end
|
74
129
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class ClusterEngine
|
5
|
+
OPENSEARCH_FORK_VERSION = '7.10.2'
|
6
|
+
|
7
|
+
attr_reader :version, :distribution
|
8
|
+
|
9
|
+
def initialize(distribution:, version:)
|
10
|
+
@distribution = distribution
|
11
|
+
@version = version
|
12
|
+
end
|
13
|
+
|
14
|
+
def engine_version
|
15
|
+
return @version unless opensearch?
|
16
|
+
|
17
|
+
OPENSEARCH_FORK_VERSION
|
18
|
+
end
|
19
|
+
|
20
|
+
def opensearch?
|
21
|
+
distribution == 'opensearch'
|
22
|
+
end
|
23
|
+
|
24
|
+
def elasticsearch?
|
25
|
+
distribution == 'elasticsearch'
|
26
|
+
end
|
27
|
+
|
28
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/7.17/removal-of-types.html
|
29
|
+
def mapping_single_type?
|
30
|
+
engine_version >= '6'
|
31
|
+
end
|
32
|
+
|
33
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/6.3/mapping.html
|
34
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/6.4/mapping.html
|
35
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/7.1/mapping.html
|
36
|
+
def mapping_default_type
|
37
|
+
return unless engine_version.to_i == 6
|
38
|
+
|
39
|
+
engine_version >= '6.4' ? :_doc : :doc
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class Collection
|
5
|
+
include Enumerable
|
6
|
+
attr_reader :options
|
7
|
+
|
8
|
+
def initialize(**options)
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
# @yield [<Array, Hash>] A batch of documents to be serialized and indexed.
|
13
|
+
# @abstract Override this method to yield each chunk of documents with optional metadata
|
14
|
+
def each
|
15
|
+
raise NotImplementedError, 'Override this method to iterate over the collection'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/esse/config.rb
CHANGED
@@ -9,10 +9,14 @@ module Esse
|
|
9
9
|
# conf.cluster(:v1) do |cluster|
|
10
10
|
# cluster.index_prefix = 'backend'
|
11
11
|
# cluster.client = Elasticsearch::Client.new
|
12
|
-
# cluster.
|
12
|
+
# cluster.settings = {
|
13
13
|
# number_of_shards: 2,
|
14
14
|
# number_of_replicas: 0
|
15
15
|
# }
|
16
|
+
# cluster.mappings = {
|
17
|
+
# dynamic_templates: [...]
|
18
|
+
# properties: { ... }
|
19
|
+
# }
|
16
20
|
# end
|
17
21
|
# end
|
18
22
|
#
|
@@ -36,13 +40,17 @@ module Esse
|
|
36
40
|
# end
|
37
41
|
class Config
|
38
42
|
DEFAULT_CLUSTER_ID = :default
|
39
|
-
ATTRIBUTES = %i[indices_directory].freeze
|
43
|
+
ATTRIBUTES = %i[indices_directory bulk_wait_interval].freeze
|
40
44
|
|
41
45
|
# The location of the indices. Defaults to the `app/indices`
|
42
46
|
attr_reader :indices_directory
|
43
47
|
|
48
|
+
# wait a given period between posting pages to give Elasticsearch time to catch up.
|
49
|
+
attr_reader :bulk_wait_interval
|
50
|
+
|
44
51
|
def initialize
|
45
52
|
self.indices_directory = 'app/indices'
|
53
|
+
self.bulk_wait_interval = 0.1
|
46
54
|
@clusters = {}
|
47
55
|
cluster(DEFAULT_CLUSTER_ID) # initialize the :default client
|
48
56
|
end
|
@@ -66,6 +74,10 @@ module Esse
|
|
66
74
|
@indices_directory = value.is_a?(Pathname) ? value : Pathname.new(value)
|
67
75
|
end
|
68
76
|
|
77
|
+
def bulk_wait_interval=(value)
|
78
|
+
@bulk_wait_interval = value.to_f
|
79
|
+
end
|
80
|
+
|
69
81
|
def load(arg)
|
70
82
|
case arg
|
71
83
|
when Hash
|
data/lib/esse/core.rb
CHANGED
@@ -1,22 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require 'multi_json'
|
5
|
-
require 'elasticsearch'
|
6
|
-
|
7
3
|
module Esse
|
8
4
|
require_relative 'config'
|
9
5
|
require_relative 'cluster'
|
10
6
|
require_relative 'primitives'
|
11
|
-
require_relative '
|
7
|
+
require_relative 'collection'
|
8
|
+
require_relative 'serializer'
|
9
|
+
require_relative 'hash_document'
|
10
|
+
require_relative 'null_document'
|
11
|
+
require_relative 'repository'
|
12
12
|
require_relative 'index_setting'
|
13
|
+
require_relative 'dynamic_template'
|
13
14
|
require_relative 'index_mapping'
|
14
15
|
require_relative 'template_loader'
|
16
|
+
require_relative 'import/request_body'
|
17
|
+
require_relative 'import/bulk'
|
15
18
|
require_relative 'backend/index'
|
16
|
-
require_relative 'backend/
|
19
|
+
require_relative 'backend/repository_backend'
|
17
20
|
require_relative 'version'
|
18
21
|
require_relative 'logging'
|
19
22
|
require_relative 'events'
|
23
|
+
require_relative 'search/query'
|
24
|
+
require_relative 'search/response'
|
25
|
+
require_relative 'deprecations' # Should be last
|
20
26
|
include Logging
|
21
27
|
|
22
28
|
@single_threaded = false
|
@@ -68,4 +74,15 @@ module Esse
|
|
68
74
|
end
|
69
75
|
[id, modified]
|
70
76
|
end
|
77
|
+
|
78
|
+
def self.eager_load_indices!
|
79
|
+
return false unless Esse.config.indices_directory.exist?
|
80
|
+
|
81
|
+
Dir[Esse.config.indices_directory.join('**/*_index.rb')].map { |path| Pathname.new(path) }.each do |path|
|
82
|
+
next unless path.extname == '.rb'
|
83
|
+
|
84
|
+
require(path.expand_path.to_s)
|
85
|
+
end
|
86
|
+
true
|
87
|
+
end
|
71
88
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class Cluster
|
5
|
+
extend Gem::Deprecate
|
6
|
+
|
7
|
+
def index_settings
|
8
|
+
settings
|
9
|
+
end
|
10
|
+
deprecate :index_settings, :settings, 2022, 10
|
11
|
+
|
12
|
+
def index_settings=(value)
|
13
|
+
self.settings = value
|
14
|
+
end
|
15
|
+
deprecate :index_settings=, :settings=, 2022, 10
|
16
|
+
|
17
|
+
def index_mappings
|
18
|
+
mappings
|
19
|
+
end
|
20
|
+
deprecate :index_mappings, :mappings, 2022, 10
|
21
|
+
|
22
|
+
def index_mappings=(value)
|
23
|
+
self.mappings = value
|
24
|
+
end
|
25
|
+
deprecate :index_mappings=, :mappings=, 2022, 10
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class Index
|
5
|
+
class << self
|
6
|
+
extend Gem::Deprecate
|
7
|
+
|
8
|
+
def define_type(name, *args, **kwargs, &block)
|
9
|
+
repository(name, *args, **kwargs, &block)
|
10
|
+
end
|
11
|
+
deprecate :define_type, :repository, 2022, 8
|
12
|
+
|
13
|
+
def type_hash
|
14
|
+
repo_hash
|
15
|
+
end
|
16
|
+
deprecate :type_hash, :repo_hash, 2022, 8
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class Repository
|
5
|
+
class << self
|
6
|
+
extend Gem::Deprecate
|
7
|
+
|
8
|
+
def type_name
|
9
|
+
document_type
|
10
|
+
end
|
11
|
+
deprecate :type_name, :document_type, 2022, 10
|
12
|
+
|
13
|
+
def mappings(*args, &block)
|
14
|
+
index.mappings(*args, &block)
|
15
|
+
end
|
16
|
+
deprecate :mappings, "Esse::Index.mappings", 2022, 10
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class DynamicTemplate
|
5
|
+
# @param [Array, Hash] value The list of dynamic_templates for mapping
|
6
|
+
def initialize(value)
|
7
|
+
@hash = normalize(value)
|
8
|
+
end
|
9
|
+
|
10
|
+
def merge!(value)
|
11
|
+
@hash = HashUtils.deep_merge(@hash, normalize(value))
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_a
|
15
|
+
@hash.map do |name, value|
|
16
|
+
{ name => value }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def any?
|
21
|
+
@hash.any?
|
22
|
+
end
|
23
|
+
|
24
|
+
def dup
|
25
|
+
self.class.new(@hash.dup)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def normalize(value)
|
31
|
+
case value
|
32
|
+
when Array
|
33
|
+
value.map { |v| normalize(v) }.reduce(&:merge)
|
34
|
+
when Hash
|
35
|
+
HashUtils.deep_transform_keys(value, &:to_sym)
|
36
|
+
end || {}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/esse/errors.rb
CHANGED
@@ -4,6 +4,59 @@ module Esse
|
|
4
4
|
class Error < StandardError
|
5
5
|
end
|
6
6
|
|
7
|
+
# @todo Rename this
|
8
|
+
module Backend
|
9
|
+
class ServerError < ::Esse::Error; end
|
10
|
+
|
11
|
+
ES_TRANSPORT_ERRORS = {
|
12
|
+
'MultipleChoices' => 'MultipleChoicesError', # 300
|
13
|
+
'MovedPermanently' => 'MovedPermanentlyError', # 301
|
14
|
+
'Found' => 'FoundError', # 302
|
15
|
+
'SeeOther' => 'SeeOtherError', # 303
|
16
|
+
'NotModified' => 'NotModifiedError', # 304
|
17
|
+
'UseProxy' => 'UseProxyError', # 305
|
18
|
+
'TemporaryRedirect' => 'TemporaryRedirectError', # 307
|
19
|
+
'PermanentRedirect' => 'PermanentRedirectError', # 308
|
20
|
+
'BadRequest' => 'BadRequestError', # 400
|
21
|
+
'Unauthorized' => 'UnauthorizedError', # 401
|
22
|
+
'PaymentRequired' => 'PaymentRequiredError', # 402
|
23
|
+
'Forbidden' => 'ForbiddenError', # 403
|
24
|
+
'NotFound' => 'NotFoundError', # 404
|
25
|
+
'MethodNotAllowed' => 'MethodNotAllowedError', # 405
|
26
|
+
'NotAcceptable' => 'NotAcceptableError', # 406
|
27
|
+
'ProxyAuthenticationRequired' => 'ProxyAuthenticationRequiredError', # 407
|
28
|
+
'RequestTimeout' => 'RequestTimeoutError', # 408
|
29
|
+
'Conflict' => 'ConflictError', # 409
|
30
|
+
'Gone' => 'GoneError', # 410
|
31
|
+
'LengthRequired' => 'LengthRequiredError', # 411
|
32
|
+
'PreconditionFailed' => 'PreconditionFailedError', # 412
|
33
|
+
'RequestEntityTooLarge' => 'RequestEntityTooLargeError', # 413
|
34
|
+
'RequestURITooLong' => 'RequestURITooLongError', # 414
|
35
|
+
'UnsupportedMediaType' => 'UnsupportedMediaTypeError', # 415
|
36
|
+
'RequestedRangeNotSatisfiable' => 'RequestedRangeNotSatisfiableError', # 416
|
37
|
+
'ExpectationFailed' => 'ExpectationFailedError', # 417
|
38
|
+
'ImATeapot' => 'ImATeapotError', # 418
|
39
|
+
'TooManyConnectionsFromThisIP' => 'TooManyConnectionsFromThisIPError', # 421
|
40
|
+
'UpgradeRequired' => 'UpgradeRequiredError', # 426
|
41
|
+
'BlockedByWindowsParentalControls' => 'BlockedByWindowsParentalControlsError', # 450
|
42
|
+
'RequestHeaderTooLarge' => 'RequestHeaderTooLargeError', # 494
|
43
|
+
'HTTPToHTTPS' => 'HTTPToHTTPSError', # 497
|
44
|
+
'ClientClosedRequest' => 'ClientClosedRequestError', # 499
|
45
|
+
'InternalServerError' => 'InternalServerError', # 500
|
46
|
+
'NotImplemented' => 'NotImplementedError', # 501
|
47
|
+
'BadGateway' => 'BadGatewayError', # 502
|
48
|
+
'ServiceUnavailable' => 'ServiceUnavailableError', # 503
|
49
|
+
'GatewayTimeout' => 'GatewayTimeoutError', # 504
|
50
|
+
'HTTPVersionNotSupported' => 'HTTPVersionNotSupportedError', # 505
|
51
|
+
'VariantAlsoNegotiates' => 'VariantAlsoNegotiatesError', # 506
|
52
|
+
'NotExtended' => 'NotExtendedError', # 510
|
53
|
+
}
|
54
|
+
|
55
|
+
ERRORS = ES_TRANSPORT_ERRORS.each_with_object({}) do |(transport_name, esse_name), memo|
|
56
|
+
memo[transport_name] = const_set esse_name, Class.new(ServerError)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
7
60
|
module Events
|
8
61
|
class UnregisteredEventError < ::Esse::Error
|
9
62
|
def initialize(object_or_event_id)
|
@@ -42,6 +95,4 @@ module Esse
|
|
42
95
|
class InvalidOption < Error
|
43
96
|
end
|
44
97
|
end
|
45
|
-
|
46
|
-
# Elasticsearch::Transport::Transport::Errors::NotFound
|
47
98
|
end
|
data/lib/esse/events/event.rb
CHANGED
@@ -3,6 +3,10 @@
|
|
3
3
|
module Esse
|
4
4
|
module Events
|
5
5
|
class Event
|
6
|
+
extend Forwardable
|
7
|
+
def_delegators :@payload, :[], :fetch, :to_h, :key?
|
8
|
+
alias_method :to_hash, :to_h
|
9
|
+
|
6
10
|
attr_reader :id
|
7
11
|
|
8
12
|
# Initialize a new event
|
@@ -18,25 +22,6 @@ module Esse
|
|
18
22
|
@payload = payload
|
19
23
|
end
|
20
24
|
|
21
|
-
# Get data from the payload
|
22
|
-
#
|
23
|
-
# @param [String,Symbol] name
|
24
|
-
#
|
25
|
-
# @api public
|
26
|
-
def [](name)
|
27
|
-
@payload.fetch(name)
|
28
|
-
end
|
29
|
-
|
30
|
-
# Coerce an event to a hash
|
31
|
-
#
|
32
|
-
# @return [Hash]
|
33
|
-
#
|
34
|
-
# @api public
|
35
|
-
def to_h
|
36
|
-
@payload
|
37
|
-
end
|
38
|
-
alias_method :to_hash, :to_h
|
39
|
-
|
40
25
|
# Get or set a payload
|
41
26
|
#
|
42
27
|
# @overload
|
data/lib/esse/events.rb
CHANGED
@@ -45,5 +45,8 @@ module Esse
|
|
45
45
|
register_event 'elasticsearch.update_mapping'
|
46
46
|
register_event 'elasticsearch.update_settings'
|
47
47
|
register_event 'elasticsearch.update_aliases'
|
48
|
+
register_event 'elasticsearch.bulk'
|
49
|
+
register_event 'elasticsearch.search'
|
50
|
+
register_event 'elasticsearch.execute_search_query'
|
48
51
|
end
|
49
52
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class HashDocument < Esse::Serializer
|
5
|
+
META_KEYS = %i[_id _type _routing routing].freeze
|
6
|
+
|
7
|
+
def initialize(object)
|
8
|
+
@object = object
|
9
|
+
@options = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
# @return [String, Number] the document ID
|
13
|
+
def id
|
14
|
+
object['_id'] || object[:_id] || object['id'] || object[:id]
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [String, nil] the document type
|
18
|
+
def type
|
19
|
+
object['_type'] || object[:_type]
|
20
|
+
end
|
21
|
+
|
22
|
+
# @return [String, nil] the document routing
|
23
|
+
def routing
|
24
|
+
object['_routing'] || object[:_routing] || object['routing'] || object[:routing]
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [Hash] the document meta
|
28
|
+
def meta
|
29
|
+
{}
|
30
|
+
end
|
31
|
+
|
32
|
+
# @return [Hash] the document source
|
33
|
+
# @abstract Override this method to return the document source
|
34
|
+
def source
|
35
|
+
object.reject { |key, _| META_KEYS.include?(key.to_sym) }
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|