elastomer-client 3.0.1 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +4 -0
- data/lib/elastomer/client/bulk.rb +1 -1
- data/lib/elastomer/client/cluster.rb +10 -22
- data/lib/elastomer/client/docs.rb +46 -55
- data/lib/elastomer/client/index.rb +33 -33
- data/lib/elastomer/client/multi_percolate.rb +9 -9
- data/lib/elastomer/client/multi_search.rb +5 -5
- data/lib/elastomer/client/native_delete_by_query.rb +2 -22
- data/lib/elastomer/client/nodes.rb +8 -22
- data/lib/elastomer/client/percolator.rb +5 -5
- data/lib/elastomer/client/repository.rb +7 -7
- data/lib/elastomer/client/rest_api_spec/api_spec.rb +119 -0
- data/lib/elastomer/client/rest_api_spec/api_spec_v2_3.rb +2232 -0
- data/lib/elastomer/client/rest_api_spec/api_spec_v2_4.rb +2250 -0
- data/lib/elastomer/client/rest_api_spec/api_spec_v5_6.rb +2491 -0
- data/lib/elastomer/client/rest_api_spec/rest_api.rb +59 -0
- data/lib/elastomer/client/rest_api_spec.rb +44 -0
- data/lib/elastomer/client/scroller.rb +10 -10
- data/lib/elastomer/client/snapshot.rb +7 -7
- data/lib/elastomer/client/tasks.rb +45 -51
- data/lib/elastomer/client/template.rb +8 -8
- data/lib/elastomer/client/warmer.rb +11 -4
- data/lib/elastomer/client.rb +31 -7
- data/lib/elastomer/version.rb +1 -1
- data/lib/elastomer/version_support.rb +35 -46
- data/script/generate-rest-api-spec +152 -0
- data/test/client/rest_api_spec/api_spec_test.rb +55 -0
- data/test/client/rest_api_spec/rest_api_test.rb +96 -0
- data/test/client/stubbed_client_test.rb +1 -19
- data/test/middleware/opaque_id_test.rb +1 -3
- data/test/notifications_test.rb +0 -5
- data/test/test_helper.rb +5 -4
- data/test/version_support_test.rb +3 -21
- metadata +13 -2
@@ -0,0 +1,59 @@
|
|
1
|
+
require "forwardable"
|
2
|
+
|
3
|
+
module Elastomer::Client::RestApiSpec
|
4
|
+
class RestApi
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
attr_reader :documentation
|
8
|
+
attr_reader :methods
|
9
|
+
attr_reader :url
|
10
|
+
attr_reader :body
|
11
|
+
|
12
|
+
def_delegators :@url,
|
13
|
+
:select_parts, :select_params, :valid_part?, :valid_param?
|
14
|
+
|
15
|
+
def initialize(documentation:, methods:, url:, body: nil)
|
16
|
+
@documentation = documentation
|
17
|
+
@methods = Array(methods)
|
18
|
+
@url = Url.new(url)
|
19
|
+
@body = body
|
20
|
+
end
|
21
|
+
|
22
|
+
def body?
|
23
|
+
!body.nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
class Url
|
27
|
+
attr_reader :path
|
28
|
+
attr_reader :paths
|
29
|
+
attr_reader :parts
|
30
|
+
attr_reader :params
|
31
|
+
|
32
|
+
def initialize(path:, paths: [], parts: {}, params: {})
|
33
|
+
@path = path
|
34
|
+
@paths = Array(paths)
|
35
|
+
@parts = parts
|
36
|
+
@params = params
|
37
|
+
|
38
|
+
@parts_set = Set.new(@parts.keys)
|
39
|
+
@params_set = Set.new(@params.keys)
|
40
|
+
end
|
41
|
+
|
42
|
+
def select_parts(from:)
|
43
|
+
from.select {|k,v| valid_part?(k)}
|
44
|
+
end
|
45
|
+
|
46
|
+
def valid_part?(part)
|
47
|
+
@parts_set.include?(part.to_s)
|
48
|
+
end
|
49
|
+
|
50
|
+
def select_params(from:)
|
51
|
+
from.select {|k,v| valid_param?(k)}
|
52
|
+
end
|
53
|
+
|
54
|
+
def valid_param?(param)
|
55
|
+
@params_set.include?(param.to_s)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
module Elastomer
|
3
|
+
class Client
|
4
|
+
|
5
|
+
# Provides access to the versioned REST API specs for Elasticsearch.
|
6
|
+
module RestApiSpec
|
7
|
+
|
8
|
+
# Returns an ApiSpec instance for the given Elasticsearcion version. This
|
9
|
+
# method will load the ApiSpec version class if it has not already been
|
10
|
+
# defined. This prevents bloat by only loading the version specs that are
|
11
|
+
# needed.
|
12
|
+
#
|
13
|
+
# Because of this lazy loading, this method is _not_ thread safe.
|
14
|
+
#
|
15
|
+
# version - the Elasticsearch version String
|
16
|
+
#
|
17
|
+
# Returns the requested ApiSpec version if available
|
18
|
+
def self.api_spec(version)
|
19
|
+
classname = "ApiSpecV#{to_class_version(version)}"
|
20
|
+
load_api_spec(version) if !self.const_defined? classname
|
21
|
+
self.const_get(classname).new
|
22
|
+
end
|
23
|
+
|
24
|
+
# Internal: Load the specific ApiSpec version class for the given version.
|
25
|
+
def self.load_api_spec(version)
|
26
|
+
path = File.expand_path("../rest_api_spec/api_spec_v#{to_class_version(version)}.rb", __FILE__)
|
27
|
+
if File.exist? path
|
28
|
+
load path
|
29
|
+
else
|
30
|
+
raise RuntimeError, "Unsupported REST API spec version: #{version}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Internal: Convert a dotted version String into an underscore format
|
35
|
+
# suitable for use in Ruby class names.
|
36
|
+
def self.to_class_version(version)
|
37
|
+
version.to_s.split(".").slice(0,2).join("_")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
require_relative "rest_api_spec/api_spec"
|
44
|
+
require_relative "rest_api_spec/rest_api"
|
@@ -12,7 +12,7 @@ module Elastomer
|
|
12
12
|
#
|
13
13
|
# Examples
|
14
14
|
#
|
15
|
-
# scroll = client.scroll('{"query":{"match_all":{}}}', :
|
15
|
+
# scroll = client.scroll('{"query":{"match_all":{}}}', index: 'test')
|
16
16
|
# scroll.each_document do |document|
|
17
17
|
# document['_id']
|
18
18
|
# document['_source']
|
@@ -35,7 +35,7 @@ module Elastomer
|
|
35
35
|
#
|
36
36
|
# Examples
|
37
37
|
#
|
38
|
-
# scan = client.scan('{"query":{"match_all":{}}}', :
|
38
|
+
# scan = client.scan('{"query":{"match_all":{}}}', index: 'test')
|
39
39
|
# scan.each_document do |document|
|
40
40
|
# document['_id']
|
41
41
|
# document['_source']
|
@@ -59,7 +59,7 @@ module Elastomer
|
|
59
59
|
#
|
60
60
|
# Examples
|
61
61
|
#
|
62
|
-
# h = client.start_scroll(:
|
62
|
+
# h = client.start_scroll(body: '{"query":{"match_all":{}},"sort":{"created":"desc"}}', index: 'test')
|
63
63
|
# scroll_id = h['_scroll_id']
|
64
64
|
# h['hits']['hits'].each { |doc| ... }
|
65
65
|
#
|
@@ -71,7 +71,7 @@ module Elastomer
|
|
71
71
|
#
|
72
72
|
# Returns the response body as a Hash.
|
73
73
|
def start_scroll( opts = {} )
|
74
|
-
opts = opts.merge :
|
74
|
+
opts = opts.merge action: "search.start_scroll", rest_api: "search"
|
75
75
|
response = get "{/index}{/type}/_search", opts
|
76
76
|
response.body
|
77
77
|
end
|
@@ -84,7 +84,7 @@ module Elastomer
|
|
84
84
|
#
|
85
85
|
# Examples
|
86
86
|
#
|
87
|
-
# scroll_id = client.start_scroll(:
|
87
|
+
# scroll_id = client.start_scroll(body: '{"query":{"match_all":{}}}', index: 'test')['_scroll_id']
|
88
88
|
#
|
89
89
|
# h = client.continue_scroll scroll_id # scroll to get the next set of results
|
90
90
|
# scroll_id = h['_scroll_id'] # and store the scroll_id to use later
|
@@ -96,7 +96,7 @@ module Elastomer
|
|
96
96
|
#
|
97
97
|
# Returns the response body as a Hash.
|
98
98
|
def continue_scroll( scroll_id, scroll = "5m" )
|
99
|
-
response = get "/_search/scroll", :
|
99
|
+
response = get "/_search/scroll", body: {scroll_id: scroll_id}, scroll: scroll, action: "search.scroll", rest_api: "scroll"
|
100
100
|
response.body
|
101
101
|
rescue RequestError => err
|
102
102
|
if err.error && err.error["caused_by"]["type"] == "search_context_missing_exception"
|
@@ -113,7 +113,7 @@ module Elastomer
|
|
113
113
|
#
|
114
114
|
# Returns the response body as a Hash.
|
115
115
|
def clear_scroll( scroll_ids )
|
116
|
-
response = delete "/_search/scroll", :
|
116
|
+
response = delete "/_search/scroll", body: {scroll_id: Array(scroll_ids)}, action: "search.clear_scroll", rest_api: "clear_scroll"
|
117
117
|
response.body
|
118
118
|
end
|
119
119
|
|
@@ -132,7 +132,7 @@ module Elastomer
|
|
132
132
|
raise ArgumentError, "Query cannot contain a sort (found sort '#{query[:sort]}' in query: #{query})"
|
133
133
|
end
|
134
134
|
|
135
|
-
query.merge(:
|
135
|
+
query.merge(sort: [:_doc])
|
136
136
|
end
|
137
137
|
|
138
138
|
DEFAULT_OPTS = {
|
@@ -161,7 +161,7 @@ module Elastomer
|
|
161
161
|
#
|
162
162
|
# Examples
|
163
163
|
#
|
164
|
-
# scan = Scroller.new(client, {:
|
164
|
+
# scan = Scroller.new(client, {query: {match_all: {}}}, index: 'test-1')
|
165
165
|
# scan.each_document { |doc|
|
166
166
|
# doc['_id']
|
167
167
|
# doc['_source']
|
@@ -170,7 +170,7 @@ module Elastomer
|
|
170
170
|
def initialize( client, query, opts = {} )
|
171
171
|
@client = client
|
172
172
|
|
173
|
-
@opts = DEFAULT_OPTS.merge({ :
|
173
|
+
@opts = DEFAULT_OPTS.merge({ body: query }).merge(opts)
|
174
174
|
|
175
175
|
@scroll_id = nil
|
176
176
|
@offset = 0
|
@@ -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 "/_snapshot/{repository}/{snapshot}", update_params(params, :
|
38
|
+
response = client.get "/_snapshot/{repository}/{snapshot}", update_params(params, action: "snapshot.exists", rest_api: "snapshot.get")
|
39
39
|
response.success?
|
40
40
|
rescue Elastomer::Client::Error => err
|
41
41
|
if err.error && err.error.dig("root_cause", 0, "type") == "snapshot_missing_exception"
|
@@ -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 "/_snapshot/{repository}/{snapshot}", update_params(params, :body
|
57
|
+
response = client.put "/_snapshot/{repository}/{snapshot}", update_params(params, body: body, action: "snapshot.create", rest_api: "snapshot.create")
|
58
58
|
response.body
|
59
59
|
end
|
60
60
|
|
@@ -67,7 +67,7 @@ module Elastomer
|
|
67
67
|
def get(params = {})
|
68
68
|
# Set snapshot name or we'll get the repository instead
|
69
69
|
snapshot = name || "_all"
|
70
|
-
response = client.get "/_snapshot/{repository}/{snapshot}", update_params(params, :snapshot
|
70
|
+
response = client.get "/_snapshot/{repository}/{snapshot}", update_params(params, snapshot: snapshot, action: "snapshot.get", rest_api: "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 "/_snapshot{/repository}{/snapshot}/_status", update_params(params, :
|
81
|
+
response = client.get "/_snapshot{/repository}{/snapshot}/_status", update_params(params, action: "snapshot.status", rest_api: "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 "/_snapshot/{repository}/{snapshot}/_restore", update_params(params, :body
|
93
|
+
response = client.post "/_snapshot/{repository}/{snapshot}/_restore", update_params(params, body: body, action: "snapshot.restore", rest_api: "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 "/_snapshot/{repository}/{snapshot}", update_params(params, :
|
104
|
+
response = client.delete "/_snapshot/{repository}/{snapshot}", update_params(params, action: "snapshot.delete", rest_api: "snapshot.delete")
|
105
105
|
response.body
|
106
106
|
end
|
107
107
|
|
@@ -120,7 +120,7 @@ module Elastomer
|
|
120
120
|
|
121
121
|
# Internal: Returns a Hash containing default parameters.
|
122
122
|
def defaults
|
123
|
-
{ :
|
123
|
+
{ repository: repository, snapshot: name }
|
124
124
|
end
|
125
125
|
end
|
126
126
|
end
|
@@ -12,18 +12,6 @@ module Elastomer
|
|
12
12
|
|
13
13
|
class Tasks
|
14
14
|
|
15
|
-
# TODO - validate params from this whitelist
|
16
|
-
PARAMETERS = %i[
|
17
|
-
nodes
|
18
|
-
actions
|
19
|
-
parent_task_id
|
20
|
-
wait_for_completion
|
21
|
-
pretty
|
22
|
-
detailed
|
23
|
-
timeout
|
24
|
-
group_by
|
25
|
-
].to_set.freeze
|
26
|
-
|
27
15
|
# Create a new Tasks for introspecting on internal cluster activity.
|
28
16
|
# More context: https://www.elastic.co/guide/en/elasticsearch/reference/5.6/tasks.html
|
29
17
|
#
|
@@ -38,21 +26,21 @@ module Elastomer
|
|
38
26
|
|
39
27
|
# Fetch results from the generic _tasks endpoint.
|
40
28
|
#
|
41
|
-
# params
|
29
|
+
# params - Hash of request parameters, including:
|
42
30
|
#
|
43
31
|
# Examples
|
44
32
|
#
|
45
33
|
# tasks.get
|
46
|
-
# tasks.get :
|
34
|
+
# tasks.get nodes: "DmteLdw1QmSgW3GZmjmoKA,DmteLdw1QmSgW3GZmjmoKB", actions: "cluster:*", detailed: true
|
47
35
|
#
|
48
36
|
# Examples (ES 5+ only)
|
49
37
|
#
|
50
|
-
# tasks.get :
|
51
|
-
# tasks.get :
|
38
|
+
# tasks.get group_by: "parents"
|
39
|
+
# tasks.get group_by: "parents", actions: "*reindex", ...
|
52
40
|
#
|
53
41
|
# Returns the response body as a Hash
|
54
42
|
def get(params = {})
|
55
|
-
response = client.get "/_tasks", params
|
43
|
+
response = client.get "/_tasks", params.merge(action: "tasks.list", rest_api: "tasks.list")
|
56
44
|
response.body
|
57
45
|
end
|
58
46
|
|
@@ -61,22 +49,24 @@ module Elastomer
|
|
61
49
|
# where "node_id" is a value from the "nodes" hash returned from the /_tasks endpoint, and "task_id" is
|
62
50
|
# from the "tasks" child hash of any of the "nodes" entries of the /_tasks endpoint
|
63
51
|
#
|
64
|
-
# node_id
|
65
|
-
# task_id
|
66
|
-
# params
|
52
|
+
# node_id - the name of the ES cluster node hosting the target task
|
53
|
+
# task_id - the numerical ID of the task to return data about in the response
|
54
|
+
# params - Hash of request parameters to include
|
67
55
|
#
|
68
56
|
# Examples
|
69
57
|
#
|
70
58
|
# tasks.get_by_id "DmteLdw1QmSgW3GZmjmoKA", 123
|
71
|
-
# tasks.get_by_id "DmteLdw1QmSgW3GZmjmoKA", 456, :
|
59
|
+
# tasks.get_by_id "DmteLdw1QmSgW3GZmjmoKA", 456, pretty: true
|
72
60
|
#
|
73
61
|
# Returns the response body as a Hash
|
74
62
|
def get_by_id(node_id, task_id, params = {})
|
75
63
|
raise ArgumentError, "invalid node ID provided: #{node_id.inspect}" if node_id.to_s.empty?
|
76
64
|
raise ArgumentError, "invalid task ID provided: #{task_id.inspect}" unless task_id.is_a?(Integer)
|
77
65
|
|
66
|
+
rest_api = client.version_support.supports_tasks_get? ? "tasks.get" : "tasks.list"
|
67
|
+
|
78
68
|
# in this API, the task ID is included in the path, not as a request parameter.
|
79
|
-
response = client.get "/_tasks
|
69
|
+
response = client.get "/_tasks/{task_id}", params.merge(task_id: "#{node_id}:#{task_id}", action: "tasks.get", rest_api: rest_api)
|
80
70
|
response.body
|
81
71
|
end
|
82
72
|
|
@@ -85,9 +75,9 @@ module Elastomer
|
|
85
75
|
# is not the correct syntax for the parent_task_id param value. The correct
|
86
76
|
# value syntax is "<parent_node_id>:<parent_task_id>"
|
87
77
|
#
|
88
|
-
# parent_node_id
|
89
|
-
# parent_task_id
|
90
|
-
# params
|
78
|
+
# parent_node_id - ID of the node the parent task is hosted by
|
79
|
+
# parent_task_id - ID of a parent task who's child tasks' data will be returned in the response
|
80
|
+
# params - Hash of request parameters to include
|
91
81
|
#
|
92
82
|
# Examples
|
93
83
|
#
|
@@ -99,50 +89,55 @@ module Elastomer
|
|
99
89
|
raise ArgumentError, "invalid parent node ID provided: #{parent_node_id.inspect}" if node_id.to_s.empty?
|
100
90
|
raise ArgumentError, "invalid parent task ID provided: #{parent_task_id.inspect}" unless parent_task_id.is_a?(Integer)
|
101
91
|
|
102
|
-
|
103
|
-
|
104
|
-
|
92
|
+
parent_task_id = "#{parent_node_id}:#{parent_task_id}"
|
93
|
+
params = params.merge(action: "tasks.parent", rest_api: "tasks.list")
|
94
|
+
|
95
|
+
if client.version_support.supports_parent_task_id?
|
96
|
+
params[:parent_task_id] = parent_task_id
|
97
|
+
else
|
98
|
+
params[:parent_task] = parent_task_id
|
99
|
+
end
|
100
|
+
|
101
|
+
response = client.get "/_tasks", params
|
105
102
|
response.body
|
106
103
|
end
|
107
104
|
|
108
105
|
# Wait for the specified amount of time (10 seconds by default) for some task(s) to complete.
|
109
106
|
# Filters for task(s) to wait upon using same filter params as Tasks#get(params)
|
110
107
|
#
|
111
|
-
# timeout
|
112
|
-
# params
|
108
|
+
# timeout - maximum time to wait for target task to complete before returning, example: "5s"
|
109
|
+
# params - Hash of request params to include (mostly task filters in this context)
|
113
110
|
#
|
114
111
|
# Examples
|
115
112
|
#
|
116
|
-
# tasks.wait_for "5s", :
|
117
|
-
# tasks.wait_for("30s", :
|
113
|
+
# tasks.wait_for "5s", actions: "*health"
|
114
|
+
# tasks.wait_for("30s", actions: "*reindex", nodes: "DmteLdw1QmSgW3GZmjmoKA,DmteLdw1QmSgW3GZmjmoKB")
|
118
115
|
#
|
119
116
|
# Returns the response body as a Hash when timeout expires or target tasks complete
|
120
117
|
# COMPATIBILITY WARNING: the response body differs between ES versions for this API
|
121
118
|
def wait_for(timeout = "10s", params = {})
|
122
|
-
|
123
|
-
self.get(params_with_wait)
|
119
|
+
self.get params.merge(wait_for_completion: true, timeout: timeout)
|
124
120
|
end
|
125
121
|
|
126
122
|
# Wait for the specified amount of time (10 seconds by default) for some task(s) to complete.
|
127
123
|
# Filters for task(s) to wait upon using same IDs and filter params as Tasks#get_by_id(params)
|
128
124
|
#
|
129
|
-
# node_id
|
130
|
-
# task_id
|
131
|
-
# timeout
|
132
|
-
# params
|
125
|
+
# node_id - the ID of the node on which the target task is hosted
|
126
|
+
# task_id - the ID of the task to wait on
|
127
|
+
# timeout - time for call to await target tasks completion before returning
|
128
|
+
# params - Hash of request params to include (mostly task filters in this context)
|
133
129
|
#
|
134
130
|
# Examples
|
135
131
|
#
|
136
132
|
# tasks.wait_by_id "DmteLdw1QmSgW3GZmjmoKA", 123, "15s"
|
137
|
-
# tasks.wait_by_id "DmteLdw1QmSgW3GZmjmoKA", 456, "30s", :
|
133
|
+
# tasks.wait_by_id "DmteLdw1QmSgW3GZmjmoKA", 456, "30s", actions: "*search"
|
138
134
|
#
|
139
135
|
# Returns the response body as a Hash when timeout expires or target tasks complete
|
140
136
|
def wait_by_id(node_id, task_id, timeout = "10s", params = {})
|
141
137
|
raise ArgumentError, "invalid node ID provided: #{node_id.inspect}" if node_id.to_s.empty?
|
142
138
|
raise ArgumentError, "invalid task ID provided: #{task_id.inspect}" unless task_id.is_a?(Integer)
|
143
139
|
|
144
|
-
|
145
|
-
self.get_by_id(node_id, task_id, params_with_wait)
|
140
|
+
self.get_by_id(node_id, task_id, params.merge(wait_for_completion: true, timeout: timeout))
|
146
141
|
end
|
147
142
|
|
148
143
|
# Cancels a task running on a particular node.
|
@@ -157,32 +152,31 @@ module Elastomer
|
|
157
152
|
# Examples
|
158
153
|
#
|
159
154
|
# tasks.cancel_by_id "DmteLdw1QmSgW3GZmjmoKA", 123
|
160
|
-
# tasks.cancel_by_id "DmteLdw1QmSgW3GZmjmoKA", 456, :
|
155
|
+
# tasks.cancel_by_id "DmteLdw1QmSgW3GZmjmoKA", 456, pretty: true
|
161
156
|
#
|
162
157
|
# Returns the response body as a Hash
|
163
158
|
def cancel_by_id(node_id, task_id, params = {})
|
164
159
|
raise ArgumentError, "invalid node ID provided: #{node_id.inspect}" if node_id.to_s.empty?
|
165
160
|
raise ArgumentError, "invalid task ID provided: #{task_id.inspect}" unless task_id.is_a?(Integer)
|
166
161
|
|
167
|
-
|
168
|
-
response.body
|
162
|
+
self.cancel(params.merge(task_id: "#{node_id}:#{task_id}"))
|
169
163
|
end
|
170
164
|
|
171
165
|
# Cancels a task or group of tasks using various filtering parameters.
|
172
166
|
#
|
173
|
-
# params
|
167
|
+
# params - Hash of request parameters to include
|
174
168
|
#
|
175
169
|
# Examples
|
176
170
|
#
|
177
|
-
# tasks.cancel :
|
178
|
-
# tasks.cancel :
|
171
|
+
# tasks.cancel actions: "*reindex"
|
172
|
+
# tasks.cancel actions: "*search", nodes: "DmteLdw1QmSgW3GZmjmoKA,DmteLdw1QmSgW3GZmjmoKB,DmteLdw1QmSgW3GZmjmoKC"
|
179
173
|
#
|
180
174
|
# Returns the response body as a Hash
|
181
175
|
def cancel(params = {})
|
182
|
-
response = client.post "/_tasks/_cancel", params
|
176
|
+
response = client.post "/_tasks{/task_id}/_cancel", params.merge(action: "tasks.cancel", rest_api: "tasks.cancel")
|
183
177
|
response.body
|
184
178
|
end
|
185
179
|
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
@@ -25,7 +25,7 @@ module Elastomer
|
|
25
25
|
|
26
26
|
# Returns true if the template already exists on the cluster.
|
27
27
|
def exists?( params = {} )
|
28
|
-
response = client.head "/_template/{template}", update_params(params, action: "template.exists")
|
28
|
+
response = client.head "/_template/{template}", update_params(params, action: "template.exists", rest_api: "indices.exists_template")
|
29
29
|
response.success?
|
30
30
|
end
|
31
31
|
alias_method :exist?, :exists?
|
@@ -37,7 +37,7 @@ module Elastomer
|
|
37
37
|
#
|
38
38
|
# Returns the response body as a Hash
|
39
39
|
def get( params = {} )
|
40
|
-
response = client.get "/_template/{template}", update_params(params, :
|
40
|
+
response = client.get "/_template/{template}", update_params(params, action: "template.get", rest_api: "indices.get_template")
|
41
41
|
response.body
|
42
42
|
end
|
43
43
|
|
@@ -49,7 +49,7 @@ module Elastomer
|
|
49
49
|
#
|
50
50
|
# Returns the response body as a Hash
|
51
51
|
def create( template, params = {} )
|
52
|
-
response = client.put "/_template/{template}", update_params(params, :
|
52
|
+
response = client.put "/_template/{template}", update_params(params, body: template, action: "template.create", rest_api: "indices.put_template")
|
53
53
|
response.body
|
54
54
|
end
|
55
55
|
|
@@ -60,7 +60,7 @@ module Elastomer
|
|
60
60
|
#
|
61
61
|
# Returns the response body as a Hash
|
62
62
|
def delete( params = {} )
|
63
|
-
response = client.delete "/_template/{template}", update_params(params, :
|
63
|
+
response = client.delete "/_template/{template}", update_params(params, action: "template.delete", rest_api: "indices.delete_template")
|
64
64
|
response.body
|
65
65
|
end
|
66
66
|
|
@@ -79,8 +79,8 @@ module Elastomer
|
|
79
79
|
|
80
80
|
# Internal: Returns a Hash containing default parameters.
|
81
81
|
def defaults
|
82
|
-
{ :
|
82
|
+
{ template: name }
|
83
83
|
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -34,7 +34,7 @@ module Elastomer
|
|
34
34
|
#
|
35
35
|
# Returns the response body as a Hash
|
36
36
|
def create(query, params = {})
|
37
|
-
response = client.put "/{index}{/type}/_warmer/{warmer}",
|
37
|
+
response = client.put "/{index}{/type}/_warmer/{warmer}", update_params(params, body: query, action: "warmer.create", rest_api: "indices.put_warmer")
|
38
38
|
response.body
|
39
39
|
end
|
40
40
|
|
@@ -45,7 +45,7 @@ module Elastomer
|
|
45
45
|
#
|
46
46
|
# Returns the response body as a Hash
|
47
47
|
def delete(params = {})
|
48
|
-
response = client.delete "/{index}{/type}/_warmer/{warmer}",
|
48
|
+
response = client.delete "/{index}{/type}/_warmer/{warmer}", update_params(params, action: "warmer.delete", rest_api: "indices.delete_warmer")
|
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 "/{index}{/type}/_warmer/{warmer}",
|
59
|
+
response = client.get "/{index}{/type}/_warmer/{warmer}", update_params(params, action: "warmer.get", rest_api: "indices.get_warmer")
|
60
60
|
response.body
|
61
61
|
end
|
62
62
|
|
@@ -82,9 +82,16 @@ module Elastomer
|
|
82
82
|
end
|
83
83
|
alias_method :exist?, :exists?
|
84
84
|
|
85
|
+
# Internal:
|
86
|
+
def update_params(params, overrides = nil)
|
87
|
+
h = defaults.update params
|
88
|
+
h.update overrides unless overrides.nil?
|
89
|
+
h
|
90
|
+
end
|
91
|
+
|
85
92
|
# Internal: Returns a Hash containing default parameters.
|
86
93
|
def defaults
|
87
|
-
{:
|
94
|
+
{index: index_name, warmer: name}
|
88
95
|
end
|
89
96
|
end
|
90
97
|
end
|
data/lib/elastomer/client.rb
CHANGED
@@ -31,10 +31,12 @@ module Elastomer
|
|
31
31
|
# :max_request_size - the maximum allowed request size in bytes (defaults to 250 MB)
|
32
32
|
# :max_retries - the maximum number of request retires (defaults to 0)
|
33
33
|
# :retry_delay - delay in seconds between retries (defaults to 0.075)
|
34
|
+
# :strict_params - set to `true` to raise exceptions when invalid request params are used
|
34
35
|
#
|
35
36
|
def initialize(host: "localhost", port: 9200, url: nil,
|
36
37
|
read_timeout: 5, open_timeout: 2, max_retries: 0, retry_delay: 0.075,
|
37
|
-
opaque_id: false, adapter: Faraday.default_adapter, max_request_size: MAX_REQUEST_SIZE
|
38
|
+
opaque_id: false, adapter: Faraday.default_adapter, max_request_size: MAX_REQUEST_SIZE,
|
39
|
+
strict_params: false)
|
38
40
|
|
39
41
|
@url = url || "http://#{host}:#{port}"
|
40
42
|
|
@@ -49,11 +51,14 @@ module Elastomer
|
|
49
51
|
@adapter = adapter
|
50
52
|
@opaque_id = opaque_id
|
51
53
|
@max_request_size = max_request_size
|
54
|
+
@strict_params = strict_params
|
52
55
|
end
|
53
56
|
|
54
57
|
attr_reader :host, :port, :url
|
55
58
|
attr_reader :read_timeout, :open_timeout
|
56
59
|
attr_reader :max_retries, :retry_delay, :max_request_size
|
60
|
+
attr_reader :strict_params
|
61
|
+
alias :strict_params? :strict_params
|
57
62
|
|
58
63
|
# Returns a duplicate of this Client connection configured in the exact same
|
59
64
|
# fashion.
|
@@ -69,7 +74,7 @@ module Elastomer
|
|
69
74
|
|
70
75
|
# Returns true if the server is available; returns false otherwise.
|
71
76
|
def ping
|
72
|
-
response = head "/", :
|
77
|
+
response = head "/", action: "cluster.ping"
|
73
78
|
response.success?
|
74
79
|
rescue StandardError
|
75
80
|
false
|
@@ -78,7 +83,10 @@ module Elastomer
|
|
78
83
|
|
79
84
|
# Returns the version String of the attached Elasticsearch instance.
|
80
85
|
def version
|
81
|
-
@version ||=
|
86
|
+
@version ||= begin
|
87
|
+
response = get "/"
|
88
|
+
response.body.dig("version", "number")
|
89
|
+
end
|
82
90
|
end
|
83
91
|
|
84
92
|
# Returns a Semantic::Version for the attached Elasticsearch instance.
|
@@ -89,10 +97,16 @@ module Elastomer
|
|
89
97
|
|
90
98
|
# Returns the information Hash from the attached Elasticsearch instance.
|
91
99
|
def info
|
92
|
-
response = get "/", :
|
100
|
+
response = get "/", action: "cluster.info"
|
93
101
|
response.body
|
94
102
|
end
|
95
103
|
|
104
|
+
# Returns the ApiSpec for the specific version of Elasticsearch that this
|
105
|
+
# Client is connected to.
|
106
|
+
def api_spec
|
107
|
+
@api_spec ||= RestApiSpec.api_spec(version)
|
108
|
+
end
|
109
|
+
|
96
110
|
# Internal: Provides access to the Faraday::Connection used by this client
|
97
111
|
# for all requests to the server.
|
98
112
|
#
|
@@ -102,7 +116,7 @@ module Elastomer
|
|
102
116
|
conn.request(:encode_json)
|
103
117
|
conn.response(:parse_json)
|
104
118
|
conn.request(:opaque_id) if @opaque_id
|
105
|
-
conn.request(:limit_size, :
|
119
|
+
conn.request(:limit_size, max_request_size: max_request_size) if max_request_size
|
106
120
|
|
107
121
|
if @adapter.is_a?(Array)
|
108
122
|
conn.adapter(*@adapter)
|
@@ -307,10 +321,10 @@ module Elastomer
|
|
307
321
|
#
|
308
322
|
# Examples
|
309
323
|
#
|
310
|
-
# expand_path('/foo{/bar}', {:
|
324
|
+
# expand_path('/foo{/bar}', {bar: 'hello', q: 'what', p: 2})
|
311
325
|
# #=> '/foo/hello?q=what&p=2'
|
312
326
|
#
|
313
|
-
# expand_path('/foo{/bar}{/baz}', {:
|
327
|
+
# expand_path('/foo{/bar}{/baz}', {baz: 'no bar'}
|
314
328
|
# #=> '/foo/no%20bar'
|
315
329
|
#
|
316
330
|
# Returns an Addressable::Uri
|
@@ -323,12 +337,22 @@ module Elastomer
|
|
323
337
|
query_values.delete :context
|
324
338
|
query_values.delete :retries
|
325
339
|
|
340
|
+
rest_api = query_values.delete :rest_api
|
341
|
+
|
326
342
|
template.keys.map(&:to_sym).each do |key|
|
327
343
|
value = query_values.delete key
|
328
344
|
value = assert_param_presence(value, key) unless path =~ /{\/#{key}}/ && value.nil?
|
329
345
|
expansions[key] = value
|
330
346
|
end
|
331
347
|
|
348
|
+
if rest_api
|
349
|
+
query_values = if strict_params?
|
350
|
+
api_spec.validate_params!(api: rest_api, params: query_values)
|
351
|
+
else
|
352
|
+
api_spec.select_params(api: rest_api, from: query_values)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
332
356
|
uri = template.expand(expansions)
|
333
357
|
uri.query_values = query_values unless query_values.empty?
|
334
358
|
uri.to_s
|
data/lib/elastomer/version.rb
CHANGED