elastomer-client 3.0.1 → 3.1.0
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/.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