eson-http 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/README.md +53 -27
  2. data/Rakefile +2 -2
  3. data/bin/elshell +6 -14
  4. data/eson-http.gemspec +4 -2
  5. data/lib/eson-http.rb +5 -0
  6. data/lib/eson/http.rb +1 -11
  7. data/lib/eson/http/api.rb +7 -1
  8. data/lib/eson/http/client.rb +8 -1
  9. data/lib/eson/http/cluster/health.rb +1 -1
  10. data/lib/eson/http/cluster/nodes.rb +1 -1
  11. data/lib/eson/http/cluster/shutdown.rb +1 -1
  12. data/lib/eson/http/cluster/stats.rb +1 -1
  13. data/lib/eson/http/core/bulk.rb +10 -1
  14. data/lib/eson/http/core/count.rb +2 -2
  15. data/lib/eson/http/core/delete_by_query.rb +2 -2
  16. data/lib/eson/http/core/explain.rb +14 -0
  17. data/lib/eson/http/core/msearch.rb +2 -2
  18. data/lib/eson/http/core/scroll.rb +14 -0
  19. data/lib/eson/http/core/search.rb +3 -10
  20. data/lib/eson/http/core/simple_search.rb +2 -2
  21. data/lib/eson/http/core/update.rb +14 -0
  22. data/lib/eson/http/core/validate.rb +18 -0
  23. data/lib/eson/http/indices/clear_cache.rb +1 -1
  24. data/lib/eson/http/indices/close_index.rb +1 -1
  25. data/lib/eson/http/indices/delete_index.rb +1 -1
  26. data/lib/eson/http/indices/delete_mapping.rb +1 -1
  27. data/lib/eson/http/indices/exists.rb +1 -1
  28. data/lib/eson/http/indices/flush.rb +1 -1
  29. data/lib/eson/http/indices/get_aliases.rb +14 -0
  30. data/lib/eson/http/indices/get_mapping.rb +2 -2
  31. data/lib/eson/http/indices/get_settings.rb +1 -1
  32. data/lib/eson/http/indices/open_index.rb +1 -1
  33. data/lib/eson/http/indices/optimize.rb +1 -1
  34. data/lib/eson/http/indices/put_mapping.rb +1 -1
  35. data/lib/eson/http/indices/refresh.rb +1 -1
  36. data/lib/eson/http/indices/segments.rb +1 -1
  37. data/lib/eson/http/indices/snapshot.rb +1 -1
  38. data/lib/eson/http/indices/stats.rb +1 -1
  39. data/lib/eson/http/indices/status.rb +1 -1
  40. data/lib/eson/http/indices/update_settings.rb +1 -1
  41. data/lib/eson/http/request.rb +32 -10
  42. data/lib/eson/modules/response_parser.rb +15 -3
  43. data/lib/eson/modules/status_handler.rb +6 -0
  44. data/test/http/client_test.rb +9 -2
  45. data/test/http/cluster_test.rb +1 -1
  46. data/test/http/index_test.rb +36 -3
  47. data/test/http/indices/basics_test.rb +15 -12
  48. data/test/seeds/seeds.rb +3 -0
  49. data/test/test_config.rb +1 -1
  50. metadata +25 -10
data/README.md CHANGED
@@ -7,7 +7,7 @@ It tries to keep the language of the ES API as intact as possible.
7
7
  ## Usage
8
8
 
9
9
  require 'eson-http'
10
-
10
+
11
11
  c = Eson::HTTP::Client.new(:server => 'http://localhost:9200')
12
12
 
13
13
  doc = {
@@ -15,24 +15,53 @@ It tries to keep the language of the ES API as intact as possible.
15
15
  :post_date => "2009-11-15T14:12:12",
16
16
  :message => "trying out Elastic Search"
17
17
  }
18
-
18
+
19
19
  c.index :index => "twitter",
20
20
  :type => "tweet",
21
21
  :id => 1,
22
22
  :document => doc
23
-
23
+
24
24
  c.get :type => "tweet", :id => 1 # returns the document
25
-
25
+
26
26
  c.search :q => "message:trying"
27
-
27
+
28
28
  c.count :q => "*"
29
29
 
