elastomer-client 0.7.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.overcommit.yml +5 -0
- data/.rubocop.yml +83 -0
- data/CHANGELOG.md +8 -0
- data/Gemfile +2 -2
- data/README.md +1 -1
- data/Rakefile +2 -2
- data/elastomer-client.gemspec +4 -2
- data/lib/elastomer/client.rb +42 -37
- data/lib/elastomer/client/bulk.rb +2 -2
- data/lib/elastomer/client/cluster.rb +19 -19
- data/lib/elastomer/client/delete_by_query.rb +7 -7
- data/lib/elastomer/client/docs.rb +81 -24
- data/lib/elastomer/client/errors.rb +2 -2
- data/lib/elastomer/client/index.rb +65 -29
- data/lib/elastomer/client/multi_percolate.rb +127 -0
- data/lib/elastomer/client/multi_search.rb +2 -2
- data/lib/elastomer/client/nodes.rb +4 -4
- data/lib/elastomer/client/percolator.rb +77 -0
- data/lib/elastomer/client/repository.rb +7 -7
- data/lib/elastomer/client/scroller.rb +14 -14
- data/lib/elastomer/client/snapshot.rb +9 -9
- data/lib/elastomer/client/template.rb +3 -3
- data/lib/elastomer/client/warmer.rb +5 -16
- data/lib/elastomer/core_ext/time.rb +1 -1
- data/lib/elastomer/middleware/encode_json.rb +5 -5
- data/lib/elastomer/middleware/opaque_id.rb +3 -3
- data/lib/elastomer/middleware/parse_json.rb +5 -5
- data/lib/elastomer/notifications.rb +4 -4
- data/lib/elastomer/version.rb +1 -1
- data/script/bootstrap +2 -0
- data/script/console +5 -5
- data/test/assertions.rb +26 -24
- data/test/client/bulk_test.rb +111 -111
- data/test/client/cluster_test.rb +58 -58
- data/test/client/delete_by_query_test.rb +53 -53
- data/test/client/docs_test.rb +279 -203
- data/test/client/errors_test.rb +1 -1
- data/test/client/index_test.rb +143 -109
- data/test/client/multi_percolate_test.rb +130 -0
- data/test/client/multi_search_test.rb +30 -28
- data/test/client/nodes_test.rb +30 -29
- data/test/client/percolator_test.rb +52 -0
- data/test/client/repository_test.rb +23 -23
- data/test/client/scroller_test.rb +40 -40
- data/test/client/snapshot_test.rb +15 -15
- data/test/client/stubbed_client_test.rb +15 -15
- data/test/client/template_test.rb +10 -10
- data/test/client/warmer_test.rb +18 -18
- data/test/client_test.rb +53 -53
- data/test/core_ext/time_test.rb +12 -12
- data/test/middleware/encode_json_test.rb +20 -20
- data/test/middleware/opaque_id_test.rb +10 -10
- data/test/middleware/parse_json_test.rb +14 -14
- data/test/notifications_test.rb +32 -32
- data/test/test_helper.rb +24 -24
- metadata +38 -2
@@ -0,0 +1,127 @@
|
|
1
|
+
module Elastomer
|
2
|
+
class Client
|
3
|
+
|
4
|
+
# Execute an array of percolate actions in bulk. Results are returned in an
|
5
|
+
# array in the order the actions were sent.
|
6
|
+
#
|
7
|
+
# The `multi_percolate` method can be used in two ways. Without a block
|
8
|
+
# the method will perform an API call, and it requires a bulk request
|
9
|
+
# body and optional request parameters.
|
10
|
+
#
|
11
|
+
# See https://www.elastic.co/guide/en/elasticsearch/reference/current/search-percolate.html#_multi_percolate_api
|
12
|
+
#
|
13
|
+
# body - Request body as a String (required if a block is not given)
|
14
|
+
# params - Optional request parameters as a Hash
|
15
|
+
# block - Passed to a MultiPercolate instance which assembles the
|
16
|
+
# percolate actions into a single request.
|
17
|
+
#
|
18
|
+
# Examples
|
19
|
+
#
|
20
|
+
# # index and type in request body
|
21
|
+
# multi_percolate(request_body)
|
22
|
+
#
|
23
|
+
# # index in URI
|
24
|
+
# multi_percolate(request_body, :index => 'default-index')
|
25
|
+
#
|
26
|
+
# # block form
|
27
|
+
# multi_percolate(:index => 'default-index') do |m|
|
28
|
+
# m.percolate({ :author => "pea53" }, { :type => 'default-type' })
|
29
|
+
# m.count({ :author => "pea53" }, { :type => 'type2' })
|
30
|
+
# ...
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
# Returns the response body as a Hash
|
34
|
+
def multi_percolate(body = nil, params = nil)
|
35
|
+
if block_given?
|
36
|
+
params, body = (body || {}), nil
|
37
|
+
yield mpercolate_obj = MultiPercolate.new(self, params)
|
38
|
+
mpercolate_obj.call
|
39
|
+
else
|
40
|
+
raise "multi_percolate request body cannot be nil" if body.nil?
|
41
|
+
params ||= {}
|
42
|
+
|
43
|
+
response = self.post "{/index}{/type}/_mpercolate", params.merge(:body => body)
|
44
|
+
response.body
|
45
|
+
end
|
46
|
+
end
|
47
|
+
alias_method :mpercolate, :multi_percolate
|
48
|
+
|
49
|
+
# The MultiPercolate class is a helper for accumulating and submitting
|
50
|
+
# multi_percolate API requests. Instances of the MultiPercolate class
|
51
|
+
# accumulate percolate actions and then issue a single API request to
|
52
|
+
# Elasticsearch, which runs all accumulated percolate actions in parallel
|
53
|
+
# and returns each result hash aggregated into an array of result
|
54
|
+
# hashes.
|
55
|
+
#
|
56
|
+
# Instead of instantiating this class directly, use
|
57
|
+
# the block form of Client#multi_percolate.
|
58
|
+
#
|
59
|
+
class MultiPercolate
|
60
|
+
|
61
|
+
# Create a new MultiPercolate instance for accumulating percolate actions
|
62
|
+
# and submitting them all as a single request.
|
63
|
+
#
|
64
|
+
# client - Elastomer::Client used for HTTP requests to the server
|
65
|
+
# params - Parameters Hash to pass to the Client#multi_percolate method
|
66
|
+
def initialize(client, params = {})
|
67
|
+
@client = client
|
68
|
+
@params = params
|
69
|
+
|
70
|
+
@actions = []
|
71
|
+
end
|
72
|
+
|
73
|
+
attr_reader :client
|
74
|
+
|
75
|
+
# Add a percolate action to the multi percolate request. This percolate
|
76
|
+
# action will not be executed until the multi_percolate API call is made.
|
77
|
+
#
|
78
|
+
# header - A Hash of the index and type, if not provided in the params
|
79
|
+
# doc - A Hash of the document
|
80
|
+
#
|
81
|
+
# Returns this MultiPercolate instance.
|
82
|
+
def percolate(doc, header = {})
|
83
|
+
add_to_actions(:percolate => header)
|
84
|
+
add_to_actions(:doc => doc)
|
85
|
+
end
|
86
|
+
|
87
|
+
# Add a percolate acount action to the multi percolate request. This
|
88
|
+
# percolate count action will not be executed until the multi_percolate
|
89
|
+
# API call is made.
|
90
|
+
#
|
91
|
+
# header - A Hash of the index and type, if not provided in the params
|
92
|
+
# doc - A Hash of the document
|
93
|
+
#
|
94
|
+
# Returns this MultiPercolate instance.
|
95
|
+
def count(doc, header = {})
|
96
|
+
add_to_actions(:count => header)
|
97
|
+
add_to_actions(:doc => doc)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Execute the multi_percolate call with the accumulated percolate actions.
|
101
|
+
# If the accumulated actions list is empty then no action is taken.
|
102
|
+
#
|
103
|
+
# Returns the response body Hash.
|
104
|
+
def call
|
105
|
+
return if @actions.empty?
|
106
|
+
|
107
|
+
body = @actions.join("\n") + "\n"
|
108
|
+
client.multi_percolate(body, @params)
|
109
|
+
ensure
|
110
|
+
@actions.clear
|
111
|
+
end
|
112
|
+
|
113
|
+
# Internal: Add an action to the pending request. Actions can be
|
114
|
+
# either headers or bodies. The first action must be a percolate header,
|
115
|
+
# followed by a body, then alternating headers and bodies.
|
116
|
+
#
|
117
|
+
# action - the Hash (header or body) to add to the pending request
|
118
|
+
#
|
119
|
+
# Returns this MultiPercolate instance.
|
120
|
+
def add_to_actions(action)
|
121
|
+
action = MultiJson.dump action
|
122
|
+
@actions << action
|
123
|
+
self
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -37,10 +37,10 @@ module Elastomer
|
|
37
37
|
yield msearch_obj = MultiSearch.new(self, params)
|
38
38
|
msearch_obj.call
|
39
39
|
else
|
40
|
-
raise
|
40
|
+
raise "multi_search request body cannot be nil" if body.nil?
|
41
41
|
params ||= {}
|
42
42
|
|
43
|
-
response = self.post
|
43
|
+
response = self.post "{/index}{/type}/_msearch", params.merge(:body => body)
|
44
44
|
response.body
|
45
45
|
end
|
46
46
|
end
|
@@ -49,7 +49,7 @@ module Elastomer
|
|
49
49
|
#
|
50
50
|
# Returns the response as a Hash
|
51
51
|
def info( params = {} )
|
52
|
-
response = client.get
|
52
|
+
response = client.get "/_nodes{/node_id}{/info}", update_params(params, :action => "nodes.info")
|
53
53
|
response.body
|
54
54
|
end
|
55
55
|
|
@@ -69,7 +69,7 @@ module Elastomer
|
|
69
69
|
#
|
70
70
|
# Returns the response as a Hash
|
71
71
|
def stats( params = {} )
|
72
|
-
response = client.get
|
72
|
+
response = client.get "/_nodes{/node_id}/stats{/stats}", update_params(params, :action => "nodes.stats")
|
73
73
|
response.body
|
74
74
|
end
|
75
75
|
|
@@ -87,7 +87,7 @@ module Elastomer
|
|
87
87
|
#
|
88
88
|
# Returns the response as a String
|
89
89
|
def hot_threads( params = {} )
|
90
|
-
response = client.get
|
90
|
+
response = client.get "/_nodes{/node_id}/hot_threads", update_params(params, :action => "nodes.hot_threads")
|
91
91
|
response.body
|
92
92
|
end
|
93
93
|
|
@@ -101,7 +101,7 @@ module Elastomer
|
|
101
101
|
#
|
102
102
|
# Returns the response as a Hash
|
103
103
|
def shutdown( params = {} )
|
104
|
-
response = client.post
|
104
|
+
response = client.post "/_cluster/nodes{/node_id}/_shutdown", update_params(params, :action => "nodes.shutdown")
|
105
105
|
response.body
|
106
106
|
end
|
107
107
|
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Elastomer
|
2
|
+
class Client
|
3
|
+
|
4
|
+
class Percolator
|
5
|
+
|
6
|
+
# Create a new Percolator for managing a query.
|
7
|
+
#
|
8
|
+
# client - Elastomer::Client used for HTTP requests to the server
|
9
|
+
# index_name - The index name
|
10
|
+
# id - The _id for the query
|
11
|
+
def initialize(client, index_name, id)
|
12
|
+
@client = client
|
13
|
+
@index_name = client.assert_param_presence(index_name, "index name")
|
14
|
+
@id = client.assert_param_presence(id, "id")
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :client, :index_name, :id
|
18
|
+
|
19
|
+
# Create a percolator query.
|
20
|
+
#
|
21
|
+
# Examples
|
22
|
+
#
|
23
|
+
# percolator = $client.index("default-index").percolator "1"
|
24
|
+
# percolator.create :query => { :match_all => { } }
|
25
|
+
#
|
26
|
+
# Returns the response body as a Hash
|
27
|
+
def create(body, params = {})
|
28
|
+
response = client.put("/{index}/.percolator/{id}", defaults.merge(params.merge(:body => body, :action => "percolator.create")))
|
29
|
+
response.body
|
30
|
+
end
|
31
|
+
|
32
|
+
# Gets a percolator query.
|
33
|
+
#
|
34
|
+
# Examples
|
35
|
+
#
|
36
|
+
# percolator = $client.index("default-index").percolator "1"
|
37
|
+
# percolator.get
|
38
|
+
#
|
39
|
+
# Returns the response body as a Hash
|
40
|
+
def get(params = {})
|
41
|
+
response = client.get("/{index}/.percolator/{id}", defaults.merge(params.merge(:action => "percolator.get")))
|
42
|
+
response.body
|
43
|
+
end
|
44
|
+
|
45
|
+
# Delete a percolator query.
|
46
|
+
#
|
47
|
+
# Examples
|
48
|
+
#
|
49
|
+
# percolator = $client.index("default-index").percolator "1"
|
50
|
+
# percolator.delete
|
51
|
+
#
|
52
|
+
# Returns the response body as a Hash
|
53
|
+
def delete(params = {})
|
54
|
+
response = client.delete("/{index}/.percolator/{id}", defaults.merge(params.merge(:action => "percolator.delete")))
|
55
|
+
response.body
|
56
|
+
end
|
57
|
+
|
58
|
+
# Checks for the existence of a percolator query.
|
59
|
+
#
|
60
|
+
# Examples
|
61
|
+
#
|
62
|
+
# percolator = $client.index("default-index").percolator "1"
|
63
|
+
# percolator.exists?
|
64
|
+
#
|
65
|
+
# Returns a boolean
|
66
|
+
def exists?(params = {})
|
67
|
+
get(params)["found"]
|
68
|
+
end
|
69
|
+
|
70
|
+
# Internal: Returns a Hash containing default parameters.
|
71
|
+
def defaults
|
72
|
+
{:index => index_name, :id => id}
|
73
|
+
end
|
74
|
+
|
75
|
+
end # Percolator
|
76
|
+
end # Client
|
77
|
+
end # Elastomer
|
@@ -14,7 +14,7 @@ module Elastomer
|
|
14
14
|
# name - The name of the index as a String or an Array of names
|
15
15
|
def initialize(client, name = nil)
|
16
16
|
@client = client
|
17
|
-
@name = @client.assert_param_presence(name,
|
17
|
+
@name = @client.assert_param_presence(name, "repository name") unless name.nil?
|
18
18
|
end
|
19
19
|
|
20
20
|
attr_reader :client, :name
|
@@ -26,7 +26,7 @@ module Elastomer
|
|
26
26
|
#
|
27
27
|
# Returns true if the repository exists
|
28
28
|
def exists?(params = {})
|
29
|
-
response = client.get
|
29
|
+
response = client.get "/_snapshot{/repository}", update_params(params, :action => "repository.exists")
|
30
30
|
response.success?
|
31
31
|
rescue Elastomer::Client::Error => exception
|
32
32
|
if exception.message =~ /RepositoryMissingException/
|
@@ -45,7 +45,7 @@ module Elastomer
|
|
45
45
|
#
|
46
46
|
# Returns the response body as a Hash
|
47
47
|
def create(body, params = {})
|
48
|
-
response = client.put
|
48
|
+
response = client.put "/_snapshot/{repository}", update_params(params, :body => body, :action => "repository.create")
|
49
49
|
response.body
|
50
50
|
end
|
51
51
|
|
@@ -56,7 +56,7 @@ module Elastomer
|
|
56
56
|
#
|
57
57
|
# Returns the response body as a Hash
|
58
58
|
def get(params = {})
|
59
|
-
response = client.get
|
59
|
+
response = client.get "/_snapshot{/repository}", update_params(params, :action => "repository.get")
|
60
60
|
response.body
|
61
61
|
end
|
62
62
|
|
@@ -67,7 +67,7 @@ module Elastomer
|
|
67
67
|
#
|
68
68
|
# Returns the response body as a Hash
|
69
69
|
def status(params = {})
|
70
|
-
response = client.get
|
70
|
+
response = client.get "/_snapshot{/repository}/_status", update_params(params, :action => "repository.status")
|
71
71
|
response.body
|
72
72
|
end
|
73
73
|
|
@@ -79,7 +79,7 @@ module Elastomer
|
|
79
79
|
#
|
80
80
|
# Returns the response body as a Hash
|
81
81
|
def update(body, params = {})
|
82
|
-
response = client.put
|
82
|
+
response = client.put "/_snapshot/{repository}", update_params(params, :body => body, :action => "repository.update")
|
83
83
|
response.body
|
84
84
|
end
|
85
85
|
|
@@ -90,7 +90,7 @@ module Elastomer
|
|
90
90
|
#
|
91
91
|
# Returns the response body as a Hash
|
92
92
|
def delete(params = {})
|
93
|
-
response = client.delete
|
93
|
+
response = client.delete "/_snapshot/{repository}", update_params(params, :action => "repository.delete")
|
94
94
|
response.body
|
95
95
|
end
|
96
96
|
|
@@ -43,7 +43,7 @@ module Elastomer
|
|
43
43
|
#
|
44
44
|
# Returns a new Scroller instance
|
45
45
|
def scan( query, opts = {} )
|
46
|
-
opts = opts.merge(:search_type =>
|
46
|
+
opts = opts.merge(:search_type => "scan")
|
47
47
|
Scroller.new(self, query, opts)
|
48
48
|
end
|
49
49
|
|
@@ -72,8 +72,8 @@ module Elastomer
|
|
72
72
|
#
|
73
73
|
# Returns the response body as a Hash.
|
74
74
|
def start_scroll( opts = {} )
|
75
|
-
opts = opts.merge :action =>
|
76
|
-
response = get
|
75
|
+
opts = opts.merge :action => "search.start_scroll"
|
76
|
+
response = get "{/index}{/type}/_search", opts
|
77
77
|
response.body
|
78
78
|
end
|
79
79
|
|
@@ -96,15 +96,15 @@ module Elastomer
|
|
96
96
|
# # repeat until the results are empty
|
97
97
|
#
|
98
98
|
# Returns the response body as a Hash.
|
99
|
-
def continue_scroll( scroll_id, scroll =
|
100
|
-
response = get
|
99
|
+
def continue_scroll( scroll_id, scroll = "5m" )
|
100
|
+
response = get "/_search/scroll", :body => scroll_id, :scroll => scroll, :action => "search.scroll"
|
101
101
|
response.body
|
102
102
|
end
|
103
103
|
|
104
104
|
DEFAULT_OPTS = {
|
105
105
|
:index => nil,
|
106
106
|
:type => nil,
|
107
|
-
:scroll =>
|
107
|
+
:scroll => "5m",
|
108
108
|
:size => 50,
|
109
109
|
}.freeze
|
110
110
|
|
@@ -165,11 +165,11 @@ module Elastomer
|
|
165
165
|
loop do
|
166
166
|
body = do_scroll
|
167
167
|
|
168
|
-
hits = body[
|
169
|
-
break if hits[
|
168
|
+
hits = body["hits"]
|
169
|
+
break if hits["hits"].empty?
|
170
170
|
|
171
|
-
hits[
|
172
|
-
@offset += hits[
|
171
|
+
hits["offset"] = @offset
|
172
|
+
@offset += hits["hits"].length
|
173
173
|
|
174
174
|
yield hits
|
175
175
|
end
|
@@ -195,7 +195,7 @@ module Elastomer
|
|
195
195
|
#
|
196
196
|
# Returns this Scan instance.
|
197
197
|
def each_document( &block )
|
198
|
-
each { |hits| hits[
|
198
|
+
each { |hits| hits["hits"].each(&block) }
|
199
199
|
end
|
200
200
|
|
201
201
|
# Internal: Perform the actual scroll requests. This method wil call out
|
@@ -206,15 +206,15 @@ module Elastomer
|
|
206
206
|
def do_scroll
|
207
207
|
if scroll_id.nil?
|
208
208
|
body = client.start_scroll(@opts)
|
209
|
-
if body[
|
210
|
-
@scroll_id = body[
|
209
|
+
if body["hits"]["hits"].empty?
|
210
|
+
@scroll_id = body["_scroll_id"]
|
211
211
|
return do_scroll
|
212
212
|
end
|
213
213
|
else
|
214
214
|
body = client.continue_scroll(scroll_id, @opts[:scroll])
|
215
215
|
end
|
216
216
|
|
217
|
-
@scroll_id = body[
|
217
|
+
@scroll_id = body["_scroll_id"]
|
218
218
|
body
|
219
219
|
end
|
220
220
|
|
@@ -22,8 +22,8 @@ module Elastomer
|
|
22
22
|
def initialize(client, repository = nil, name = nil)
|
23
23
|
@client = client
|
24
24
|
# don't allow nil repository if snapshot name is not nil
|
25
|
-
@repository = @client.assert_param_presence(repository,
|
26
|
-
@name = @client.assert_param_presence(name,
|
25
|
+
@repository = @client.assert_param_presence(repository, "repository name") unless repository.nil? && name.nil?
|
26
|
+
@name = @client.assert_param_presence(name, "snapshot name") unless name.nil?
|
27
27
|
end
|
28
28
|
|
29
29
|
attr_reader :client, :repository, :name
|
@@ -35,7 +35,7 @@ module Elastomer
|
|
35
35
|
#
|
36
36
|
# Returns true if the snapshot exists
|
37
37
|
def exists?(params = {})
|
38
|
-
response = client.get
|
38
|
+
response = client.get "/_snapshot/{repository}/{snapshot}", update_params(params, :action => "snapshot.exists")
|
39
39
|
response.success?
|
40
40
|
rescue Elastomer::Client::Error => exception
|
41
41
|
if exception.message =~ /SnapshotMissingException/
|
@@ -54,7 +54,7 @@ module Elastomer
|
|
54
54
|
#
|
55
55
|
# Returns the response body as a Hash
|
56
56
|
def create(body = {}, params = {})
|
57
|
-
response = client.put
|
57
|
+
response = client.put "/_snapshot/{repository}/{snapshot}", update_params(params, :body => body, :action => "snapshot.create")
|
58
58
|
response.body
|
59
59
|
end
|
60
60
|
|
@@ -66,8 +66,8 @@ module Elastomer
|
|
66
66
|
# Returns the response body as a Hash
|
67
67
|
def get(params = {})
|
68
68
|
# Set snapshot name or we'll get the repository instead
|
69
|
-
snapshot = name ||
|
70
|
-
response = client.get
|
69
|
+
snapshot = name || "_all"
|
70
|
+
response = client.get "/_snapshot/{repository}/{snapshot}", update_params(params, :snapshot => snapshot, :action => "snapshot.get")
|
71
71
|
response.body
|
72
72
|
end
|
73
73
|
|
@@ -78,7 +78,7 @@ module Elastomer
|
|
78
78
|
#
|
79
79
|
# Returns the response body as a Hash
|
80
80
|
def status(params = {})
|
81
|
-
response = client.get
|
81
|
+
response = client.get "/_snapshot{/repository}{/snapshot}/_status", update_params(params, :action => "snapshot.status")
|
82
82
|
response.body
|
83
83
|
end
|
84
84
|
|
@@ -90,7 +90,7 @@ module Elastomer
|
|
90
90
|
#
|
91
91
|
# Returns the response body as a Hash
|
92
92
|
def restore(body = {}, params = {})
|
93
|
-
response = client.post
|
93
|
+
response = client.post "/_snapshot/{repository}/{snapshot}/_restore", update_params(params, :body => body, :action => "snapshot.restore")
|
94
94
|
response.body
|
95
95
|
end
|
96
96
|
|
@@ -101,7 +101,7 @@ module Elastomer
|
|
101
101
|
#
|
102
102
|
# Returns the response body as a Hash
|
103
103
|
def delete(params = {})
|
104
|
-
response = client.delete
|
104
|
+
response = client.delete "/_snapshot/{repository}/{snapshot}", update_params(params, :action => "snapshot.delete")
|
105
105
|
response.body
|
106
106
|
end
|
107
107
|
|