esse 0.0.5 → 0.1.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.
- checksums.yaml +4 -4
- data/exec/esse +3 -1
- data/lib/esse/backend/index/aliases.rb +7 -3
- data/lib/esse/backend/index/close.rb +6 -3
- data/lib/esse/backend/index/create.rb +19 -8
- data/lib/esse/backend/index/delete.rb +13 -8
- data/lib/esse/backend/index/documents.rb +2 -2
- data/lib/esse/backend/index/existance.rb +1 -1
- data/lib/esse/backend/index/open.rb +6 -3
- data/lib/esse/backend/index/refresh.rb +2 -2
- data/lib/esse/backend/index/reset.rb +2 -4
- data/lib/esse/backend/index/update.rb +37 -12
- data/lib/esse/backend/index.rb +5 -1
- data/lib/esse/backend/index_type/documents.rb +7 -7
- data/lib/esse/cli/event_listener.rb +87 -0
- data/lib/esse/cli/generate.rb +7 -3
- data/lib/esse/cli/index/base_operation.rb +76 -0
- data/lib/esse/cli/index/close.rb +26 -0
- data/lib/esse/cli/index/create.rb +26 -0
- data/lib/esse/cli/index/delete.rb +26 -0
- data/lib/esse/cli/index/import.rb +26 -0
- data/lib/esse/cli/index/open.rb +26 -0
- data/lib/esse/cli/index/reset.rb +26 -0
- data/lib/esse/cli/index/update_aliases.rb +32 -0
- data/lib/esse/cli/index/update_mapping.rb +33 -0
- data/lib/esse/cli/index/update_settings.rb +26 -0
- data/lib/esse/cli/index.rb +78 -2
- data/lib/esse/cli/templates/config.rb.erb +20 -0
- data/lib/esse/cli/templates/index.rb.erb +74 -9
- data/lib/esse/cli/templates/type_collection.rb.erb +41 -0
- data/lib/esse/cli/templates/{mappings.json → type_mappings.json} +0 -0
- data/lib/esse/cli/templates/{serializer.rb.erb → type_serializer.rb.erb} +9 -4
- data/lib/esse/cli.rb +75 -3
- data/lib/esse/cluster.rb +18 -2
- data/lib/esse/config.rb +39 -5
- data/lib/esse/core.rb +15 -33
- data/lib/esse/document.rb +43 -0
- data/lib/esse/errors.rb +47 -0
- data/lib/esse/events/bus.rb +103 -0
- data/lib/esse/events/event.rb +64 -0
- data/lib/esse/events/publisher.rb +119 -0
- data/lib/esse/events.rb +49 -0
- data/lib/esse/index/backend.rb +2 -1
- data/lib/esse/index/base.rb +4 -6
- data/lib/esse/index/mappings.rb +2 -3
- data/lib/esse/index/settings.rb +7 -8
- data/lib/esse/index.rb +2 -1
- data/lib/esse/index_mapping.rb +2 -2
- data/lib/esse/index_setting.rb +8 -4
- data/lib/esse/index_type/actions.rb +2 -1
- data/lib/esse/index_type/backend.rb +2 -1
- data/lib/esse/index_type/mappings.rb +2 -2
- data/lib/esse/index_type.rb +6 -1
- data/lib/esse/logging.rb +19 -0
- data/lib/esse/object_document_mapper.rb +110 -0
- data/lib/esse/primitives/hash_utils.rb +40 -0
- data/lib/esse/primitives/hstring.rb +4 -3
- data/lib/esse/primitives/output.rb +64 -0
- data/lib/esse/primitives.rb +1 -0
- data/lib/esse/template_loader.rb +1 -1
- data/lib/esse/version.rb +1 -1
- data/lib/esse.rb +12 -3
- metadata +108 -22
- data/.gitignore +0 -12
- data/.rubocop.yml +0 -128
- data/.tool-versions +0 -1
- data/.yardopts +0 -2
- data/CHANGELOG.md +0 -0
- data/Gemfile +0 -7
- data/Gemfile.lock +0 -62
- data/LICENSE.txt +0 -21
- data/README.md +0 -52
- data/Rakefile +0 -4
- data/bin/console +0 -22
- data/bin/setup +0 -8
- data/esse.gemspec +0 -40
- data/lib/esse/index_type/serializer.rb +0 -87
data/lib/esse/config.rb
CHANGED
@@ -3,6 +3,31 @@
|
|
3
3
|
require 'pathname'
|
4
4
|
|
5
5
|
module Esse
|
6
|
+
# Block configurations
|
7
|
+
# Esse.configure do |conf|
|
8
|
+
# conf.indices_directory = 'app/indices/directory'
|
9
|
+
# conf.cluster(:v1) do |cluster|
|
10
|
+
# cluster.index_prefix = 'backend'
|
11
|
+
# cluster.client = Elasticsearch::Client.new
|
12
|
+
# cluster.index_settings = {
|
13
|
+
# number_of_shards: 2,
|
14
|
+
# number_of_replicas: 0
|
15
|
+
# }
|
16
|
+
# end
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# Inline configurations
|
20
|
+
# Esse.config.indices_directory = 'app/indices/directory'
|
21
|
+
# Esse.config.cluster(:v1).client = Elasticsearch::Client.new
|
22
|
+
class << self
|
23
|
+
def config
|
24
|
+
@config ||= Config.new
|
25
|
+
yield(@config) if block_given?
|
26
|
+
@config
|
27
|
+
end
|
28
|
+
alias_method :configure, :config
|
29
|
+
end
|
30
|
+
|
6
31
|
# Provides all configurations
|
7
32
|
#
|
8
33
|
# Example
|
@@ -19,14 +44,14 @@ module Esse
|
|
19
44
|
def initialize
|
20
45
|
self.indices_directory = 'app/indices'
|
21
46
|
@clusters = {}
|
22
|
-
|
47
|
+
cluster(DEFAULT_CLUSTER_ID) # initialize the :default client
|
23
48
|
end
|
24
49
|
|
25
50
|
def cluster_ids
|
26
51
|
@clusters.keys
|
27
52
|
end
|
28
53
|
|
29
|
-
def
|
54
|
+
def cluster(key = DEFAULT_CLUSTER_ID, **options)
|
30
55
|
return unless key
|
31
56
|
|
32
57
|
id = key.to_sym
|
@@ -35,6 +60,7 @@ module Esse
|
|
35
60
|
yield c if block_given?
|
36
61
|
end
|
37
62
|
end
|
63
|
+
alias_method :clusters, :cluster
|
38
64
|
|
39
65
|
def indices_directory=(value)
|
40
66
|
@indices_directory = value.is_a?(Pathname) ? value : Pathname.new(value)
|
@@ -45,14 +71,22 @@ module Esse
|
|
45
71
|
when Hash
|
46
72
|
assign(arg)
|
47
73
|
when File, Pathname
|
48
|
-
|
74
|
+
assign(YAML.load_file(arg))
|
49
75
|
when String
|
50
|
-
|
76
|
+
return load(Pathname.new(arg)) if File.exist?(arg)
|
77
|
+
|
78
|
+
assign(YAML.safe_load(arg))
|
51
79
|
else
|
52
80
|
raise ArgumentError, printf('could not load configuration using: %p', val)
|
53
81
|
end
|
54
82
|
end
|
55
83
|
|
84
|
+
# :nodoc:
|
85
|
+
# This is only used by rspec to disable the CLI print out.
|
86
|
+
def cli_event_listeners?
|
87
|
+
true
|
88
|
+
end
|
89
|
+
|
56
90
|
private
|
57
91
|
|
58
92
|
def assign(hash)
|
@@ -64,7 +98,7 @@ module Esse
|
|
64
98
|
end
|
65
99
|
if (connections = hash['clusters'] || hash[:clusters]).is_a?(Hash)
|
66
100
|
connections.each do |key, value|
|
67
|
-
|
101
|
+
cluster(key).assign(value) if value.is_a?(Hash)
|
68
102
|
end
|
69
103
|
end
|
70
104
|
true
|
data/lib/esse/core.rb
CHANGED
@@ -1,35 +1,28 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
|
3
4
|
require 'multi_json'
|
4
5
|
require 'elasticsearch'
|
5
6
|
|
6
7
|
module Esse
|
8
|
+
require_relative 'config'
|
9
|
+
require_relative 'cluster'
|
10
|
+
require_relative 'primitives'
|
11
|
+
require_relative 'index_type'
|
12
|
+
require_relative 'index_setting'
|
13
|
+
require_relative 'index_mapping'
|
14
|
+
require_relative 'template_loader'
|
15
|
+
require_relative 'backend/index'
|
16
|
+
require_relative 'backend/index_type'
|
17
|
+
require_relative 'version'
|
18
|
+
require_relative 'logging'
|
19
|
+
require_relative 'events'
|
20
|
+
include Logging
|
21
|
+
|
7
22
|
@single_threaded = false
|
8
23
|
# Mutex used to protect mutable data structures
|
9
24
|
@data_mutex = Mutex.new
|
10
25
|
|
11
|
-
# Block configurations
|
12
|
-
# Esse.config do |conf|
|
13
|
-
# conf.indices_directory = 'app/indices/directory'
|
14
|
-
# conf.clusters(:v1) do |cluster|
|
15
|
-
# cluster.index_prefix = 'backend'
|
16
|
-
# cluster.client = Elasticsearch::Client.new
|
17
|
-
# cluster.index_settings = {
|
18
|
-
# number_of_shards: 2,
|
19
|
-
# number_of_replicas: 0
|
20
|
-
# }
|
21
|
-
# end
|
22
|
-
# end
|
23
|
-
#
|
24
|
-
# Inline configurations
|
25
|
-
# Esse.config.indices_directory = 'app/indices/directory'
|
26
|
-
# Esse.config.clusters(:v1).client = Elasticsearch::Client.new
|
27
|
-
def self.config
|
28
|
-
@config ||= Config.new
|
29
|
-
yield(@config) if block_given?
|
30
|
-
@config
|
31
|
-
end
|
32
|
-
|
33
26
|
# Unless in single threaded mode, protects access to any mutable
|
34
27
|
# global data structure in Esse.
|
35
28
|
# Uses a non-reentrant mutex, so calling code should be careful.
|
@@ -75,15 +68,4 @@ module Esse
|
|
75
68
|
end
|
76
69
|
[id, modified]
|
77
70
|
end
|
78
|
-
|
79
|
-
require_relative 'config'
|
80
|
-
require_relative 'cluster'
|
81
|
-
require_relative 'primitives'
|
82
|
-
require_relative 'index_type'
|
83
|
-
require_relative 'index_setting'
|
84
|
-
require_relative 'index_mapping'
|
85
|
-
require_relative 'template_loader'
|
86
|
-
require_relative 'backend/index'
|
87
|
-
require_relative 'backend/index_type'
|
88
|
-
require_relative 'version'
|
89
71
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
# @abstract
|
5
|
+
#
|
6
|
+
# A document is a class that represents a single JSON document to be indexed
|
7
|
+
class Document
|
8
|
+
def initialize(entry, **context)
|
9
|
+
@source = item
|
10
|
+
@context = context
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns the Elasticsearch `_id` for the document.
|
14
|
+
#
|
15
|
+
# @return [String, Number] The Elasticsearch `_id` for the document
|
16
|
+
# @abstract
|
17
|
+
def id
|
18
|
+
raise NotImplementedError
|
19
|
+
end
|
20
|
+
|
21
|
+
# Returns the Elasticsearch `_routing` for the item. Elasticsearch
|
22
|
+
# default if this value is not provided is to use the `_id`.
|
23
|
+
# Setting this value to `false` or `nil` will omit sending the
|
24
|
+
# meta-field with your requests and use default routing behaviour.
|
25
|
+
#
|
26
|
+
# @return [String, NilClass, Boolean] The Elasticsearch `_routing` for the document
|
27
|
+
# @abstract
|
28
|
+
def routing
|
29
|
+
end
|
30
|
+
|
31
|
+
def attributes
|
32
|
+
{}
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_h
|
36
|
+
{
|
37
|
+
_id: id,
|
38
|
+
}.tap do |hash|
|
39
|
+
hash[:_routing] = routing if routing
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/lib/esse/errors.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
class Error < StandardError
|
5
|
+
end
|
6
|
+
|
7
|
+
module Events
|
8
|
+
class UnregisteredEventError < ::Esse::Error
|
9
|
+
def initialize(object_or_event_id)
|
10
|
+
case object_or_event_id
|
11
|
+
when String, Symbol
|
12
|
+
super("You are trying to publish an unregistered event: `#{object_or_event_id}`")
|
13
|
+
else
|
14
|
+
super('You are trying to publish an unregistered event')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class InvalidSubscriberError < ::Esse::Error
|
20
|
+
# @api private
|
21
|
+
def initialize(object_or_event_id)
|
22
|
+
case object_or_event_id
|
23
|
+
when String, Symbol
|
24
|
+
super("you are trying to subscribe to an event: `#{object_or_event_id}` that has not been registered")
|
25
|
+
else
|
26
|
+
super('you try use subscriber object that will never be executed')
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module CLI
|
33
|
+
class Error < ::Esse::Error
|
34
|
+
def initialize(msg = nil, **message_attributes)
|
35
|
+
if message_attributes.any?
|
36
|
+
msg = format(msg, **message_attributes)
|
37
|
+
end
|
38
|
+
super(msg)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class InvalidOption < Error
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Elasticsearch::Transport::Transport::Errors::NotFound
|
47
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
module Events
|
5
|
+
# Event bus
|
6
|
+
#
|
7
|
+
# An event bus stores listeners (callbacks) and events
|
8
|
+
#
|
9
|
+
# @api private
|
10
|
+
class Bus
|
11
|
+
# @return [Hash] A hash with events registered within a bus
|
12
|
+
attr_reader :events
|
13
|
+
|
14
|
+
# @return [Hash] A hash with event listeners registered within a bus
|
15
|
+
attr_reader :listeners
|
16
|
+
|
17
|
+
# Initialize a new event bus
|
18
|
+
#
|
19
|
+
# @param [Hash] events A hash with events
|
20
|
+
# @param [Hash] listeners A hash with listeners
|
21
|
+
#
|
22
|
+
# @api private
|
23
|
+
# @idea
|
24
|
+
# Hash is thread-safe in practice because CRuby runs
|
25
|
+
# threads one at a time and does not do context
|
26
|
+
# switching during the execution of C functions
|
27
|
+
# However, in case of jRuby or other ruby interpreters,
|
28
|
+
# this assumption may not be true. In that case, we should
|
29
|
+
# use a different data structure. I think we should use
|
30
|
+
# a Concurrent::Hash or Concurrent::Map object from
|
31
|
+
# concurrent-ruby
|
32
|
+
# @see https://github.com/ruby-concurrency/concurrent-ruby
|
33
|
+
def initialize(events: {}, listeners: Hash.new { |h, k| h[k] = [] })
|
34
|
+
@listeners = listeners
|
35
|
+
@events = events
|
36
|
+
end
|
37
|
+
|
38
|
+
# @api private
|
39
|
+
def publish(event_id, payload)
|
40
|
+
process(event_id, payload) do |event, listener|
|
41
|
+
listener.call(event)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# @api private
|
46
|
+
def attach(listener)
|
47
|
+
events.each do |id, event|
|
48
|
+
method_name = event.listener_method
|
49
|
+
next unless listener.respond_to?(method_name)
|
50
|
+
|
51
|
+
listeners[id] << listener.method(method_name)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# @api private
|
56
|
+
def detach(listener)
|
57
|
+
listeners.each do |id, arr|
|
58
|
+
arr.each do |func|
|
59
|
+
listeners[id].delete(func) if func.receiver == listener
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# @api private
|
65
|
+
def subscribe(event_id, &block)
|
66
|
+
listeners[event_id] << block
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
# @api private
|
71
|
+
def subscribed?(listener)
|
72
|
+
listeners.values.any? { |value| value.any? { |func| func == listener } } || (
|
73
|
+
methods = events.values.map(&:listener_method).select(&listener.method(:respond_to?)).map(&listener.method(:method))
|
74
|
+
methods && listeners.values.any? { |value| (methods & value).size > 0 }
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
# @api private
|
79
|
+
def can_handle?(object_or_event_id)
|
80
|
+
case object_or_event_id
|
81
|
+
when String, Symbol
|
82
|
+
events.key?(object_or_event_id)
|
83
|
+
else
|
84
|
+
events
|
85
|
+
.values
|
86
|
+
.map(&:listener_method)
|
87
|
+
.any?(&object_or_event_id.method(:respond_to?))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
protected
|
92
|
+
|
93
|
+
# @api private
|
94
|
+
def process(event_id, payload)
|
95
|
+
listeners[event_id].each do |listener|
|
96
|
+
event = events[event_id].payload(payload)
|
97
|
+
|
98
|
+
yield(event, listener)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Esse
|
4
|
+
module Events
|
5
|
+
class Event
|
6
|
+
attr_reader :id
|
7
|
+
|
8
|
+
# Initialize a new event
|
9
|
+
#
|
10
|
+
# @param [Symbol, String] id The event identifier
|
11
|
+
# @param [Hash] payload
|
12
|
+
#
|
13
|
+
# @return [Event]
|
14
|
+
#
|
15
|
+
# @api private
|
16
|
+
def initialize(id, payload = {})
|
17
|
+
@id = id
|
18
|
+
@payload = payload
|
19
|
+
end
|
20
|
+
|
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
|
+
# Get or set a payload
|
41
|
+
#
|
42
|
+
# @overload
|
43
|
+
# @return [Hash] payload
|
44
|
+
#
|
45
|
+
# @overload payload(data)
|
46
|
+
# @param [Hash] data A new payload
|
47
|
+
# @return [Event] A copy of the event with the provided payload
|
48
|
+
#
|
49
|
+
# @api public
|
50
|
+
def payload(data = nil)
|
51
|
+
if data
|
52
|
+
self.class.new(id, @payload.merge(data))
|
53
|
+
else
|
54
|
+
@payload
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# @api private
|
59
|
+
def listener_method
|
60
|
+
@listener_method ||= Hstring.new("on_#{id}").underscore.to_sym
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'event'
|
4
|
+
require_relative 'bus'
|
5
|
+
|
6
|
+
module Esse
|
7
|
+
module Events
|
8
|
+
module Publisher
|
9
|
+
def self.included(klass)
|
10
|
+
klass.extend(ClassMethods)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Class interface for publishers
|
14
|
+
#
|
15
|
+
# @api public
|
16
|
+
module ClassMethods
|
17
|
+
# Register a new event type
|
18
|
+
#
|
19
|
+
# @param [Symbol,String] event_id The event identifier
|
20
|
+
# @param [Hash] payload Optional default payload
|
21
|
+
#
|
22
|
+
# @return [self]
|
23
|
+
#
|
24
|
+
# @api public
|
25
|
+
def register_event(event_id, payload = {})
|
26
|
+
__bus__.events[event_id] = Event.new(event_id, payload)
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
# Publish an event
|
31
|
+
#
|
32
|
+
# @param [String] event_id The event identifier
|
33
|
+
# @param [Hash] payload An optional payload
|
34
|
+
# @raise [Esse::Events::UnregisteredEventError] if the event is not registered
|
35
|
+
#
|
36
|
+
# @api public
|
37
|
+
def publish(event_id, payload = {})
|
38
|
+
if __bus__.can_handle?(event_id)
|
39
|
+
__bus__.publish(event_id, payload)
|
40
|
+
self
|
41
|
+
else
|
42
|
+
raise UnregisteredEventError, event_id
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Publish an event with extra runtime information to the payload
|
47
|
+
#
|
48
|
+
# @param [String] event_id The event identifier
|
49
|
+
# @param [Hash] payload An optional payload
|
50
|
+
# @raise [Esse::Events::UnregisteredEventError] if the event is not registered
|
51
|
+
#
|
52
|
+
# @api public
|
53
|
+
def instrument(event_id, payload = {}, &block)
|
54
|
+
publish_event = false # ensure block is also called on error
|
55
|
+
raise(UnregisteredEventError, event_id) unless __bus__.can_handle?(event_id)
|
56
|
+
|
57
|
+
payload[:__started_at__] = Time.now
|
58
|
+
block.call(payload).tap { publish_event = true }
|
59
|
+
ensure
|
60
|
+
if publish_event
|
61
|
+
payload[:runtime] ||= Time.now - payload.delete(:__started_at__) if payload[:__started_at__]
|
62
|
+
__bus__.publish(event_id, payload)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Subscribe to events.
|
67
|
+
#
|
68
|
+
# @param [Symbol,String,Object] object_or_event_id The event identifier or a listener object
|
69
|
+
# @param [Hash] filter_hash An optional event filter
|
70
|
+
#
|
71
|
+
# @raise [Esse::Events::InvalidSubscriberError] if the subscriber is not registered
|
72
|
+
# @return [Object] self
|
73
|
+
#
|
74
|
+
#
|
75
|
+
# @api public
|
76
|
+
def subscribe(object_or_event_id, &block)
|
77
|
+
if __bus__.can_handle?(object_or_event_id)
|
78
|
+
if block
|
79
|
+
__bus__.subscribe(object_or_event_id, &block)
|
80
|
+
else
|
81
|
+
__bus__.attach(object_or_event_id)
|
82
|
+
end
|
83
|
+
|
84
|
+
self
|
85
|
+
else
|
86
|
+
raise InvalidSubscriberError, object_or_event_id
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Unsubscribe a listener
|
91
|
+
#
|
92
|
+
# @param [Object] listener The listener object
|
93
|
+
#
|
94
|
+
# @return [self]
|
95
|
+
#
|
96
|
+
# @api public
|
97
|
+
def unsubscribe(listener)
|
98
|
+
__bus__.detach(listener)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Return true if a given listener has been subscribed to any event
|
102
|
+
#
|
103
|
+
# @api public
|
104
|
+
def subscribed?(listener)
|
105
|
+
__bus__.subscribed?(listener)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Internal event bus
|
109
|
+
#
|
110
|
+
# @return [Bus]
|
111
|
+
#
|
112
|
+
# @api private
|
113
|
+
def __bus__
|
114
|
+
@__bus__ ||= Bus.new
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/lib/esse/events.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'events/publisher'
|
4
|
+
|
5
|
+
module Esse
|
6
|
+
# Extension used for classes that can pub/sub events
|
7
|
+
#
|
8
|
+
# Examples:
|
9
|
+
#
|
10
|
+
# # Publish an event
|
11
|
+
# Esse::Events.publish('elasticsearch.create_index', { definition: {index_name: 'my_index'} })
|
12
|
+
# # Subscribe to an event
|
13
|
+
# Esse::Events.subscribe('elasticsearch.create_index') do |event|
|
14
|
+
# puts event.payload
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# # Publish an event using instrumentation
|
18
|
+
# Esse::Events.instrument('elasticsearch.create_index') do |payload|
|
19
|
+
# payload[:definition] = {index_name: 'my_index'}
|
20
|
+
# # Some slow action
|
21
|
+
# end
|
22
|
+
# Esse::Events.subscribe('elasticsearch.create_index') do |event|
|
23
|
+
# puts event.payload[:runtime] # Extra information about the amount of time the action took
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# # Attach a listener to the event bus
|
27
|
+
# class MyEventListener
|
28
|
+
# def on_elasticsearch_create_index(event)
|
29
|
+
# puts event.payload
|
30
|
+
# end
|
31
|
+
# end
|
32
|
+
# listener = MyEventListener.new
|
33
|
+
# Esse::Events.attach(listener)
|
34
|
+
# # Dettash the listener
|
35
|
+
# Esse::Events.detach(listener)
|
36
|
+
#
|
37
|
+
#
|
38
|
+
module Events
|
39
|
+
include Publisher
|
40
|
+
|
41
|
+
register_event 'elasticsearch.close'
|
42
|
+
register_event 'elasticsearch.open'
|
43
|
+
register_event 'elasticsearch.create_index'
|
44
|
+
register_event 'elasticsearch.delete_index'
|
45
|
+
register_event 'elasticsearch.update_mapping'
|
46
|
+
register_event 'elasticsearch.update_settings'
|
47
|
+
register_event 'elasticsearch.update_aliases'
|
48
|
+
end
|
49
|
+
end
|
data/lib/esse/index/backend.rb
CHANGED
data/lib/esse/index/base.rb
CHANGED
@@ -3,12 +3,10 @@
|
|
3
3
|
module Esse
|
4
4
|
class Index
|
5
5
|
module ClassMethods
|
6
|
-
attr_reader :cluster_id
|
7
|
-
|
8
6
|
# Define a Index method on the given module that calls the Index
|
9
7
|
# method on the receiver. This is how the Esse::Index() method is
|
10
8
|
# defined, and allows you to define Index() methods on other modules,
|
11
|
-
# making it easier to have custom index settings for all
|
9
|
+
# making it easier to have custom index settings for all indices under
|
12
10
|
# a namespace. Example:
|
13
11
|
#
|
14
12
|
# module V1
|
@@ -35,7 +33,7 @@ module Esse
|
|
35
33
|
#
|
36
34
|
# Example:
|
37
35
|
# # Using a custom cluster
|
38
|
-
# Esse.config.
|
36
|
+
# Esse.config.cluster(:v1).client = Elasticsearch::Client.new
|
39
37
|
# class UsersIndex < Esse::Index(:v1)
|
40
38
|
# end
|
41
39
|
#
|
@@ -92,12 +90,12 @@ module Esse
|
|
92
90
|
def cluster
|
93
91
|
unless Esse.config.cluster_ids.include?(cluster_id)
|
94
92
|
raise NotImplementedError, <<~MSG
|
95
|
-
There is no cluster configured for this index. Use `Esse.config.
|
93
|
+
There is no cluster configured for this index. Use `Esse.config.cluster(cluster_id) { ... }' define the elasticsearch
|
96
94
|
client connection.
|
97
95
|
MSG
|
98
96
|
end
|
99
97
|
|
100
|
-
Esse.synchronize { Esse.config.
|
98
|
+
Esse.synchronize { Esse.config.cluster(cluster_id) }
|
101
99
|
end
|
102
100
|
|
103
101
|
def inspect
|
data/lib/esse/index/mappings.rb
CHANGED
@@ -7,7 +7,6 @@
|
|
7
7
|
module Esse
|
8
8
|
class Index
|
9
9
|
module ClassMethods
|
10
|
-
|
11
10
|
# This is the actually content that will be passed through the ES api
|
12
11
|
def mappings_hash
|
13
12
|
{ Esse::MAPPING_ROOT_KEY => (index_mapping || type_mapping) }
|
@@ -16,9 +15,9 @@ module Esse
|
|
16
15
|
# This method is only used to define mapping
|
17
16
|
def mappings(hash = {}, &block)
|
18
17
|
@mapping = Esse::IndexMapping.new(body: hash, paths: template_dirs)
|
19
|
-
return unless
|
18
|
+
return unless block
|
20
19
|
|
21
|
-
@mapping.define_singleton_method(:
|
20
|
+
@mapping.define_singleton_method(:to_h, &block)
|
22
21
|
end
|
23
22
|
|
24
23
|
private
|
data/lib/esse/index/settings.rb
CHANGED
@@ -4,16 +4,15 @@ module Esse
|
|
4
4
|
# https://github.com/elastic/elasticsearch-ruby/blob/master/elasticsearch-api/lib/elasticsearch/api/actions/indices/put_settings.rb
|
5
5
|
class Index
|
6
6
|
module ClassMethods
|
7
|
-
|
8
|
-
|
9
|
-
hash = cluster_settings ? cluster.index_settings.merge(setting.body) : setting.body
|
7
|
+
def settings_hash
|
8
|
+
hash = setting.body
|
10
9
|
{ Esse::SETTING_ROOT_KEY => (hash.key?(Esse::SETTING_ROOT_KEY) ? hash[Esse::SETTING_ROOT_KEY] : hash) }
|
11
10
|
end
|
12
11
|
|
13
12
|
# Define /_settings definition by each index.
|
14
13
|
#
|
15
14
|
# +hash+: The body of the request includes the updated settings.
|
16
|
-
# +block+: Overwrite default :
|
15
|
+
# +block+: Overwrite default :to_h from IndexSetting instance
|
17
16
|
#
|
18
17
|
# Example:
|
19
18
|
#
|
@@ -29,16 +28,16 @@ module Esse
|
|
29
28
|
# end
|
30
29
|
# end
|
31
30
|
def settings(hash = {}, &block)
|
32
|
-
@setting = Esse::IndexSetting.new(body: hash, paths: template_dirs, globals: cluster.index_settings)
|
33
|
-
return unless
|
31
|
+
@setting = Esse::IndexSetting.new(body: hash, paths: template_dirs, globals: -> { cluster.index_settings })
|
32
|
+
return unless block
|
34
33
|
|
35
|
-
@setting.define_singleton_method(:
|
34
|
+
@setting.define_singleton_method(:to_h, &block)
|
36
35
|
end
|
37
36
|
|
38
37
|
private
|
39
38
|
|
40
39
|
def setting
|
41
|
-
@setting ||= Esse::IndexSetting.new(paths: template_dirs, globals: cluster.index_settings)
|
40
|
+
@setting ||= Esse::IndexSetting.new(paths: template_dirs, globals: -> { cluster.index_settings })
|
42
41
|
end
|
43
42
|
end
|
44
43
|
|