30
+ ## Default parameters
31
+
32
+ All parameters can be set to default values by using `#with`. `#with` returns a new client that has the default parameters set.
33
+
34
+ require 'eson-http'
35
+
36
+ c = Eson::HTTP::Client.new(:server => 'http://localhost:9200')
37
+ .with(:index => "twitter", :type => "tweet")
38
+
39
+ doc = {
40
+ :user => "kimchy",
41
+ :post_date => "2009-11-15T14:12:12",
42
+ :message => "trying out Elastic Search"
43
+ }
44
+
45
+ c.index :id => 1, :doc => doc
46
+
47
+ c.get :id => 1
48
+
49
+ c.search :q => "message:trying" # this searches tweets/tweet/_search !!!
50
+
51
+ c.count :q => "*" # same here
52
+
53
+ `#with` also has a block form that passes the new client as a parameter:
54
+
55
+ c.with(:index => "twitter", :type => "tweet") do |modified_client|
56
+ modified_client.get :id => 1
57
+ end
58
+
30
59
  ## Building requests by hand
31
60
 
32
61
  The client has an additional mode that does not call elasticsearch immediately, but returns the request object instead.
33
62
 
34
63
  require 'echolon/http'
35
-
64
+
36
65
  c = Eson::HTTP::Client.new(:server => 'http://localhost:9200',
37
66
  :auto_call => false)
38
67
 
@@ -41,27 +70,27 @@ The client has an additional mode that does not call elasticsearch immediately,
41
70
  :post_date => "2009-11-15T14:12:12",
42
71
  :message => "trying out Elastic Search"
43
72
  }
44
-
73
+
45
74
  index_request = c.index
46
75
  index_request.index = "twitter"
47
76
  index_request.type = "tweet"
48
77
  index_request.id = 1
49
78
  index_request.doc = doc
50
-
79
+
51
80
  index_request.call
52
-
81
+
53
82
  # or:
54
-
83
+
55
84
  index_request = c.index
56
- index_request.params = {
85
+ index_request.parameters = {
57
86
  :index => "twitter",
58
87
  :type => "tweet"
59
88
  :id => 1,
60
89
  :doc => doc
61
90
  }
62
-
91
+
63
92
  # or:
64
-
93
+
65
94
  index_request = c.index :index => "twitter",
66
95
  :type => "tweet"
67
96
  :id => 1,
@@ -72,19 +101,17 @@ The client has an additional mode that does not call elasticsearch immediately,
72
101
  `bulk` and `msearch` requests can be constructed by calling the respective client methods on them:
73
102
 
74
103
 
75
- ```
76
- c.bulk do |b|
77
- b.index :index => "default",
78
- :type => "bar"
79
- :doc => {"foo" => "bar"}
80
- b.delete :index => "default",
81
- :id => '134'
82
- end
83
-
84
- c.msearch do |s|
85
- s.search #....
86
- end
87
- ```
104
+ c.bulk do |b|
105
+ b.index :index => "default",
106
+ :type => "bar"
107
+ :doc => {"foo" => "bar"}
108
+ b.delete :index => "default",
109
+ :id => '134'
110
+ end
111
+
112
+ c.msearch do |s|
113
+ s.search #....
114
+ end
88
115
 
89
116
  ## The shell
90
117
 
@@ -104,7 +131,6 @@ Eson-HTTP comes with a quick-and-dirty shell, if you have pry installed:
104
131
  ## TODO
105
132
 
106
133
  * Test suite needs to be reordered. Its the oldest part of the project and a bit messy.
107
- * Filters in aliases are not supported
108
134
 
109
135
  ## See also
110
136
 
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  require 'rake/testtask'
2
- require 'rake/gempackagetask'
2
+ require 'rubygems/package_task'
3
3
  require 'rake/testtask'
4
4
 
5
5
  def gemspec
@@ -14,7 +14,7 @@ task :gemspec do
14
14
  gemspec.validate
15
15
  end
16
16
 
17
- Rake::GemPackageTask.new(gemspec) do |pkg|
17
+ Gem::PackageTask.new(gemspec) do |pkg|
18
18
  pkg.gem_spec = gemspec
19
19
  end
20
20
 
@@ -1,20 +1,12 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH << File.join(File.dirname(File.dirname(__FILE__)), "lib")
4
-
5
- require 'echolon-http'
6
- require 'echolon-search'
7
-
8
- require 'elsearch-node'
9
-
10
- require 'node/external'
11
-
12
- require 'rest-client'
13
- require 'addressable/template'
14
-
3
+ require 'eson-core'
4
+ require 'eson-http'
5
+ require 'eson-dsl'
6
+ require 'logger'
15
7
  require 'pry'
16
8
 
17
9
  c = Eson::HTTP::Client.new(:server => ARGV.first || 'http://localhost:9200',
18
- :logger => Logger.new($stdout))
10
+ :logger => Logger.new($stdout))
19
11
 
20
- c.pry
12
+ c.pry
@@ -4,7 +4,8 @@ $:.push File.expand_path("../lib", __FILE__)
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "eson-http"
7
- s.version = "0.7.0" #Echolon::VERSION
7
+ s.version = "0.8.0"
8
+
8
9
  s.platform = Gem::Platform::RUBY
