es_client 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 843f33d86423abe66668f3a433877678d0e82435
4
- data.tar.gz: 785f403f7aae35ac33896e67b82b03e809d36c05
3
+ metadata.gz: c39fa72b26d853a0812871c797d706bc38fde342
4
+ data.tar.gz: 7bf1d0d4f2ae7f2878df4b4ce9d010296d51ceb2
5
5
  SHA512:
6
- metadata.gz: 647d9d56a31b29d570fc2e0cf175a2a717aa0e055acaf2ecb6ad84414d5b16761eac264a4de07f33d86e5ff1248dc30112f95552964dbdf499cf314615b95cfb
7
- data.tar.gz: 6943f76a4645317c49c196ab678a1ee108089516f9a73cc3850b98ad161d261387479e5a37e131357752cb55e747c0645fda60aa842526c6d3494a85195479d5
6
+ metadata.gz: fb83231b8766826cf7d53bff65795b33bcef8fb1519ded4e09783fca9433104dc52e7c3e10b6352df6076efa207da51c4f219b270cae24cd8e0b58327dab0998
7
+ data.tar.gz: 79ad067307fc768595da2d654d80575d23cd072780669e65afeac89318403f7d8099326f59fc3ec0a3acfa32d3cb93839368e556ce6afb661985a0459b855183
data/.gitignore CHANGED
@@ -15,4 +15,4 @@ mkmf.log
15
15
  .ruby-gemset
16
16
  .ruby-version
17
17
  /etc
