elastomer-client 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|