9
10
  s.authors = ["Florian Gilcher"]
10
11
  s.email = ["florian.gilcher@asquera.de"]
@@ -20,7 +21,8 @@ Gem::Specification.new do |s|
20
21
  s.require_paths = ["lib"]
21
22
 
22
23
  #s.add_dependency "typhoeus"
23
- s.add_dependency "faraday", "~> 0.7.0"
24
+ s.add_dependency "faraday", "~> 0.8.0"
25
+ s.add_dependency "net-http-persistent"
24
26
  s.add_dependency "addressable"
25
27
  s.add_dependency "eson-core"
26
28
  s.add_development_dependency "elasticsearch-node"
@@ -20,9 +20,13 @@ require 'eson/http/core/count'
20
20
  require 'eson/http/core/bulk'
21
21
  require 'eson/http/core/percolate'
22
22
  require 'eson/http/core/simple_search'
23
+ require 'eson/http/core/update'
23
24
  require 'eson/http/core/more_like_this'
24
25
  require 'eson/http/core/msearch'
25
26
  require 'eson/http/core/mget'
27
+ require 'eson/http/core/scroll'
28
+ require 'eson/http/core/validate'
29
+ require 'eson/http/core/explain'
26
30
 
27
31
  require 'eson/http/cluster/health'
28
32
  require 'eson/http/cluster/state'
@@ -31,6 +35,7 @@ require 'eson/http/cluster/stats'
31
35
  require 'eson/http/cluster/shutdown'
32
36
 
33
37
  require 'eson/http/indices/aliases'
38
+ require 'eson/http/indices/get_aliases'
34
39
  require 'eson/http/indices/analyze'
35
40
  require 'eson/http/indices/clear_cache'
36
41
  require 'eson/http/indices/close_index'
@@ -1,16 +1,6 @@
1
1
  module Eson
2
+ # @api internal
2
3
  module HTTP
3
- def self.logger=(logger)
4
- if String === logger
5
- require 'logger'
6
- @logger = Logger.new(logger)
7
- else
8
- @logger = logger
9
- end
10
- end
11
4
 
12
- def self.logger
13
- @logger
14
- end
15
5
  end
16
6
  end
@@ -1,8 +1,14 @@
1
1
  module Eson
2
2
  module HTTP
3
+ # HTTP::Api is like {Eson::Api}, but allows to define a request method
4
+ # as well. All HTTP::Api objects also have to define `#path` as a method
5
+ # to return the endpoint path as a url template.
3
6
  module API
4
7
  include Eson::API
5
-
8
+
9
+ # DSL method to indicate the request method.
10
+ #
11
+ # @param [symbol] method The http method verb to use.
6
12
  def request_method(method)
7
13
  define_method :request_method do
8
14
  @request_method || method
@@ -1,16 +1,23 @@
1
1
  module Eson
2
2
  module HTTP
3
+ # This client is a convenience subclass of {Eson::Client}. It sets sane
4
+ # default parameters and adds the following plugins: {Eson::StatusHandler}
5
+ # for handling response status, {Eson::ResponseParser} to parse JSON
6
+ # responses and return Hashes and {Eson::QueryPlugin} to use the Query DSL
7
+ # directly.
3
8
  class Client < Eson::Client
9
+ # Default settings
4
10
  DEFAULT_OPTS = {
5
11
  :server => "http://localhost:9200",
6
12
  :protocol => Eson::HTTP
7
13
  }
8
14
 
15
+ # @see Eson::Client
9
16
  def initialize(opts = {})
10
17
  opts = DEFAULT_OPTS.merge(:plugins => default_plugins).merge(opts)
11
18
  super(opts)
12
19
  end
13
-
20
+
14
21
  private
15
22
  def default_plugins
16
23
  [Eson::StatusHandler, Eson::ResponseParser].tap do |plugins|
@@ -7,7 +7,7 @@ module Eson
7
7
  request_method :get
8
8
 
9
9
  def path
10
- '/_cluster/health/{-list|,|indices}'
10
+ '/_cluster/health/{indices}'
11
11
  end
12
12
 
13
13
  end
@@ -7,7 +7,7 @@ module Eson
7
7
  request_method :get
8
8
 
9
9
  def path
10
- '/_cluster/nodes/{-list|,|nodes}'
10
+ '/_cluster/nodes/{nodes}'
11
11
  end
12
12
  end
13
13
  end
@@ -8,7 +8,7 @@ module Eson
8
8
  request_method :post
9
9
 
10
10
  def path
11
- '/_cluster/nodes/{-list|,|nodes}/_shutdown'
11
+ '/_cluster/nodes/{nodes}/_shutdown'
12
12
  end
