elastomer-client 0.7.0 → 0.8.1

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.overcommit.yml +5 -0
  3. data/.rubocop.yml +83 -0
  4. data/CHANGELOG.md +8 -0
  5. data/Gemfile +2 -2
  6. data/README.md +1 -1
  7. data/Rakefile +2 -2
  8. data/elastomer-client.gemspec +4 -2
  9. data/lib/elastomer/client.rb +42 -37
  10. data/lib/elastomer/client/bulk.rb +2 -2
  11. data/lib/elastomer/client/cluster.rb +19 -19
  12. data/lib/elastomer/client/delete_by_query.rb +7 -7
  13. data/lib/elastomer/client/docs.rb +81 -24
  14. data/lib/elastomer/client/errors.rb +2 -2
  15. data/lib/elastomer/client/index.rb +65 -29
  16. data/lib/elastomer/client/multi_percolate.rb +127 -0
  17. data/lib/elastomer/client/multi_search.rb +2 -2
  18. data/lib/elastomer/client/nodes.rb +4 -4
  19. data/lib/elastomer/client/percolator.rb +77 -0
  20. data/lib/elastomer/client/repository.rb +7 -7
  21. data/lib/elastomer/client/scroller.rb +14 -14
  22. data/lib/elastomer/client/snapshot.rb +9 -9
  23. data/lib/elastomer/client/template.rb +3 -3
  24. data/lib/elastomer/client/warmer.rb +5 -16
  25. data/lib/elastomer/core_ext/time.rb +1 -1
  26. data/lib/elastomer/middleware/encode_json.rb +5 -5
  27. data/lib/elastomer/middleware/opaque_id.rb +3 -3
  28. data/lib/elastomer/middleware/parse_json.rb +5 -5
  29. data/lib/elastomer/notifications.rb +4 -4
  30. data/lib/elastomer/version.rb +1 -1
  31. data/script/bootstrap +2 -0
  32. data/script/console +5 -5
  33. data/test/assertions.rb +26 -24
  34. data/test/client/bulk_test.rb +111 -111
  35. data/test/client/cluster_test.rb +58 -58
  36. data/test/client/delete_by_query_test.rb +53 -53
  37. data/test/client/docs_test.rb +279 -203
  38. data/test/client/errors_test.rb +1 -1
  39. data/test/client/index_test.rb +143 -109
  40. data/test/client/multi_percolate_test.rb +130 -0
  41. data/test/client/multi_search_test.rb +30 -28
  42. data/test/client/nodes_test.rb +30 -29
  43. data/test/client/percolator_test.rb +52 -0
  44. data/test/client/repository_test.rb +23 -23
  45. data/test/client/scroller_test.rb +40 -40
  46. data/test/client/snapshot_test.rb +15 -15
  47. data/test/client/stubbed_client_test.rb +15 -15
  48. data/test/client/template_test.rb +10 -10
  49. data/test/client/warmer_test.rb +18 -18
  50. data/test/client_test.rb +53 -53
  51. data/test/core_ext/time_test.rb +12 -12
  52. data/test/middleware/encode_json_test.rb +20 -20
  53. data/test/middleware/opaque_id_test.rb +10 -10
  54. data/test/middleware/parse_json_test.rb +14 -14
  55. data/test/notifications_test.rb +32 -32
  56. data/test/test_helper.rb +24 -24
  57. 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 'multi_search request body cannot be nil' if body.nil?
40
+ raise "multi_search request body cannot be nil" if body.nil?
41
41
  params ||= {}
42
42
 
43
- response = self.post '{/index}{/type}/_msearch', params.merge(:body => body)
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 '/_nodes{/node_id}{/info}', update_params(params, :action => 'nodes.info')
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 '/_nodes{/node_id}/stats{/stats}', update_params(params, :action => 'nodes.stats')
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 '/_nodes{/node_id}/hot_threads', update_params(params, :action => 'nodes.hot_threads')
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 '/_cluster/nodes{/node_id}/_shutdown', update_params(params, :action => 'nodes.shutdown')
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, 'repository name') unless name.nil?
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 '/_snapshot{/repository}', update_params(params, :action => 'repository.exists')
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 '/_snapshot/{repository}', update_params(params, :body => body, :action => 'repository.create')
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 '/_snapshot{/repository}', update_params(params, :action => 'repository.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 '/_snapshot{/repository}/_status', update_params(params, :action => 'repository.status')
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 '/_snapshot/{repository}', update_params(params, :body => body, :action => 'repository.update')
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 '/_snapshot/{repository}', update_params(params, :action => 'repository.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 => 'scan')
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 => 'search.start_scroll'
76
- response = get '{/index}{/type}/_search', opts
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 = '5m' )
100
- response = get '/_search/scroll', :body => scroll_id, :scroll => scroll, :action => 'search.scroll'
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 => '5m',
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['hits']
169
- break if hits['hits'].empty?
168
+ hits = body["hits"]
169
+ break if hits["hits"].empty?
170
170
 
171
- hits['offset'] = @offset
172
- @offset += hits['hits'].length
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['hits'].each(&block) }
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['hits']['hits'].empty?
210
- @scroll_id = body['_scroll_id']
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['_scroll_id']
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, 'repository name') unless repository.nil? && name.nil?
26
- @name = @client.assert_param_presence(name, 'snapshot name') unless name.nil?
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 '/_snapshot/{repository}/{snapshot}', update_params(params, :action => 'snapshot.exists')
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 '/_snapshot/{repository}/{snapshot}', update_params(params, :body => body, :action => 'snapshot.create')
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 || '_all'
70
- response = client.get '/_snapshot/{repository}/{snapshot}', update_params(params, :snapshot => snapshot, :action => 'snapshot.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 '/_snapshot{/repository}{/snapshot}/_status', update_params(params, :action => 'snapshot.status')
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 '/_snapshot/{repository}/{snapshot}/_restore', update_params(params, :body => body, :action => 'snapshot.restore')
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 '/_snapshot/{repository}/{snapshot}', update_params(params, :action => 'snapshot.delete')
104
+ response = client.delete "/_snapshot/{repository}/{snapshot}", update_params(params, :action => "snapshot.delete")
105
105
  response.body
106
106
  end
107
107