rsolr-cloud 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +10 -0
- data/README.md +25 -2
- data/Rakefile +5 -3
- data/lib/rsolr/cloud/connection.rb +9 -6
- data/lib/rsolr/cloud/error.rb +2 -3
- data/lib/rsolr/cloud/version.rb +1 -1
- data/rsolr-cloud.gemspec +14 -13
- data/spec/rsolr/cloud/connection_spec.rb +42 -23
- data/spec/spec_helper.rb +3 -3
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71d093877802659b1af783d4c56e708f0626b595
|
4
|
+
data.tar.gz: 590c93c0644deb1e64cdb11b19b745b0c8450e48
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98958fdc073fdec8a2964726cd151aa4269b1c2055d4b881419042fad5e7b2fbbd98a49d1e40fef3ff678c41335d20b914ce4e8fec73a86c625df4eab8e0e361
|
7
|
+
data.tar.gz: 209958d191198a820fe466266769a67ed4a8fb51e64bdd33bc5ba3f76de22557ac140eb71eeaca77caf5948563ebca6ac21c7defc454de3909f2443fbf0c4a3b
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2016-02-10 13:14:48 +0900 using RuboCop version 0.37.1.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
Metrics/LineLength:
|
10
|
+
Max: 100
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# RSolr::Cloud
|
2
2
|
|
3
|
-
|
3
|
+
A RSolr's connection adopter supporting SolrCloud.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -35,7 +35,7 @@ solr_client = RSolr::Client.new(cloud_connection,
|
|
35
35
|
read_timeout: 60,
|
36
36
|
open_timeout: 60)
|
37
37
|
|
38
|
-
# You can use rsolr as usual but collection
|
38
|
+
# You can use rsolr as usual but :collection option must be specified with the name of the collection.
|
39
39
|
response = solr.get('select', collection: 'collection1', params: {q: '*:*'})
|
40
40
|
|
41
41
|
```
|
@@ -47,3 +47,26 @@ response = solr.get('select', collection: 'collection1', params: {q: '*:*'})
|
|
47
47
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
48
48
|
4. Push to the branch (`git push origin my-new-feature`)
|
49
49
|
5. Create a new Pull Request
|
50
|
+
|
51
|
+
## Development
|
52
|
+
|
53
|
+
To install gems which are necessary for development and testing:
|
54
|
+
|
55
|
+
```
|
56
|
+
$ bundle install
|
57
|
+
```
|
58
|
+
|
59
|
+
To run the test suite:
|
60
|
+
|
61
|
+
```
|
62
|
+
$ rake
|
63
|
+
```
|
64
|
+
|
65
|
+
The default rake task contains RuboCop and RSpec. Each task can be run separately:
|
66
|
+
|
67
|
+
```
|
68
|
+
$ rake rubocop
|
69
|
+
```
|
70
|
+
```
|
71
|
+
$ rake spec
|
72
|
+
```
|
data/Rakefile
CHANGED
@@ -1,8 +1,10 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
2
|
|
3
3
|
begin
|
4
4
|
require 'rspec/core/rake_task'
|
5
5
|
RSpec::Core::RakeTask.new(:spec)
|
6
|
-
|
6
|
+
require 'rubocop/rake_task'
|
7
|
+
RuboCop::RakeTask.new
|
8
|
+
task default: [:rubocop, :spec]
|
9
|
+
rescue LoadError # rubocop:disable HandleExceptions
|
7
10
|
end
|
8
|
-
|
@@ -1,11 +1,12 @@
|
|
1
1
|
module RSolr
|
2
|
+
# rubocop:disable Metrics/ClassLength
|
2
3
|
module Cloud
|
3
4
|
# RSolr connection adapter for SolrCloud
|
4
5
|
class Connection < RSolr::Connection
|
5
6
|
include MonitorMixin
|
6
7
|
|
7
|
-
ZNODE_LIVE_NODES = '/live_nodes'
|
8
|
-
ZNODE_COLLECTIONS = '/collections'
|
8
|
+
ZNODE_LIVE_NODES = '/live_nodes'.freeze
|
9
|
+
ZNODE_COLLECTIONS = '/collections'.freeze
|
9
10
|
|
10
11
|
def initialize(zk)
|
11
12
|
super()
|
@@ -17,19 +18,19 @@ module RSolr
|
|
17
18
|
|
18
19
|
def execute(client, request_context)
|
19
20
|
collection_name = request_context[:collection]
|
20
|
-
|
21
|
+
raise 'The :collection option must be specified.' unless collection_name
|
21
22
|
path = request_context[:path].to_s
|
22
23
|
query = request_context[:query]
|
23
24
|
query = query ? "?#{query}" : ''
|
24
|
-
url = select_node(collection_name,
|
25
|
-
|
25
|
+
url = select_node(collection_name, path == 'update')
|
26
|
+
raise RSolr::Cloud::Error::NotEnoughNodes unless url
|
26
27
|
request_context[:uri] = RSolr::Uri.create(url).merge(path + query)
|
27
28
|
super(client, request_context)
|
28
29
|
end
|
29
30
|
|
30
31
|
private
|
31
32
|
|
32
|
-
def select_node(collection, leader_only
|
33
|
+
def select_node(collection, leader_only = false)
|
33
34
|
if leader_only
|
34
35
|
synchronize { @leader_urls[collection].to_a.sample }
|
35
36
|
else
|
@@ -66,7 +67,9 @@ module RSolr
|
|
66
67
|
@all_urls = {}
|
67
68
|
@leader_urls = {}
|
68
69
|
@collections.each do |name, state|
|
70
|
+
# rubocop:disable SpaceAroundOperators
|
69
71
|
@all_urls[name], @leader_urls[name] = available_urls(name, state)
|
72
|
+
# rubocop:enable SpaceAroundOperators
|
70
73
|
end
|
71
74
|
end
|
72
75
|
end
|
data/lib/rsolr/cloud/error.rb
CHANGED
data/lib/rsolr/cloud/version.rb
CHANGED
data/rsolr-cloud.gemspec
CHANGED
@@ -4,25 +4,26 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'rsolr/cloud/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'rsolr-cloud'
|
8
8
|
spec.version = Rsolr::Cloud::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
9
|
+
spec.authors = ['Shintaro Kimura']
|
10
|
+
spec.email = ['service@enigmo.co.jp']
|
11
|
+
spec.summary = 'The connection adopter supporting SolrCloud for RSolr'
|
12
|
+
spec.description = 'The connection adopter supporting SolrCloud for RSolr'
|
13
|
+
spec.homepage = ''
|
14
|
+
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0")
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
19
|
+
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_development_dependency
|
22
|
-
spec.add_development_dependency
|
23
|
-
spec.add_development_dependency
|
21
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
22
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
23
|
+
spec.add_development_dependency 'rspec', '~> 3.3'
|
24
24
|
spec.add_development_dependency 'activesupport', '~> 4.2'
|
25
25
|
spec.add_development_dependency 'zk-server', '~> 1.1.7'
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
26
|
+
spec.add_development_dependency 'zk', '~> 1.9.5'
|
27
|
+
spec.add_development_dependency 'rsolr', '~> 1.0.12'
|
28
|
+
spec.add_development_dependency 'rubocop', '~> 0.37.1'
|
28
29
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'spec_helper.rb'
|
2
2
|
|
3
3
|
RSpec.describe RSolr::Cloud::Connection do
|
4
|
-
|
5
4
|
before do
|
6
5
|
@zk_in_solr = ZK.new
|
7
6
|
delete_with_children(@zk_in_solr, '/live_nodes')
|
@@ -25,7 +24,9 @@ RSpec.describe RSolr::Cloud::Connection do
|
|
25
24
|
%w(collection1 collection2).each do |collection|
|
26
25
|
@zk_in_solr.create("/collections/#{collection}")
|
27
26
|
json = File.read("spec/files/#{collection}_all_nodes_alive.json")
|
28
|
-
@zk_in_solr.create("/collections/#{collection}/state.json",
|
27
|
+
@zk_in_solr.create("/collections/#{collection}/state.json",
|
28
|
+
json,
|
29
|
+
mode: :ephemeral)
|
29
30
|
end
|
30
31
|
@zk = ZK.new
|
31
32
|
@subject = RSolr::Cloud::Connection.new @zk
|
@@ -37,7 +38,8 @@ RSpec.describe RSolr::Cloud::Connection do
|
|
37
38
|
|
38
39
|
it 'should configure Net::HTTP with one of active node in select request.' do
|
39
40
|
expect(@subject.instance_variable_get(:@leader_urls)['collection1'].sort).to eq(
|
40
|
-
['http://192.168.1.22:8983/solr/collection1',
|
41
|
+
['http://192.168.1.22:8983/solr/collection1',
|
42
|
+
'http://192.168.1.24:8983/solr/collection1'].sort)
|
41
43
|
expect(@subject.instance_variable_get(:@all_urls)['collection1'].sort).to eq(
|
42
44
|
['http://192.168.1.21:8983/solr/collection1',
|
43
45
|
'http://192.168.1.22:8983/solr/collection1',
|
@@ -57,7 +59,8 @@ RSpec.describe RSolr::Cloud::Connection do
|
|
57
59
|
|
58
60
|
it 'should configure Net::HTTP with one of leader node in update request' do
|
59
61
|
expect(@subject.instance_variable_get(:@leader_urls)['collection1'].sort).to eq(
|
60
|
-
['http://192.168.1.22:8983/solr/collection1',
|
62
|
+
['http://192.168.1.22:8983/solr/collection1',
|
63
|
+
'http://192.168.1.24:8983/solr/collection1'].sort)
|
61
64
|
expect(@subject.instance_variable_get(:@all_urls)['collection1'].sort).to eq(
|
62
65
|
['http://192.168.1.21:8983/solr/collection1',
|
63
66
|
'http://192.168.1.22:8983/solr/collection1',
|
@@ -73,22 +76,29 @@ RSpec.describe RSolr::Cloud::Connection do
|
|
73
76
|
expect(request.body).to eq('the data')
|
74
77
|
double.as_null_object
|
75
78
|
end
|
76
|
-
@subject.execute client, collection: 'collection1',
|
79
|
+
@subject.execute client, collection: 'collection1',
|
80
|
+
method: :post,
|
81
|
+
path: 'update',
|
82
|
+
data: 'the data'
|
77
83
|
end
|
78
84
|
|
79
85
|
it 'should remove downed replica node and add recovered node' do
|
80
86
|
@zk_in_solr.delete('/live_nodes/192.168.1.21:8983_solr')
|
81
|
-
@zk_in_solr.set('/collections/collection1/state.json',
|
87
|
+
@zk_in_solr.set('/collections/collection1/state.json',
|
88
|
+
File.read('spec/files/collection1_replica_down.json'))
|
82
89
|
expect { @subject.instance_variable_get(:@leader_urls)['collection1'].sort }.to become_soon(
|
83
|
-
['http://192.168.1.22:8983/solr/collection1',
|
90
|
+
['http://192.168.1.22:8983/solr/collection1',
|
91
|
+
'http://192.168.1.24:8983/solr/collection1'].sort)
|
84
92
|
expect { @subject.instance_variable_get(:@all_urls)['collection1'].sort }.to become_soon(
|
85
93
|
['http://192.168.1.22:8983/solr/collection1',
|
86
94
|
'http://192.168.1.23:8983/solr/collection1',
|
87
95
|
'http://192.168.1.24:8983/solr/collection1'].sort)
|
88
96
|
@zk_in_solr.create('/live_nodes/192.168.1.21:8983_solr', mode: :ephemeral)
|
89
|
-
@zk_in_solr.set('/collections/collection1/state.json',
|
97
|
+
@zk_in_solr.set('/collections/collection1/state.json',
|
98
|
+
File.read('spec/files/collection1_all_nodes_alive.json'))
|
90
99
|
expect { @subject.instance_variable_get(:@leader_urls)['collection1'].sort }.to become_soon(
|
91
|
-
['http://192.168.1.22:8983/solr/collection1',
|
100
|
+
['http://192.168.1.22:8983/solr/collection1',
|
101
|
+
'http://192.168.1.24:8983/solr/collection1'].sort)
|
92
102
|
expect { @subject.instance_variable_get(:@all_urls)['collection1'].sort }.to become_soon(
|
93
103
|
['http://192.168.1.21:8983/solr/collection1',
|
94
104
|
'http://192.168.1.22:8983/solr/collection1',
|
@@ -98,17 +108,21 @@ RSpec.describe RSolr::Cloud::Connection do
|
|
98
108
|
|
99
109
|
it 'should remove downed leader node and add recovered node' do
|
100
110
|
@zk_in_solr.delete('/live_nodes/192.168.1.22:8983_solr')
|
101
|
-
@zk_in_solr.set('/collections/collection1/state.json',
|
111
|
+
@zk_in_solr.set('/collections/collection1/state.json',
|
112
|
+
File.read('spec/files/collection1_leader_down.json'))
|
102
113
|
expect { @subject.instance_variable_get(:@leader_urls)['collection1'].sort }.to become_soon(
|
103
|
-
['http://192.168.1.23:8983/solr/collection1',
|
114
|
+
['http://192.168.1.23:8983/solr/collection1',
|
115
|
+
'http://192.168.1.24:8983/solr/collection1'].sort)
|
104
116
|
expect { @subject.instance_variable_get(:@all_urls)['collection1'].sort }.to become_soon(
|
105
117
|
['http://192.168.1.21:8983/solr/collection1',
|
106
118
|
'http://192.168.1.23:8983/solr/collection1',
|
107
119
|
'http://192.168.1.24:8983/solr/collection1'].sort)
|
108
120
|
@zk_in_solr.create('/live_nodes/192.168.1.22:8983_solr', mode: :ephemeral)
|
109
|
-
@zk_in_solr.set('/collections/collection1/state.json',
|
121
|
+
@zk_in_solr.set('/collections/collection1/state.json',
|
122
|
+
File.read('spec/files/collection1_all_nodes_alive.json'))
|
110
123
|
expect { @subject.instance_variable_get(:@leader_urls)['collection1'].sort }.to become_soon(
|
111
|
-
['http://192.168.1.22:8983/solr/collection1',
|
124
|
+
['http://192.168.1.22:8983/solr/collection1',
|
125
|
+
'http://192.168.1.24:8983/solr/collection1'].sort)
|
112
126
|
expect { @subject.instance_variable_get(:@all_urls)['collection1'].sort }.to become_soon(
|
113
127
|
['http://192.168.1.21:8983/solr/collection1',
|
114
128
|
'http://192.168.1.22:8983/solr/collection1',
|
@@ -117,16 +131,20 @@ RSpec.describe RSolr::Cloud::Connection do
|
|
117
131
|
end
|
118
132
|
|
119
133
|
it 'should remove recovering leader node and add recovered node' do
|
120
|
-
@zk_in_solr.set('/collections/collection1/state.json',
|
134
|
+
@zk_in_solr.set('/collections/collection1/state.json',
|
135
|
+
File.read('spec/files/collection1_leader_recovering.json'))
|
121
136
|
expect { @subject.instance_variable_get(:@leader_urls)['collection1'].sort }.to become_soon(
|
122
|
-
['http://192.168.1.23:8983/solr/collection1',
|
137
|
+
['http://192.168.1.23:8983/solr/collection1',
|
138
|
+
'http://192.168.1.24:8983/solr/collection1'].sort)
|
123
139
|
expect { @subject.instance_variable_get(:@all_urls)['collection1'].sort }.to become_soon(
|
124
140
|
['http://192.168.1.21:8983/solr/collection1',
|
125
141
|
'http://192.168.1.23:8983/solr/collection1',
|
126
142
|
'http://192.168.1.24:8983/solr/collection1'].sort)
|
127
|
-
@zk_in_solr.set('/collections/collection1/state.json',
|
143
|
+
@zk_in_solr.set('/collections/collection1/state.json',
|
144
|
+
File.read('spec/files/collection1_all_nodes_alive.json'))
|
128
145
|
expect { @subject.instance_variable_get(:@leader_urls)['collection1'].sort }.to become_soon(
|
129
|
-
['http://192.168.1.23:8983/solr/collection1',
|
146
|
+
['http://192.168.1.23:8983/solr/collection1',
|
147
|
+
'http://192.168.1.24:8983/solr/collection1'].sort)
|
130
148
|
expect { @subject.instance_variable_get(:@all_urls)['collection1'].sort }.to become_soon(
|
131
149
|
['http://192.168.1.21:8983/solr/collection1',
|
132
150
|
'http://192.168.1.22:8983/solr/collection1',
|
@@ -136,11 +154,13 @@ RSpec.describe RSolr::Cloud::Connection do
|
|
136
154
|
|
137
155
|
it 'should add new created collection.' do
|
138
156
|
@zk_in_solr.create('/collections/collection3')
|
139
|
-
@zk_in_solr.create('/collections/collection3/state.json',
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
157
|
+
@zk_in_solr.create('/collections/collection3/state.json',
|
158
|
+
File.read('spec/files/collection3_all_nodes_alive.json'))
|
159
|
+
expect { @subject.instance_variable_get(:@leader_urls)['collection3'].to_a.sort }
|
160
|
+
.to become_soon(['http://192.168.1.24:8983/solr/collection3'])
|
161
|
+
expect { @subject.instance_variable_get(:@all_urls)['collection3'].to_a.sort }
|
162
|
+
.to become_soon(['http://192.168.1.21:8983/solr/collection3',
|
163
|
+
'http://192.168.1.24:8983/solr/collection3'].sort)
|
144
164
|
end
|
145
165
|
|
146
166
|
it 'should remove deleted collection.' do
|
@@ -153,5 +173,4 @@ RSpec.describe RSolr::Cloud::Connection do
|
|
153
173
|
@zk_in_solr.close if @zk_in_solr
|
154
174
|
@zk.close if @zk
|
155
175
|
end
|
156
|
-
|
157
176
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -12,7 +12,8 @@ module Helpers
|
|
12
12
|
delete_with_children(zk, File.join(path, node))
|
13
13
|
end
|
14
14
|
zk.delete(path)
|
15
|
-
rescue ZK::Exceptions::NoNode
|
15
|
+
rescue ZK::Exceptions::NoNode # rubocop:disable HandleExceptions
|
16
|
+
# don't care if it already exists or not.
|
16
17
|
end
|
17
18
|
|
18
19
|
def wait_until(timeout = 10)
|
@@ -23,7 +24,7 @@ module Helpers
|
|
23
24
|
break if result || started_on < timeout.second.ago
|
24
25
|
Thread.pass
|
25
26
|
end
|
26
|
-
|
27
|
+
raise 'Timed out' unless result
|
27
28
|
end
|
28
29
|
end
|
29
30
|
|
@@ -61,5 +62,4 @@ RSpec::Matchers.define :become_soon do |expected|
|
|
61
62
|
def supports_block_expectations?
|
62
63
|
true
|
63
64
|
end
|
64
|
-
|
65
65
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rsolr-cloud
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shintaro Kimura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-02-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -108,6 +108,20 @@ dependencies:
|
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: 1.0.12
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.37.1
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 0.37.1
|
111
125
|
description: The connection adopter supporting SolrCloud for RSolr
|
112
126
|
email:
|
113
127
|
- service@enigmo.co.jp
|
@@ -116,6 +130,7 @@ extensions: []
|
|
116
130
|
extra_rdoc_files: []
|
117
131
|
files:
|
118
132
|
- ".gitignore"
|
133
|
+
- ".rubocop.yml"
|
119
134
|
- Gemfile
|
120
135
|
- LICENSE.txt
|
121
136
|
- README.md
|
@@ -154,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
154
169
|
version: '0'
|
155
170
|
requirements: []
|
156
171
|
rubyforge_project:
|
157
|
-
rubygems_version: 2.
|
172
|
+
rubygems_version: 2.5.1
|
158
173
|
signing_key:
|
159
174
|
specification_version: 4
|
160
175
|
summary: The connection adopter supporting SolrCloud for RSolr
|