13
13
  end
14
14
  end
@@ -10,7 +10,7 @@ module Eson
10
10
  if nodes.empty?
11
11
  '/_cluster/nodes/stats'
12
12
  else
13
- '/_cluster/nodes/{-list|,|nodes}/stats'
13
+ '/_cluster/nodes/{nodes}/stats'
14
14
  end
15
15
  end
16
16
  end
@@ -1,6 +1,10 @@
1
1
  module Eson
2
2
  module HTTP
3
3
  module Bulk
4
+ FIELD_MAPPING = [:index, :type, :id, :parent, :ttl, :timestamp, :routing].map do |field|
5
+ [field, "_#{field}"]
6
+ end
7
+
4
8
  include Shared::Bulk
5
9
  extend API
6
10
 
@@ -26,7 +30,12 @@ module Eson
26
30
  end
27
31
 
28
32
  def to_params_hash(r)
29
- { "_index" => r.index, "_type" => r.type, "_id" => r.id }
33
+ FIELD_MAPPING.inject({}) do |params, (field, serialized_field)|
34
+ if r.respond_to?(field) && val = r.send(field)
35
+ params[serialized_field] = val
36
+ end
37
+ params
38
+ end
30
39
  end
31
40
  end
32
41
  end
@@ -8,9 +8,9 @@ module Eson
8
8
 
9
9
  def bare_path
10
10
  unless types.empty?
11
- path = "{-list|,|indices}/{-list|,|types}/"
11
+ path = "{indices}/{types}/"
12
12
  else
13
- path = "{-list|,|indices}/"
13
+ path = "{indices}/"
14
14
  end
15
15
  end
16
16
 
@@ -8,9 +8,9 @@ module Eson
8
8
 
9
9
  def bare_path
10
10
  unless types.empty?
11
- path = "{-list|,|indices}/{-list|,|types}/"
11
+ path = "{indices}/{types}/"
12
12
  else
13
- path = "{-list|,|indices}/"
13
+ path = "{indices}/"
14
14
  end
15
15
  end
16
16
 
@@ -0,0 +1,14 @@
1
+ module Eson
2
+ module HTTP
3
+ module Explain
4
+ include Shared::Explain
5
+ extend API
6
+
7
+ request_method :get
8
+
9
+ def path
10
+ "/{index}/{type}/{id}/_explain"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -35,9 +35,9 @@ module Eson
35
35
 
36
36
  def path
37
37
  unless types.empty?
38
- path = "{-list|,|indices}/{-list|,|types}/"
38
+ path = "{indices}/{types}/"
39
39
  else
40
- path = "{-list|,|indices}/"
40
+ path = "{indices}/"
41
41
  end
42
42
 
43
43
  path << "_msearch"
@@ -0,0 +1,14 @@
1
+ module Eson
2
+ module HTTP
3
+ module Scroll
4
+ include Shared::Scroll
5
+ extend API
6
+
7
+ request_method :get
8
+
9
+ def path
10
+ "_search/scroll"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -8,22 +8,15 @@ module Eson
8
8
 
9
9
  def bare_path
10
10
  unless types.empty?
11
- path = "{-list|,|indices}/{-list|,|types}/"
11
+ path = "{indices}/{types}/"
12
12
  else
13
- path = "{-list|,|indices}/"
13
+ path = "{indices}/"
14
14
  end
15
15
  end
16
16
 
17
17
  def path
18
- path = bare_path + "_search"
19
-
20
- if scroll
21
- path << "/scroll"
22
- end
23
-
24
- path
18
+ bare_path + "_search"
25
19
  end
26
-
27
20
  end
28
21
  end
29
22
  end
@@ -8,9 +8,9 @@ module Eson
8
8
 
9
9
  def path
10
10
  unless types.empty?
11
- "{-list|,|indices}/{-list|,|types}/_search"
11
+ "{indices}/{types}/_search"
12
12
  else
13
- "{-list|,|indices}/_search"
13
+ "{indices}/_search"
14
14
  end
15
15
  end
16
16
  end
@@ -0,0 +1,14 @@
1
+ module Eson
2
+ module HTTP
3
+ module Update
4
+ include Shared::Update
5
+ extend API
6
+
7
+ request_method :post
8
+
9
+ def path
10
+ "/{index}/{type}/{id}/_update"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,18 @@
1
+ module Eson
2
+ module HTTP
3
+ module Validate
4
+ include Shared::Validate
5
+ extend API
6
+
7
+ request_method :get
8
+
9
+ def path
10
+ if type
11
+ "/{index}/{type}/_validate/query"
12
+ else
13
+ "/{index}/_validate/query"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -8,7 +8,7 @@ module Eson
8
8
 
