elastomer-client 0.3.3 → 0.4.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/CHANGELOG.md +11 -0
- data/docs/notifications.md +17 -5
- data/lib/elastomer/client.rb +18 -3
- data/lib/elastomer/client/bulk.rb +0 -1
- data/lib/elastomer/client/cluster.rb +97 -33
- data/lib/elastomer/client/docs.rb +0 -1
- data/lib/elastomer/client/errors.rb +50 -20
- data/lib/elastomer/client/index.rb +59 -1
- data/lib/elastomer/client/nodes.rb +43 -12
- data/lib/elastomer/client/repository.rb +127 -0
- data/lib/elastomer/client/snapshot.rb +127 -0
- data/lib/elastomer/version.rb +1 -1
- data/test/client/cluster_test.rb +33 -0
- data/test/client/docs_test.rb +5 -5
- data/test/client/errors_test.rb +48 -0
- data/test/client/index_test.rb +24 -0
- data/test/client/multi_search_test.rb +4 -4
- data/test/client/nodes_test.rb +24 -2
- data/test/client/repository_test.rb +108 -0
- data/test/client/snapshot_test.rb +111 -0
- data/test/client/template_test.rb +6 -0
- data/test/middleware/opaque_id_test.rb +3 -0
- data/test/test_helper.rb +18 -0
- metadata +10 -2
data/test/client/docs_test.rb
CHANGED
@@ -250,7 +250,7 @@ describe Elastomer::Client::Docs do
|
|
250
250
|
|
251
251
|
# for some reason, if there's no document indexed here all the mlt
|
252
252
|
# queries return zero results
|
253
|
-
@docs.
|
253
|
+
@docs.index \
|
254
254
|
:_id => 3,
|
255
255
|
:_type => 'doc1',
|
256
256
|
:title => 'the author of faraday',
|
@@ -380,25 +380,25 @@ describe Elastomer::Client::Docs do
|
|
380
380
|
# docs - An instance of Elastomer::Client::Docs or Elastomer::Client::Bulk. If
|
381
381
|
# nil uses the @docs instance variable.
|
382
382
|
def populate!(docs = @docs)
|
383
|
-
docs.
|
383
|
+
docs.index \
|
384
384
|
:_id => 1,
|
385
385
|
:_type => 'doc1',
|
386
386
|
:title => 'the author of gravatar',
|
387
387
|
:author => 'mojombo'
|
388
388
|
|
389
|
-
docs.
|
389
|
+
docs.index \
|
390
390
|
:_id => 2,
|
391
391
|
:_type => 'doc1',
|
392
392
|
:title => 'the author of resque',
|
393
393
|
:author => 'defunkt'
|
394
394
|
|
395
|
-
docs.
|
395
|
+
docs.index \
|
396
396
|
:_id => 1,
|
397
397
|
:_type => 'doc2',
|
398
398
|
:title => 'the author of logging',
|
399
399
|
:author => 'pea53'
|
400
400
|
|
401
|
-
docs.
|
401
|
+
docs.index \
|
402
402
|
:_id => 2,
|
403
403
|
:_type => 'doc2',
|
404
404
|
:title => 'the author of rubber-band',
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Elastomer::Client::Error do
|
4
|
+
|
5
|
+
it "is instantiated with a simple message" do
|
6
|
+
err = Elastomer::Client::Error.new "something went wrong"
|
7
|
+
assert_equal "something went wrong", err.message
|
8
|
+
end
|
9
|
+
|
10
|
+
it "is instantiated from an HTTP response" do
|
11
|
+
response = Faraday::Response.new(:body => "UTF8Error invalid middle-byte")
|
12
|
+
err = Elastomer::Client::Error.new(response)
|
13
|
+
assert_equal "UTF8Error invalid middle-byte", err.message
|
14
|
+
|
15
|
+
response = Faraday::Response.new(:body => {"error" => "IndexMissingException"})
|
16
|
+
err = Elastomer::Client::Error.new(response)
|
17
|
+
assert_equal "IndexMissingException", err.message
|
18
|
+
end
|
19
|
+
|
20
|
+
it "is instantiated from another exception" do
|
21
|
+
err = Faraday::Error::ConnectionFailed.new "could not connect to host"
|
22
|
+
err.set_backtrace %w[one two three four]
|
23
|
+
|
24
|
+
err = Elastomer::Client::Error.new(err, "POST", "/index/doc")
|
25
|
+
assert_equal "could not connect to host :: POST /index/doc", err.message
|
26
|
+
assert_equal %w[one two three four], err.backtrace
|
27
|
+
end
|
28
|
+
|
29
|
+
it "is fatal by default" do
|
30
|
+
assert Elastomer::Client::Error.fatal?, "client errors are fatal by default"
|
31
|
+
|
32
|
+
error = Elastomer::Client::Error.new "oops!"
|
33
|
+
assert !error.retry?, "client errors are not retryable by default"
|
34
|
+
end
|
35
|
+
|
36
|
+
it "has some fatal subclasses" do
|
37
|
+
assert Elastomer::Client::ResourceNotFound.fatal?, "Resource not found is fatal"
|
38
|
+
assert Elastomer::Client::ParsingError.fatal?, "Parsing error is fatal"
|
39
|
+
assert Elastomer::Client::SSLError.fatal?, "SSL error is fatal"
|
40
|
+
assert Elastomer::Client::RequestError.fatal?, "Request error is fatal"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "has some non-fatal subclasses" do
|
44
|
+
assert !Elastomer::Client::TimeoutError.fatal?, "Timeouts are not fatal"
|
45
|
+
assert !Elastomer::Client::ConnectionFailed.fatal?, "Connection failures are not fatal"
|
46
|
+
assert !Elastomer::Client::ServerError.fatal?, "Server errors are not fatal"
|
47
|
+
end
|
48
|
+
end
|
data/test/client/index_test.rb
CHANGED
@@ -130,6 +130,29 @@ describe Elastomer::Client::Index do
|
|
130
130
|
|
131
131
|
$client.cluster.update_aliases :add => {:index => @name, :alias => 'foofaloo'}
|
132
132
|
assert_equal({@name => {'aliases' => {'foofaloo' => {}}}}, @index.get_aliases)
|
133
|
+
|
134
|
+
if es_version_1_x?
|
135
|
+
assert_equal({@name => {'aliases' => {'foofaloo' => {}}}}, @index.get_alias("f*"))
|
136
|
+
assert_equal({}, @index.get_alias("r*"))
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
if es_version_1_x?
|
141
|
+
it 'adds and deletes aliases to the index' do
|
142
|
+
@index.create(nil)
|
143
|
+
assert_empty @index.get_alias("*")
|
144
|
+
|
145
|
+
@index.add_alias "gondolin"
|
146
|
+
aliases = @index.get_alias("*")
|
147
|
+
assert_equal %w[gondolin], aliases[@name]["aliases"].keys.sort
|
148
|
+
|
149
|
+
@index.add_alias "gondor"
|
150
|
+
aliases = @index.get_alias("*")
|
151
|
+
assert_equal %w[gondolin gondor], aliases[@name]["aliases"].keys.sort
|
152
|
+
|
153
|
+
@index.delete_alias "gon*"
|
154
|
+
assert_empty @index.get_alias("*")
|
155
|
+
end
|
133
156
|
end
|
134
157
|
|
135
158
|
# COMPATIBILITY ES 1.x removed English stopwords from the default analyzers,
|
@@ -154,6 +177,7 @@ describe Elastomer::Client::Index do
|
|
154
177
|
}
|
155
178
|
}
|
156
179
|
)
|
180
|
+
wait_for_index(@name)
|
157
181
|
|
158
182
|
tokens = @index.analyze 'Just a few words to analyze.', :analyzer => 'english_standard'
|
159
183
|
tokens = tokens['tokens'].map { |h| h['token'] }
|
@@ -100,25 +100,25 @@ describe Elastomer::Client::MultiSearch do
|
|
100
100
|
end
|
101
101
|
|
102
102
|
def populate!
|
103
|
-
@docs.
|
103
|
+
@docs.index \
|
104
104
|
:_id => 1,
|
105
105
|
:_type => 'doc1',
|
106
106
|
:title => 'the author of gravatar',
|
107
107
|
:author => 'mojombo'
|
108
108
|
|
109
|
-
@docs.
|
109
|
+
@docs.index \
|
110
110
|
:_id => 2,
|
111
111
|
:_type => 'doc1',
|
112
112
|
:title => 'the author of resque',
|
113
113
|
:author => 'defunkt'
|
114
114
|
|
115
|
-
@docs.
|
115
|
+
@docs.index \
|
116
116
|
:_id => 1,
|
117
117
|
:_type => 'doc2',
|
118
118
|
:title => 'the author of logging',
|
119
119
|
:author => 'pea53'
|
120
120
|
|
121
|
-
@docs.
|
121
|
+
@docs.index \
|
122
122
|
:_id => 2,
|
123
123
|
:_type => 'doc2',
|
124
124
|
:title => 'the author of rubber-band',
|
data/test/client/nodes_test.rb
CHANGED
@@ -2,7 +2,7 @@ require File.expand_path('../../test_helper', __FILE__)
|
|
2
2
|
|
3
3
|
describe Elastomer::Client::Nodes do
|
4
4
|
|
5
|
-
it 'gets info for the
|
5
|
+
it 'gets info for the node(s)' do
|
6
6
|
h = $client.nodes.info
|
7
7
|
assert h.key?('cluster_name'), 'the cluster name is returned'
|
8
8
|
assert_instance_of Hash, h['nodes'], 'the node list is returned'
|
@@ -16,6 +16,28 @@ describe Elastomer::Client::Nodes do
|
|
16
16
|
assert node.key?('indices'), 'indices stats are returned'
|
17
17
|
end
|
18
18
|
|
19
|
+
if es_version_1_x?
|
20
|
+
it 'fitlers node info' do
|
21
|
+
h = $client.nodes.info(:info => 'os')
|
22
|
+
node = h['nodes'].values.first
|
23
|
+
assert node.key?('os'), 'expected os info to be present'
|
24
|
+
assert !node.key?('jvm'), 'expected jvm info to be absent'
|
25
|
+
|
26
|
+
h = $client.nodes.info(:info => %w[jvm process])
|
27
|
+
node = h['nodes'].values.first
|
28
|
+
assert node.key?('jvm'), 'expected jvm info to be present'
|
29
|
+
assert node.key?('process'), 'expected process info to be present'
|
30
|
+
assert !node.key?('network'), 'expected network info to be absent'
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'filters node stats' do
|
34
|
+
h = $client.nodes.stats(:stats => 'http')
|
35
|
+
node = h['nodes'].values.first
|
36
|
+
assert node.key?('http'), 'expected http stats to be present'
|
37
|
+
assert !node.key?('indices'), 'expected indices stats to be absent'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
19
41
|
it 'gets the hot threads for the node(s)' do
|
20
42
|
str = $client.nodes.hot_threads :read_timeout => 2
|
21
43
|
assert_instance_of String, str
|
@@ -27,7 +49,7 @@ describe Elastomer::Client::Nodes do
|
|
27
49
|
assert_empty h['nodes']
|
28
50
|
end
|
29
51
|
|
30
|
-
it 'can be scoped to
|
52
|
+
it 'can be scoped to multiple nodes' do
|
31
53
|
h = $client.nodes(%w[node1 node2 node3]).info
|
32
54
|
assert_empty h['nodes']
|
33
55
|
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require File.expand_path('../../test_helper', __FILE__)
|
2
|
+
|
3
|
+
describe Elastomer::Client::Repository do
|
4
|
+
|
5
|
+
if es_version_1_x?
|
6
|
+
|
7
|
+
before do
|
8
|
+
@name = 'elastomer-repository-test'
|
9
|
+
@repo = $client.repository(@name)
|
10
|
+
@repo.delete if @repo.exists?
|
11
|
+
end
|
12
|
+
|
13
|
+
after do
|
14
|
+
@repo.delete if @repo.exists?
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'determines if a repo exists' do
|
18
|
+
assert_equal false, @repo.exists?
|
19
|
+
assert_equal false, @repo.exist?
|
20
|
+
with_tmp_repo do
|
21
|
+
assert_equal true, @repo.exists?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'creates repos' do
|
26
|
+
Dir.mktmpdir do |dir|
|
27
|
+
response = @repo.create({:type => 'fs', :settings => {:location => dir}})
|
28
|
+
assert_equal true, response["acknowledged"]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'cannot create a repo without a name' do
|
33
|
+
Dir.mktmpdir do |dir|
|
34
|
+
lambda {
|
35
|
+
$client.repository.create({:type => 'fs', :settings => {:location => dir}})
|
36
|
+
}.must_raise ArgumentError
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'gets repos' do
|
41
|
+
with_tmp_repo do
|
42
|
+
response = @repo.get
|
43
|
+
refute_nil response[@name]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'gets all repos' do
|
48
|
+
with_tmp_repo do
|
49
|
+
response = $client.repository.get
|
50
|
+
refute_nil response[@name]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'gets repo status' do
|
55
|
+
with_tmp_repo do
|
56
|
+
response = @repo.status
|
57
|
+
assert_equal [], response["snapshots"]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'gets status of all repos' do
|
62
|
+
response = $client.repository.status
|
63
|
+
assert_equal [], response["snapshots"]
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'updates repos' do
|
67
|
+
Dir.mktmpdir do |dir|
|
68
|
+
@repo.create({:type => 'fs', :settings => {:location => dir}})
|
69
|
+
response = @repo.update(:type => 'fs', :settings => {:compress => true, :location => dir})
|
70
|
+
assert_equal true, response["acknowledged"]
|
71
|
+
response = @repo.get
|
72
|
+
assert_equal "true", response[@name]["settings"]["compress"]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'cannot update a repo without a name' do
|
77
|
+
Dir.mktmpdir do |dir|
|
78
|
+
lambda {
|
79
|
+
$client.repository.update({:type => 'fs', :settings => {:location => dir}})
|
80
|
+
}.must_raise ArgumentError
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'deletes repos' do
|
85
|
+
with_tmp_repo do
|
86
|
+
response = @repo.delete
|
87
|
+
assert_equal true, response["acknowledged"]
|
88
|
+
assert_equal false, @repo.exists?
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'cannot delete a repo without a name' do
|
93
|
+
lambda {
|
94
|
+
$client.repository.delete
|
95
|
+
}.must_raise ArgumentError
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'gets snapshots' do
|
99
|
+
with_tmp_repo do
|
100
|
+
response = @repo.snapshots.get
|
101
|
+
assert_equal [], response["snapshots"]
|
102
|
+
response = @repo.snapshot.get
|
103
|
+
assert_equal [], response["snapshots"]
|
104
|
+
assert_equal false, @repo.snapshot('elastomer-test').exists?
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
|
2
|
+
require File.expand_path('../../test_helper', __FILE__)
|
3
|
+
|
4
|
+
describe Elastomer::Client::Snapshot do
|
5
|
+
if es_version_1_x?
|
6
|
+
before do
|
7
|
+
@index_name = 'elastomer-snapshot-test-index'
|
8
|
+
@index = $client.index(@index_name)
|
9
|
+
@repo_name = 'elastomer-snapshot-test'
|
10
|
+
@name = 'elastomer-test'
|
11
|
+
@repo = $client.repository(@repo_name)
|
12
|
+
@snapshot = $client.snapshot(@repo_name, @name)
|
13
|
+
@repo.delete if @repo.exists?
|
14
|
+
# No need to delete snapshots because each with_tmp_repo location is unique
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
@repo.delete if @repo.exists?
|
19
|
+
@index.delete if @index.exists?
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'determines if a snapshot exists' do
|
23
|
+
with_tmp_repo do
|
24
|
+
assert_equal false, @snapshot.exists?
|
25
|
+
assert_equal false, @snapshot.exist?
|
26
|
+
@snapshot.create({}, :wait_for_completion => true)
|
27
|
+
assert_equal true, @snapshot.exist?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'creates snapshots' do
|
32
|
+
with_tmp_repo do
|
33
|
+
response = @snapshot.create({}, :wait_for_completion => true)
|
34
|
+
assert_equal @name, response["snapshot"]["snapshot"]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'creates snapshots with options' do
|
39
|
+
@index.create(:number_of_shards => 1, :number_of_replicas => 0)
|
40
|
+
with_tmp_repo do
|
41
|
+
response = @snapshot.create({:indices => [@index_name]}, :wait_for_completion => true)
|
42
|
+
assert_equal [@index_name], response["snapshot"]["indices"]
|
43
|
+
assert_equal 1, response["snapshot"]["shards"]["total"]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'gets snapshot info for one and all' do
|
48
|
+
with_tmp_snapshot do
|
49
|
+
response = @snapshot.get
|
50
|
+
assert_equal @name, response["snapshots"][0]["snapshot"]
|
51
|
+
response = @repo.snapshots.get
|
52
|
+
assert_equal @name, response["snapshots"][0]["snapshot"]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'gets snapshot status for one and all' do
|
57
|
+
@index.create(:number_of_shards => 1, :number_of_replicas => 0)
|
58
|
+
with_tmp_repo do
|
59
|
+
@snapshot.create({:indices => [@index_name]}, :wait_for_completion => true)
|
60
|
+
response = @snapshot.status
|
61
|
+
assert_equal 1, response["snapshots"][0]["shards_stats"]["total"]
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'gets status of snapshots in progress' do
|
66
|
+
# we can't reliably get status of an in-progress snapshot in tests, so
|
67
|
+
# check for an empty result instead
|
68
|
+
response = @repo.snapshots.status
|
69
|
+
assert_equal [], response["snapshots"]
|
70
|
+
response = $client.snapshot.status
|
71
|
+
assert_equal [], response["snapshots"]
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'disallows nil repo name with non-nil snapshot name' do
|
75
|
+
assert_raises(ArgumentError) { $client.repository.snapshot('snapshot') }
|
76
|
+
assert_raises(ArgumentError) { $client.snapshot(nil, 'snapshot') }
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'deletes snapshots' do
|
80
|
+
with_tmp_snapshot do
|
81
|
+
response = @snapshot.delete
|
82
|
+
assert_equal true, response["acknowledged"]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'restores snapshots' do
|
87
|
+
@index.create(:number_of_shards => 1, :number_of_replicas => 0)
|
88
|
+
wait_for_index(@index_name)
|
89
|
+
with_tmp_repo do
|
90
|
+
@snapshot.create({:indices => [@index_name]}, :wait_for_completion => true)
|
91
|
+
@index.delete
|
92
|
+
response = @snapshot.restore({}, :wait_for_completion => true)
|
93
|
+
assert_equal 1, response["snapshot"]["shards"]["total"]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'restores snapshots with options' do
|
98
|
+
@index.create(:number_of_shards => 1, :number_of_replicas => 0)
|
99
|
+
wait_for_index(@index_name)
|
100
|
+
with_tmp_repo do
|
101
|
+
@snapshot.create({:indices => [@index_name]}, :wait_for_completion => true)
|
102
|
+
response = @snapshot.restore({
|
103
|
+
:rename_pattern => @index_name,
|
104
|
+
:rename_replacement => "#{@index_name}-restored"
|
105
|
+
}, :wait_for_completion => true)
|
106
|
+
assert_equal ["#{@index_name}-restored"], response["snapshot"]["indices"]
|
107
|
+
assert_equal 1, response["snapshot"]["shards"]["total"]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -11,6 +11,12 @@ describe Elastomer::Client::Cluster do
|
|
11
11
|
@template.delete if @template.exists?
|
12
12
|
end
|
13
13
|
|
14
|
+
it 'lists templates in the cluster' do
|
15
|
+
@template.create({:template => 'test-elastomer*'})
|
16
|
+
templates = $client.cluster.templates
|
17
|
+
assert !templates.empty?, "expected to see a template"
|
18
|
+
end
|
19
|
+
|
14
20
|
it 'creates a template' do
|
15
21
|
assert !@template.exists?, 'the template should not exist'
|
16
22
|
|
@@ -15,6 +15,9 @@ describe Elastomer::Middleware::OpaqueId do
|
|
15
15
|
]
|
16
16
|
}
|
17
17
|
|
18
|
+
stub.get('/') { |env|
|
19
|
+
[ 200, {}, {'version' => {'number' => '1.0.0'}} ]
|
20
|
+
}
|
18
21
|
stub.get('/_cluster/state') { |env|
|
19
22
|
[ 200, {'X-Opaque-Id' => "00000000-0000-0000-0000-000000000000"}, %q[{"foo":"bar"}] ]
|
20
23
|
}
|