18
- /log
18
+ /log/*.log
@@ -1,3 +1,10 @@
1
1
  language: ruby
2
+
3
+ services:
4
+ - elasticsearch
5
+
6
+ gemfile:
7
+ - Gemfile
8
+
2
9
  rvm:
3
- - 2.1.5
10
+ - 2.2.0
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # EsClient
2
2
 
3
+ [![Build Status](https://travis-ci.org/leschenko/es_client.png?branch=master)](https://travis-ci.org/leschenko/es_client)
4
+ [![Dependency Status](https://gemnasium.com/leschenko/es_client.png)](https://gemnasium.com/leschenko/es_client)
5
+
3
6
  This elasticsearch client is just all you need to index and search your data with persistent http connection.
4
7
  It don't tend to wrap [elasticsearch](http://elasticsearch.org) dsl into ruby style dsl.
5
8
  [Excon](https://github.com/excon/excon) used for http staff.
@@ -25,7 +28,7 @@ Or install it yourself as:
25
28
 
26
29
  Create index:
27
30
  ```ruby
28
- index = EsClient::Index.new('products', mappings: {product: {properties: {sku: {type: 'string'}}}}, settings: {number_of_shards: 1})
31
+ index = EsClient::Index.new('products')
29
32
  index.create
30
33
  ```
31
34
 
@@ -49,7 +52,33 @@ And, of course, search:
49
52
  index.search(query: {query_string: {query: 'table OR chair'}}).decoded
50
53
  ```
51
54
 
52
- ## With ActiveRecord model:
55
+ ### Configuration options
56
+ ```ruby
57
+ EsClient.setup do |config|
58
+ # path to log file
59
+ config.log_path = Rails.root.join('log', 'elasticsearch.log')
60
+
61
+ # log level (successful requests logged in debug)
62
+ # config.logger.level = ::Logger::Severity::INFO unless Rails.env.development?
63
+
64
+ # log options, should be set to false in production for better performance
65
+ # `log_binary` - log binary data in bulk requests
66
+ # `log_response` - log response json, can be disabled in production
67
+ # `pretty` - pretty generate json in logs
68
+ # config.logger_options = {log_binary: true, log_response: true, pretty: true}
69
+
70
+ # application wide index prefix
71
+ config.index_prefix = 'my_app_name_here'
72
+
73
+ # enable indexing callbacks
74
+ # config.callbacks_enabled = true
75
+
76
+ # options passed to Excon initializer
77
+ # config.http_client_options = {persistent: true}
78
+ end
79
+ ```
80
+
81
+ ### With ActiveRecord model:
53
82
 
54
83
  Include EsClient modules:
55
84
  ```ruby
@@ -92,7 +121,7 @@ User.es_client_reindex_with_progress
92
121
 
93
122
  ## Contributing
94
123
 
95
- 1. Fork it ( https://github.com/[my-github-username]/es_client/fork )
124
+ 1. Fork it ( https://github.com/leschenko/es_client/fork )
96
125
  2. Create your feature branch (`git checkout -b my-new-feature`)
97
126
  3. Commit your changes (`git commit -am 'Add some feature'`)
98
127
  4. Push to the branch (`git push origin my-new-feature`)
data/Rakefile CHANGED
@@ -1,7 +1,6 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
3
 
4
4
  RSpec::Core::RakeTask.new(:spec)
5
5
 
6
- task :default => :spec
7
-
6
+ task default: :spec
@@ -29,8 +29,8 @@ module EsClient
29
29
 
30
30
  def mapping(value=nil)
31
31
  if value
32
- @index.options[:mappings] ||= {}
33
- @index.options[:mappings].deep_merge!(value)
32
+ index.options[:mappings] ||= {}
33
+ index.options[:mappings].deep_merge!(value)
34
34
  else
35
35
  index.get_mapping
36
36
  end
@@ -38,8 +38,8 @@ module EsClient
38
38
 
39
39
  def settings(value=nil)
40
40
  if value
41
- @index.options[:settings] ||= {}
42
- @index.options[:settings].deep_merge!(value)
41
+ index.options[:settings] ||= {}
42
+ index.options[:settings].deep_merge!(value)
43
43
  else
44
44
  index.get_settings
45
45
  end
@@ -2,29 +2,26 @@ module EsClient
2
2
  class Client
3
3
  RETRY_TIMES = 1
4
4
 
5
+ HTTP_VERBS = %i(get post put delete head)
6
+
7
+ SUCCESS_HTTP_CODES = [200, 201]
8
+
5
9
  def initialize(host, options)
6
10
  @host = host
7
11
  @options = options
8
12
  end
9
13
 
10
- def get(path, options={})
11
- request options.merge(method: :get, path: path)
12
- end
13
-
14
- def post(path, options={})
15
- request options.merge(method: :post, path: path)
16
- end
17
-
18
- def put(path, options={})
19
- request options.merge(method: :put, path: path)
20
- end
21
-
22
- def delete(path, options={})
23
- request options.merge(method: :delete, path: path)
24
- end
14
+ HTTP_VERBS.each do |method|
15
+ class_eval <<-DEF, __FILE__, __LINE__ + 1
16
+ def #{method}(path, options={})
17
+ request options.merge(method: :#{method}, path: path)
18
+ end
25
19
 
26
- def head(path, options={})
27
- request options.merge(method: :head, path: path)
20
+ def #{method}!(path, options={})
21
+ options[:expects] = SUCCESS_HTTP_CODES
22
+ #{method}(path, options)
23
+ end
24
+ DEF
28
25
  end
29
26
 
30
27
  def request(options)
@@ -36,13 +33,16 @@ module EsClient
36
33
  response
37
34
  rescue Excon::Errors::SocketError => e
38
35
  if retry_times >= RETRY_TIMES
39
- exception = ::EsClient::Client::Error.new(e, self)
40
- EsClient.logger.exception(exception, http, options) if EsClient.logger
41
- raise exception
36
+ EsClient.logger.exception(e, http, options) if EsClient.logger
37
+ raise
42
38
  end
43
39
  retry_times += 1
40
+ EsClient.logger.info "[#{retry_times}] Try reconnect to #{@host}"
44
41
  reconnect!
45
42
  retry
43
+ rescue Excon::Errors::BadRequest => e
44
+ EsClient.logger.exception(e, http, options.merge(response: e.response.body)) if EsClient.logger
45
+ raise
46
46
  end
47
47
  end
48
48
 
@@ -57,15 +57,5 @@ module EsClient
57
57
  def log(message, level=:info)
58
58
  EsClient.logger.try!(level, message)
59
59
  end
60
-
61
- class Error < StandardError
62
- attr_reader :transport
63
-
64
- def initialize(excon_error, transport)
65
- @transport = transport
66
- super("#{excon_error.message} (#{excon_error.class})")
67
- set_backtrace(excon_error.backtrace)
68
- end
69
- end
70
60
  end
71
61
  end
@@ -23,11 +23,12 @@ module EsClient
23
23
 
24
24
  def create
25
25
  request_options = @options.present? ? {body: @options.to_json} : {}
26
- EsClient.client.post("/#{name}", request_options)
26
+ EsClient.client.post!("/#{name}", request_options)
27
27
  end
28
28
 
29
29
  def delete
30
- EsClient.client.delete("/#{name}")
30
+ return unless exists?
31
+ EsClient.client.delete!("/#{name}")
31
32
  end
32
33
 
33
34
  def refresh
@@ -6,17 +6,19 @@ module EsClient
6
6
  end
7
7
 
8
8
  def request(http, response, options)
9
- return unless debug?
9
+ log_level = response.success? ? :debug : :warn
10
+ return unless send("#{log_level}?")
10
11
  took = response.try!(:decoded).try!(:[], 'took') ? response.decoded['took'] : 'N/A'
11
12
  message = "[#{response.code}](#{took} msec) #{to_curl(http, options)}"
12
13
  message << "\n#{JSON.pretty_generate(response.decoded)}" if @options[:log_response] && response.try!(:decoded)
13
- debug message
14
+ send log_level, message
14
15
  end
15
16
 
16
17
  def exception(e, http=nil, options=nil)
18
+ return unless error?
17
19
  backtrace = e.backtrace.map { |l| "#{' ' * 2}#{l}" }.join("\n")
18
- curl = "\n #{to_curl(http, options)}" if options && http
19
- error "#{e.class} #{e.message} #{curl}\n#{backtrace}\n\n"
20
+ curl = "#{to_curl(http, options)}" if options && http
21
+ error "#{e.class} #{e.message}#{curl}\n#{options[:response]}\n#{backtrace}\n\n"
20
22
  end
21
23
 
22
24
  private
@@ -1,3 +1,3 @@
1
1
  module EsClient
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
File without changes
@@ -32,6 +32,18 @@ describe EsClient::Client do
32
32
  end
33
33
 
34
34
  context 'failure' do
35
+ it 'non bang method do not raise exception' do
36
+ Excon.stub({}, {body: '{}', status: 400})
37
+ transport = EsClient::Client.new('http://example.com', {})
38
+ expect { transport.get('/example', mock: true) }.not_to raise_error
39
+ end
40
+
41
+ it 'bang method raise exception' do
42
+ Excon.stub({}, {body: '{}', status: 400})
43
+ transport = EsClient::Client.new('http://example.com', {})
44
+ expect { transport.get!('/example', mock: true) }.to raise_error
45
+ end
46
+
35
47
  it 'reconnect on failed request' do
36
48
  transport = EsClient::Client.new('http://example.com', {})
37
49
  allow(transport.http).to receive(:request) { raise Excon::Errors::SocketError.new(StandardError.new) }
@@ -18,7 +18,7 @@ describe EsClient::Index do
18
18
  describe 'create' do
19
19
  it 'create index' do
20
20
  index = EsClient::Index.new('test_index')
21
- allow(EsClient.client).to receive(:post).with('/test_index', {}).and_return(double(:response, success?: true))
21
+ allow(EsClient.client).to receive(:post).with('/test_index', {expects: [200, 201]}).and_return(double(:response, success?: true))
22
22
  expect(index.create.success?).to eq true
23
23
  end
24
24
  end
@@ -26,7 +26,8 @@ describe EsClient::Index do
26
26
  describe 'delete' do
27
27
  it 'create index' do
28
28
  index = EsClient::Index.new('test_index')
29
- allow(EsClient.client).to receive(:delete).with('/test_index').and_return(double(:response, success?: true))
29
+ allow(EsClient.client).to receive(:delete!).with('/test_index').and_return(double(:response, success?: true))
30
+ expect(index).to receive(:exists?).and_return(true)
30
31
  expect(index.delete.success?).to eq true
31
32
  end
32
33
  end
@@ -10,7 +10,7 @@ describe EsClient::Index do
10
10
 
11
11
  it 'index not exists' do
12
12
  index = EsClient::Index.new('test_index')
13
- index.create
13
+ index.recreate
14
14
  expect(index.exists?).to eq true
15
15
  end
16
16
  end
@@ -32,22 +32,22 @@ describe EsClient::Index do
32
32
 
33
33
  it 'create index error' do
34
34
  index = EsClient::Index.new('test_index')
35
- index.create
36
- expect(index.create.success?).to eq false
35
+ index.recreate
36
+ expect { index.create }.to raise_exception(Excon::Errors::BadRequest)
37
37
  end
38
38
  end
39
39
 
40
40
  describe 'delete' do
41
41
  it 'delete index' do
42
42
  index = EsClient::Index.new('test_index')
43
- index.create
43
+ index.recreate
44
44
  expect(index.delete.success?).to eq true
45
45
  end
46
46
 
47
47
  it 'delete index error' do
48
48
  index = EsClient::Index.new('test_index')
49
49
  index.delete
50
- expect(index.delete.success?).to eq false
50
+ expect(index.delete).to be_nil
51
51
  end
52
52
  end
53
53
 
@@ -10,7 +10,7 @@ end
10
10
 
11
11
  EsClient.setup do |config|
12
12
  config.log_path = File.expand_path('../../log/elasticsearch.log', __FILE__)
13
- config.host = 'http://localhost:9201'
13
+ config.host = "http://localhost:#{ENV['ES_PORT'] || 9200}"
14
14
  end
15
15
 
16
16
  class RspecActiveRecordBase
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: es_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Leschenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-06 00:00:00.000000000 Z
11
+ date: 2015-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -135,13 +135,14 @@ files:
135
135
  - lib/es_client/logger.rb
136
136
  - lib/es_client/response.rb
137
137
  - lib/es_client/version.rb
138
+ - log/.gitkeep
138
139
  - spec/es_client/active_record/adapter_spec.rb
139
140
  - spec/es_client/active_record/glue_spec.rb
140
141
  - spec/es_client/active_record/shortcuts_spec.rb
142
+ - spec/es_client/client_spec.rb
141
143
  - spec/es_client/index_spec.rb
142
144
  - spec/es_client/logger_spec.rb
143
145
  - spec/es_client/responce_spec.rb
144
- - spec/es_client/transport_spec.rb
145
146
  - spec/es_client_spec.rb
146
147
  - spec/integration/es_client/index_spec.rb
147
148
  - spec/spec_helper.rb
@@ -173,10 +174,10 @@ test_files:
173
174
  - spec/es_client/active_record/adapter_spec.rb
174
175
  - spec/es_client/active_record/glue_spec.rb
175
176
  - spec/es_client/active_record/shortcuts_spec.rb
177
+ - spec/es_client/client_spec.rb
176
178
  - spec/es_client/index_spec.rb
177
179
  - spec/es_client/logger_spec.rb
178
180
  - spec/es_client/responce_spec.rb
179
- - spec/es_client/transport_spec.rb
180
181
  - spec/es_client_spec.rb
181
182
  - spec/integration/es_client/index_spec.rb
182
183
  - spec/spec_helper.rb