9
9
  def path
10
10
  if index
11
- "/{-list|,|indices}/_cache/clear"
11
+ "/{indices}/_cache/clear"
12
12
  else
13
13
  "/_cache/clear"
14
14
  end
@@ -7,7 +7,7 @@ module Eson
7
7
  request_method :post
8
8
 
9
9
  def path
10
- "/{-list|,|indices}/_close"
10
+ "/{indices}/_close"
11
11
  end
12
12
  end
13
13
  end
@@ -7,7 +7,7 @@ module Eson
7
7
  request_method :delete
8
8
 
9
9
  def path
10
- "/{-list|,|indices}"
10
+ "/{indices}"
11
11
  end
12
12
  end
13
13
  end
@@ -9,7 +9,7 @@ module Eson
9
9
 
10
10
  def path
11
11
  if type && !indices.empty?
12
- "/{-list|,|indices}/{type}"
12
+ "/{indices}/{type}"
13
13
  end
14
14
  end
15
15
  end
@@ -7,7 +7,7 @@ module Eson
7
7
  request_method :head
8
8
 
9
9
  def path
10
- "/{-list|,|indices}"
10
+ "/{indices}"
11
11
  end
12
12
  end
13
13
  end
@@ -8,7 +8,7 @@ module Eson
8
8
 
9
9
  def path
10
10
  unless indices.empty?
11
- "/{-list|,|indices}/_flush"
11
+ "/{indices}/_flush"
12
12
  else
13
13
  "/_flush"
14
14
  end
@@ -0,0 +1,14 @@
1
+ module Eson
2
+ module HTTP
3
+ module GetAliases
4
+ include Shared::GetAliases
5
+ extend API
6
+
7
+ request_method :get
8
+
9
+ def path
10
+ "/_aliases"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -8,9 +8,9 @@ module Eson
8
8
 
9
9
  def path
10
10
  if !types.empty? && !indices.empty?
11
- "/{-list|,|indices}/{-list|,|types}/_mapping"
11
+ "/{indices}/{types}/_mapping"
12
12
  elsif !indices.empty?
13
- "/{-list|,|indices}/_mapping"
13
+ "/{indices}/_mapping"
14
14
  else
15
15
  "/_mapping"
16
16
  end
@@ -8,7 +8,7 @@ module Eson
8
8
 
9
9
  def path
10
10
  if index
11
- "/{-list|,|indices}/_settings"
11
+ "/{indices}/_settings"
12
12
  else
13
13
  "/_settings"
14
14
  end
@@ -7,7 +7,7 @@ module Eson
7
7
  request_method :post
8
8
 
9
9
  def path
10
- "/{-list|,|indices}/_open"
10
+ "/{indices}/_open"
11
11
  end
12
12
  end
13
13
  end
@@ -8,7 +8,7 @@ module Eson
8
8
 
9
9
  def path
10
10
  if index
11
- "/{-list|,|indices}/_refresh"
11
+ "/{indices}/_refresh"
12
12
  else
13
13
  "/_refresh"
14
14
  end
@@ -8,7 +8,7 @@ module Eson
8
8
 
9
9
  def path
10
10
  if type && !indices.empty?
11
- "/{-list|,|indices}/{type}/_mapping"
11
+ "/{indices}/{type}/_mapping"
12
12
  end
13
13
  end
14
14
  end
@@ -8,7 +8,7 @@ module Eson
8
8
 
9
9
  def path
10
10
  if index
11
- "/{-list|,|indices}/_refresh"
11
+ "/{indices}/_refresh"
12
12
  else
13
13
  "/_refresh"
14
14
  end
@@ -8,7 +8,7 @@ module Eson
8
8
 
9
9
  def path
10
10
  unless indices.empty?
11
- "/{-list|,|indices}/_segments"
11
+ "/{indices}/_segments"
12
12
  else
13
13
  "/_segments"
14
14
  end
@@ -8,7 +8,7 @@ module Eson
8
8
 
9
9
  def path
10
10
  unless indices.empty?
11
- "/{-list|,|indices}/_gateway/snapshot"
11
+ "/{indices}/_gateway/snapshot"
12
12
  else
13
13
  "/_gateway/snapshot"
14
14
  end
@@ -8,7 +8,7 @@ module Eson
8
8
 
9
9
  def path
10
10
  unless indices.empty?
11
- "/{-list|,|indices}/_stats"
11
+ "/{indices}/_stats"
12
12
  else
13
13
  "/_stats"
14
14
  end
@@ -8,7 +8,7 @@ module Eson
8
8
 
9
9
  def path
10
10
  if !indices.empty?
11
- "/{-list|,|indices}/_status"
11
+ "/{indices}/_status"
12
12
  else
13
13
  "/_status"
14
14
  end
@@ -8,7 +8,7 @@ module Eson
8
8
 
9
9
  def path
10
10
  unless indices.empty?
11
- "/{-list|,|indices}/_settings"
11
+ "/{indices}/_settings"
12
12
  else
13
13
  "/_settings"
14
14
  end
@@ -2,12 +2,16 @@ require 'faraday'
2
2
 
3
3
  module Eson
4
4
  module HTTP
5
+ # This is the HTTP specific subclass of Eson::Request that encodes all
6
+ # HTTP interactions.
5
7
  class Request < Eson::Request
6
8
  # This middleware circumvents faradays detection of
7
9
  # :get as special and emits a generic request - which
8
10
  # can have a body...
9
11
  # This is mostly due to ElasticSearchs reliance of
10
12
  # Bodys on get and delete.
13
+ #
14
+ # @api interal
11
15
  class GetHackMiddleware < Faraday::Middleware
12
16
  def call(env)
13
17
  env[:method] = "get" if env[:method] == :get
@@ -16,20 +20,26 @@ module Eson
16
20
  end
17
21
  end
18
22
 
19
- attr_accessor :request_method
20
-
23
+ # Constructs the base resource to send requests to.
24
+ #
25
+ # @api internal
26
+ # @return [Faraday::Connection] the connection
21
27
  def base_resource
22
28
  conn = Faraday.new(:url => client.node) do |builder|
23
- builder.use Faraday::Response::Logger, Eson::HTTP.logger
29
+ builder.use Faraday::Response::Logger, client.logger
24
30
  builder.use GetHackMiddleware
25
31
 
26
- builder.adapter :net_http
32
+ builder.adapter :net_http_persistent
27
33
  end
28
34
 
29
35
  conn.basic_auth(*client.auth) if client.auth?
30
36
  conn
31
37
  end
32
38
 
39
+ # Emits a HTTP request based on the parameters and API information.
40
+ #
41
+ # @api internal
42
+ # @return [Faraday::Response] the response
33
43
  def call
34
44
  resource = base_resource
35
45
 
@@ -54,29 +64,37 @@ module Eson
54
64
 
55
65
  response
56
66
  end
57
-
67
+
68
+ # Fills in the blanks in the path by using {Addressable::Template}.
69
+ #
70
+ # @api internal
71
+ # @return [String] the full uri
58
72
  def fill
59
73
  template = Addressable::Template.new(path)
60
-
74
+
61
75
  template_keys = template.keys.map(&:to_sym)
62
76
  expansions = {}
63
77
  query_values = {}
64
-
78
+
65
79
  url_params.each do |p|
66
80
  val = self.send(p)
67
-
81
+
68
82
  if template_keys.include? p
69
83
  expansions[p] = val if val
70
84
  else
71
85
  query_values[p] = val if val
72
86
  end
73
87
  end
74
-
88
+
75
89
  uri = template.expand(expansions)
76
90
  uri.query_values = query_values unless query_values.empty?
77
91
  uri
78
92
  end
79
-
93
+
94
+ # The parameters that are passed in the url. These are all params
95
+ # without the source params.
96
+ #
97
+ # @return [Array] the url parameters
80
98
  def url_params
81
99
  if self.respond_to? :source_param
82
100
  source_params = Array(source_param)
@@ -87,6 +105,10 @@ module Eson
87
105
  (parameters - source_params)
88
106
  end
89
107
 
108
+ # Returns the request method. If none is given, it is assumed to be
109
+ # `:get`.
110
+ #
111
+ # @return [Symbol] The request method.
90
112
  def request_method
91
113
  @request_method || :get
92
114
  end
@@ -1,13 +1,26 @@
1
1
  module Eson
2
+ # A plugins that parses HTTP responses as json and returns the json
2
3
  module ResponseParser
4
+ # This exception subclass representds parse errors. In addition to saving
5
+ # the response, it also saves the JSON source in a special field.
3
6
  class JSONParseError < Eson::Error
4
7
  attr_accessor :source
5
8
  end
6
-
9
+
10
+ # Evaluate the plugin.
11
+ #
12
+ # @param [Array<Object>] args Any number of args used for calling the endpoint.
13
+ # @return [Hash, Array] the parsed json
14
+ # @raise [JSONParseError] ES returned invalid JSON
7
15
  def call(*args)
8
16
  parse(super)
9
17
  end
10
-
18
+
19
+ # Parse the response.
20
+ #
21
+ # @param [#body] response The response
22
+ # @return [Hash, Array] the parsed json
23
+ # @raise [JSONParseError] ES returned invalid JSON
11
24
  def parse(response)
12
25
  begin
13
26
  MultiJson.decode(response.body) if response.body
@@ -16,7 +29,6 @@ module Eson
16
29
  error.source = response.body
17
30
  raise error
18
31
  end
19
-
20
32
  end
21
33
  end
22
34
  end
@@ -1,9 +1,15 @@
1
1
  module Eson
2
+ # A plugin to handle status codes.
2
3
  module StatusHandler
3
4
  def call(*args)
4
5
  handle(super)
5
6
  end
6
7
 
8
+ # Handle the response status.
9
+ #
10
+ # @raise [Eson::IndexNotFoundError] if the index is missing
11
+ # @raise [Eson::NotFoundError] if the document is missing
12
+ # @raise [Eson::Error] otherwise
7
13
  def handle(response)
8
14
  case response.status
9
15
  when 404
@@ -9,6 +9,13 @@ context "HTTP client" do
9
9
  :auto_call => false)
10
10
  end
11
11
 
12
- asserts("too many params") { client.index.params = {:foo => :bar} }.raises(NoMethodError)
13
-
12
+ asserts("too many params") { client.index.parameters = {:foo => :bar} }.raises(NoMethodError)
13
+
14
+ asserts("#with allows parameter change") {
15
+ req = client.with :index => :foo do |other_client|
16
+ other_client.search :q => "*"
17
+ end
18
+
19
+ req.index
20
+ }.equals(:foo)
14
21
  end
@@ -13,7 +13,7 @@ context 'HTTP client cluster api' do
13
13
  client.health
14
14
  end
15
15
 
16
- asserts("returns cluster info") { topic["cluster_name"]}.equals("elasticsearch")
16
+ asserts("returns cluster info") { topic["cluster_name"]}.equals("eson-test")
17
17
  end
18
18
 
19
19
  context "cluster state" do
@@ -37,6 +37,19 @@ context 'HTTP client quick api' do
37
37
  asserts("ok") { topic["ok"] }
38
38
  end
39
39
 
40
+ if ElasticSearch::Node.version > "0.19.0"
41
+ context "update" do
42
+ setup do
43
+ client.update :type => "bar",
44
+ :id => 600,
45
+ :script => "ctx._source.test = value",
46
+ :params => { :value => "foo" },
47
+ :refresh => true
48
+ end
49
+
50
+ asserts("ok") { topic["ok"] }
51
+ end
52
+ end
40
53
  end
41
54
 
42
55
  context "percolate" do
@@ -83,7 +96,27 @@ context 'HTTP client quick api' do
83
96
  asserts("number of docs") { topic["docs"].length }.equals(2)
84
97
  end
85
98
 
86
- unless ENV["ES_VERSION"] && ENV["ES_VERSION"] < "0.19.0"
99
+ unless ElasticSearch::Node.version < "0.19.0"
100
+ context "#explain" do
101
+ setup do
102
+ client.explain :index => "explain", :type => "bar", :id => 1,
103
+ :query => {:match_all => { }}
104
+ end
105
+
106
+ asserts("explanation output") { topic["explanation"] }.kind_of Hash
107
+ end
108
+
109
+ context "#validate" do
110
+ setup do
111
+ client.validate :index => "explain", :type => "bar",
112
+ :query => { :match_all => { } },
113
+ :explain => true
114
+ end
115
+
116
+ asserts("valid") { topic["valid"] }
117
+ end
118
+
119
+
87
120
  context "delete_by_query" do
88
121
  setup do
89
122
  client.index :index => "delete_by_query",
@@ -93,11 +126,11 @@ context 'HTTP client quick api' do
93
126
  :type => "foo",
94
127
  :doc => {:foo => :bar}
95
128
  client.refresh :index => "delete_by_query"
96
-
129
+
97
130
  client.delete_by_query :index => "delete_by_query",
98
131
  :query => { :match_all => {} }
99
132
  end
100
-
133
+
101
134
  asserts("no doc left") { client.search(:index => "delete_by_query")["hits"]["total"] }.equals(0)
102
135
  end
103
136
  end
@@ -129,16 +129,23 @@ context 'HTTP client' do
129
129
  setup do
130
130
  client.create_index :index => "abc"
131
131
  client.create_index :index => "def"
132
+ client.create_index :index => "ghi"
133
+ client.create_index :index => "jkl"
132
134
  client.aliases do |r|
133
135
  r.add "abc", "alias"
134
136
  r.add "def", "alias"
137
+ r.add "ghi", "alias", :routing => 1
138
+ r.add "jkl", "alias", :filter => { "term" => { "user" => "kimchy" } }
135
139
  end
136
140
  end
137
141
 
138
142
  asserts("ok") { topic["ok"] }
139
143
  asserts("can be queried") do
140
144
  client.status :index => "alias"
141
- end
145
+ end
146
+ asserts("can be retrieved") do
147
+ client.get_aliases
148
+ end
142
149
  end
143
150
 
144
151
  context "refresh" do
@@ -231,11 +238,7 @@ context 'HTTP client' do
231
238
  end
232
239
 
233
240
  context "exists?" do
234
- setup do
235
- client.exists? :index => 'does_not_exist_at_all'
236
- end
237
-
238
- asserts { topic }.equals(false)
241
+ denies { client.exists? :index => 'does_not_exist_at_all' }
239
242
  end
240
243
 
241
244
  context "index stats" do
@@ -247,11 +250,11 @@ context 'HTTP client' do
247
250
  end
248
251
 
249
252
  context "index segments" do
250
- setup do
251
- client.segments :index => 'default'
252
- end
253
-
254
- asserts { topic["ok"] }.equals(true)
255
- end
253
+ setup do
254
+ client.segments :index => 'default'
255
+ end
256
+
257
+ asserts { topic["ok"] }.equals(true)
258
+ end
256
259
 
257
260
  end
@@ -28,3 +28,6 @@ c.open_index :index => "for_closing" rescue nil
28
28
  c.delete_index :index => "for_closing" rescue nil
29
29
  c.delete_index :index => "for_reopening" rescue nil
30
30
  c.delete_index :index => "mappings" rescue nil
31
+
32
+ c.index :index => "explain", :type => "bar", :id => 1,
33
+ :doc => { :foo => :bar }
@@ -18,7 +18,7 @@ module Node
18
18
  module External
19
19
  def self.instance
20
20
  @node ||= begin
21
- node = ElasticSearch::Node::External.new("gateway.type" => "none")
21
+ node = ElasticSearch::Node::External.new("gateway.type" => "none", "cluster.name" => "eson-test")
22
22
  at_exit do
23
23
  node.close
24
24
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: eson-http
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-10 00:00:00.000000000 Z
12
+ date: 2013-01-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: 0.7.0
21
+ version: 0.8.0
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,7 +26,23 @@ dependencies:
26
26
  requirements:
27
27
  - - ~>
28
28
  - !ruby/object:Gem::Version
29
- version: 0.7.0
29
+ version: 0.8.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: net-http-persistent
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
30
46
  - !ruby/object:Gem::Dependency
31
47
  name: addressable
32
48
  requirement: !ruby/object:Gem::Requirement
@@ -118,14 +134,18 @@ files:
118
134
  - lib/eson/http/core/count.rb
119
135
  - lib/eson/http/core/delete.rb
120
136
  - lib/eson/http/core/delete_by_query.rb
137
+ - lib/eson/http/core/explain.rb
121
138
  - lib/eson/http/core/get.rb
122
139
  - lib/eson/http/core/index.rb
123
140
  - lib/eson/http/core/mget.rb
124
141
  - lib/eson/http/core/more_like_this.rb
125
142
  - lib/eson/http/core/msearch.rb
126
143
  - lib/eson/http/core/percolate.rb
144
+ - lib/eson/http/core/scroll.rb
127
145
  - lib/eson/http/core/search.rb
128
146
  - lib/eson/http/core/simple_search.rb
147
+ - lib/eson/http/core/update.rb
148
+ - lib/eson/http/core/validate.rb
129
149
  - lib/eson/http/indices/aliases.rb
130
150
  - lib/eson/http/indices/analyze.rb
131
151
  - lib/eson/http/indices/clear_cache.rb
@@ -136,6 +156,7 @@ files:
136
156
  - lib/eson/http/indices/delete_template.rb
137
157
  - lib/eson/http/indices/exists.rb
138
158
  - lib/eson/http/indices/flush.rb
159
+ - lib/eson/http/indices/get_aliases.rb
139
160
  - lib/eson/http/indices/get_mapping.rb
140
161
  - lib/eson/http/indices/get_settings.rb
141
162
  - lib/eson/http/indices/get_template.rb
@@ -173,18 +194,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
173
194
  - - ! '>='
174
195
  - !ruby/object:Gem::Version
175
196
  version: '0'
176
- segments:
177
- - 0
178
- hash: 3355220238060799392
179
197
  required_rubygems_version: !ruby/object:Gem::Requirement
180
198
  none: false
181
199
  requirements:
182
200
  - - ! '>='
183
201
  - !ruby/object:Gem::Version
184
202
  version: '0'
185
- segments:
186
- - 0
187
- hash: 3355220238060799392
188
203
  requirements: []
189
204
  rubyforge_project:
190
205
  rubygems_version: 1.8.21