solr_wrapper 0.6.1 → 0.7.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/exe/solr_wrapper +1 -15
- data/lib/solr_wrapper.rb +5 -1
- data/lib/solr_wrapper/configuration.rb +104 -0
- data/lib/solr_wrapper/downloader.rb +17 -0
- data/lib/solr_wrapper/instance.rb +58 -180
- data/lib/solr_wrapper/md5.rb +43 -0
- data/lib/solr_wrapper/settings.rb +112 -0
- data/lib/solr_wrapper/version.rb +1 -1
- data/spec/lib/solr_wrapper/configuration_spec.rb +24 -0
- data/spec/lib/solr_wrapper/instance_spec.rb +28 -1
- metadata +10 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76ae78f988ac44da700258433749f9af21e295c2
|
4
|
+
data.tar.gz: 17465fcf5dfddc6e79cb77e79daaefbe758285b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acd8180341d4acee240a201be0d85919b5ff5725388b43c8a24f0d9753147f495a094515d7a7b356215d1e1f84d1fdd667c9f27aab107169cbc548cd7a473d7b
|
7
|
+
data.tar.gz: 672f9d286d56d2ec8a2b77076b998a385b8de8e27ec85575d2f15d709ada04c14f862217ed79bfee1a74f6f023a8e3c9706da4c16c573d9a0b1033234d452afb
|
data/exe/solr_wrapper
CHANGED
@@ -31,7 +31,7 @@ OptionParser.new do |opts|
|
|
31
31
|
opts.on("-c", "--cloud", "Run solr in cloud mode") do |c|
|
32
32
|
options[:cloud] = c
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
opts.on("--download_path PATH", "Download/use solr at the given path") do |d|
|
36
36
|
options[:download_path] = d
|
37
37
|
end
|
@@ -59,20 +59,6 @@ end.parse!
|
|
59
59
|
|
60
60
|
# default to verbose
|
61
61
|
options[:verbose] = true if options[:verbose].nil?
|
62
|
-
default_configuration_paths = ['.solr_wrapper', '~/.solr_wrapper']
|
63
|
-
default_configuration_paths.each do |p|
|
64
|
-
path = File.expand_path('.solr_wrapper')
|
65
|
-
options[:config] ||= path if File.exist? path
|
66
|
-
end
|
67
|
-
|
68
|
-
if options[:config]
|
69
|
-
require 'erb'
|
70
|
-
require 'yaml'
|
71
|
-
config = YAML.load(ERB.new(IO.read(options[:config])).result(binding))
|
72
|
-
collection_config = config.delete(:collection) || {}
|
73
|
-
options = config.merge(options)
|
74
|
-
collection_options = collection_config.merge(collection_options)
|
75
|
-
end
|
76
62
|
|
77
63
|
instance = SolrWrapper.default_instance(options)
|
78
64
|
$stderr.print "Starting Solr #{instance.version} on port #{instance.port} ... "
|
data/lib/solr_wrapper.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
require 'solr_wrapper/version'
|
2
|
+
require 'solr_wrapper/configuration'
|
3
|
+
require 'solr_wrapper/settings'
|
4
|
+
require 'solr_wrapper/md5'
|
5
|
+
require 'solr_wrapper/downloader'
|
2
6
|
require 'solr_wrapper/instance'
|
3
7
|
|
4
8
|
module SolrWrapper
|
@@ -18,7 +22,7 @@ module SolrWrapper
|
|
18
22
|
end
|
19
23
|
|
20
24
|
def self.default_instance(options = {})
|
21
|
-
@default_instance ||= SolrWrapper::Instance.new
|
25
|
+
@default_instance ||= SolrWrapper::Instance.new options
|
22
26
|
end
|
23
27
|
|
24
28
|
##
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module SolrWrapper
|
2
|
+
class Configuration
|
3
|
+
attr_reader :options
|
4
|
+
|
5
|
+
def initialize(options)
|
6
|
+
@options = options
|
7
|
+
read_config
|
8
|
+
end
|
9
|
+
|
10
|
+
def solr_xml
|
11
|
+
options[:solr_xml]
|
12
|
+
end
|
13
|
+
|
14
|
+
def extra_lib_dir
|
15
|
+
options[:extra_lib_dir]
|
16
|
+
end
|
17
|
+
|
18
|
+
def validate
|
19
|
+
options[:validate]
|
20
|
+
end
|
21
|
+
|
22
|
+
def ignore_md5sum
|
23
|
+
options[:ignore_md5sum]
|
24
|
+
end
|
25
|
+
|
26
|
+
def md5sum
|
27
|
+
options[:md5sum]
|
28
|
+
end
|
29
|
+
|
30
|
+
def url
|
31
|
+
options[:url]
|
32
|
+
end
|
33
|
+
|
34
|
+
def port
|
35
|
+
# Check if the port option has been explicitly set to nil.
|
36
|
+
# this means to start solr wrapper on a random open port
|
37
|
+
return nil if options.key?(:port) && !options[:port]
|
38
|
+
options[:port] || SolrWrapper.default_instance_options[:port]
|
39
|
+
end
|
40
|
+
|
41
|
+
def download_path
|
42
|
+
options[:download_path]
|
43
|
+
end
|
44
|
+
|
45
|
+
def download_dir
|
46
|
+
options[:download_dir]
|
47
|
+
end
|
48
|
+
|
49
|
+
def solr_options
|
50
|
+
options.fetch(:solr_options, {})
|
51
|
+
end
|
52
|
+
|
53
|
+
def env
|
54
|
+
options.fetch(:env, {})
|
55
|
+
end
|
56
|
+
|
57
|
+
def instance_dir
|
58
|
+
options[:instance_dir]
|
59
|
+
end
|
60
|
+
|
61
|
+
def version
|
62
|
+
@version ||= options.fetch(:version, SolrWrapper.default_instance_options[:version])
|
63
|
+
end
|
64
|
+
|
65
|
+
def mirror_url
|
66
|
+
"http://www.apache.org/dyn/closer.lua/lucene/solr/#{version}/solr-#{version}.zip?asjson=true"
|
67
|
+
end
|
68
|
+
|
69
|
+
def cloud
|
70
|
+
options[:cloud]
|
71
|
+
end
|
72
|
+
|
73
|
+
def verbose?
|
74
|
+
!!options.fetch(:verbose, false)
|
75
|
+
end
|
76
|
+
|
77
|
+
def version_file
|
78
|
+
options[:version_file]
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def read_config
|
84
|
+
default_configuration_paths = ['.solr_wrapper', '~/.solr_wrapper']
|
85
|
+
default_configuration_paths.each do |p|
|
86
|
+
path = File.expand_path(p)
|
87
|
+
options[:config] ||= path if File.exist? path
|
88
|
+
end
|
89
|
+
|
90
|
+
if options[:config]
|
91
|
+
$stdout.puts "Loading configuration from #{options[:config]}" if verbose?
|
92
|
+
config = YAML.load(ERB.new(IO.read(options[:config])).result(binding))
|
93
|
+
unless config
|
94
|
+
$stderr.puts "Unable to parse config #{options[:config]}" if verbose?
|
95
|
+
return
|
96
|
+
end
|
97
|
+
collection_config = config.delete(:collection) || {}
|
98
|
+
@options = config.merge(options)
|
99
|
+
elsif verbose?
|
100
|
+
$stdout.puts "No config specified"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module SolrWrapper
|
2
|
+
class Downloader
|
3
|
+
def self.fetch_with_progressbar(url, output)
|
4
|
+
pbar = ProgressBar.create(title: File.basename(url), total: nil, format: "%t: |%B| %p%% (%e )")
|
5
|
+
open(url, content_length_proc: lambda do|t|
|
6
|
+
if t && 0 < t
|
7
|
+
pbar.total = t
|
8
|
+
end
|
9
|
+
end,
|
10
|
+
progress_proc: lambda do|s|
|
11
|
+
pbar.progress = s
|
12
|
+
end) do |io|
|
13
|
+
IO.copy_stream(io, output)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -8,10 +8,12 @@ require 'socket'
|
|
8
8
|
require 'stringio'
|
9
9
|
require 'tmpdir'
|
10
10
|
require 'zip'
|
11
|
+
require 'erb'
|
12
|
+
require 'yaml'
|
11
13
|
|
12
14
|
module SolrWrapper
|
13
15
|
class Instance
|
14
|
-
attr_reader :
|
16
|
+
attr_reader :config, :md5, :pid
|
15
17
|
|
16
18
|
##
|
17
19
|
# @param [Hash] options
|
@@ -31,8 +33,26 @@ module SolrWrapper
|
|
31
33
|
# @option options [Boolean] :ignore_md5sum
|
32
34
|
# @option options [Hash] :solr_options
|
33
35
|
# @option options [Hash] :env
|
36
|
+
# @option options [String] :config
|
34
37
|
def initialize(options = {})
|
35
|
-
@
|
38
|
+
@config = Settings.new(Configuration.new(options))
|
39
|
+
@md5 = MD5.new(@config)
|
40
|
+
end
|
41
|
+
|
42
|
+
def host
|
43
|
+
config.host
|
44
|
+
end
|
45
|
+
|
46
|
+
def port
|
47
|
+
config.port
|
48
|
+
end
|
49
|
+
|
50
|
+
def url
|
51
|
+
config.url
|
52
|
+
end
|
53
|
+
|
54
|
+
def version
|
55
|
+
config.version
|
36
56
|
end
|
37
57
|
|
38
58
|
def wrap(&_block)
|
@@ -47,8 +67,8 @@ module SolrWrapper
|
|
47
67
|
# Start Solr and wait for it to become available
|
48
68
|
def start
|
49
69
|
extract_and_configure
|
50
|
-
if managed?
|
51
|
-
exec('start', p: port, c:
|
70
|
+
if config.managed?
|
71
|
+
exec('start', p: port, c: config.cloud)
|
52
72
|
|
53
73
|
# Wait for solr to start
|
54
74
|
unless status
|
@@ -60,7 +80,7 @@ module SolrWrapper
|
|
60
80
|
##
|
61
81
|
# Stop Solr and wait for it to finish exiting
|
62
82
|
def stop
|
63
|
-
if managed? && started?
|
83
|
+
if config.managed? && started?
|
64
84
|
|
65
85
|
exec('stop', p: port)
|
66
86
|
# Wait for solr to stop
|
@@ -75,15 +95,15 @@ module SolrWrapper
|
|
75
95
|
##
|
76
96
|
# Stop Solr and wait for it to finish exiting
|
77
97
|
def restart
|
78
|
-
if managed? && started?
|
79
|
-
exec('restart', p: port, c:
|
98
|
+
if config.managed? && started?
|
99
|
+
exec('restart', p: port, c: config.cloud)
|
80
100
|
end
|
81
101
|
end
|
82
102
|
|
83
103
|
##
|
84
104
|
# Check the status of a managed Solr service
|
85
105
|
def status
|
86
|
-
return true unless managed?
|
106
|
+
return true unless config.managed?
|
87
107
|
|
88
108
|
out = exec('status').read
|
89
109
|
out =~ /running on port #{port}/
|
@@ -136,28 +156,15 @@ module SolrWrapper
|
|
136
156
|
end
|
137
157
|
end
|
138
158
|
|
139
|
-
##
|
140
|
-
# Get the host this Solr instance is bound to
|
141
|
-
def host
|
142
|
-
'127.0.0.1'
|
143
|
-
end
|
144
|
-
|
145
|
-
##
|
146
|
-
# Get the port this Solr instance is running at
|
147
|
-
def port
|
148
|
-
@port ||= options[:port]
|
149
|
-
@port ||= random_open_port.to_s
|
150
|
-
end
|
151
|
-
|
152
159
|
##
|
153
160
|
# Clean up any files solr_wrapper may have downloaded
|
154
161
|
def clean!
|
155
162
|
stop
|
156
163
|
remove_instance_dir!
|
157
|
-
FileUtils.remove_entry(download_path) if File.exists?(download_path)
|
158
|
-
FileUtils.remove_entry(tmp_save_dir, true) if File.exists? tmp_save_dir
|
159
|
-
|
160
|
-
FileUtils.remove_entry(version_file) if File.exists? version_file
|
164
|
+
FileUtils.remove_entry(config.download_path) if File.exists?(config.download_path)
|
165
|
+
FileUtils.remove_entry(config.tmp_save_dir, true) if File.exists? config.tmp_save_dir
|
166
|
+
md5.clean!
|
167
|
+
FileUtils.remove_entry(config.version_file) if File.exists? config.version_file
|
161
168
|
end
|
162
169
|
|
163
170
|
##
|
@@ -166,26 +173,14 @@ module SolrWrapper
|
|
166
173
|
FileUtils.remove_entry(instance_dir, true) if File.exists? instance_dir
|
167
174
|
end
|
168
175
|
|
169
|
-
##
|
170
|
-
# Get a (likely) URL to the solr instance
|
171
|
-
def url
|
172
|
-
"http://#{host}:#{port}/solr/"
|
173
|
-
end
|
174
|
-
|
175
176
|
def configure
|
176
177
|
raise_error_unless_extracted
|
177
|
-
FileUtils.cp
|
178
|
-
FileUtils.cp_r File.join(
|
179
|
-
end
|
180
|
-
|
181
|
-
def instance_dir
|
182
|
-
@instance_dir ||= options.fetch(:instance_dir, File.join(Dir.tmpdir, File.basename(download_url, ".zip")))
|
178
|
+
FileUtils.cp config.solr_xml, File.join(config.instance_dir, 'server', 'solr', 'solr.xml') if config.solr_xml
|
179
|
+
FileUtils.cp_r File.join(config.extra_lib_dir, '.'), File.join(config.instance_dir, 'server', 'solr', 'lib') if config.extra_lib_dir
|
183
180
|
end
|
184
181
|
|
185
182
|
def extract_and_configure
|
186
|
-
|
187
|
-
configure
|
188
|
-
instance_dir
|
183
|
+
extract.tap { configure }
|
189
184
|
end
|
190
185
|
|
191
186
|
# rubocop:disable Lint/RescueException
|
@@ -194,7 +189,7 @@ module SolrWrapper
|
|
194
189
|
# Does noting if solr already exists at instance_dir
|
195
190
|
# @return [String] instance_dir Directory where solr has been installed
|
196
191
|
def extract
|
197
|
-
return instance_dir if extracted?
|
192
|
+
return config.instance_dir if extracted?
|
198
193
|
|
199
194
|
zip_path = download
|
200
195
|
|
@@ -202,59 +197,43 @@ module SolrWrapper
|
|
202
197
|
Zip::File.open(zip_path) do |zip_file|
|
203
198
|
# Handle entries one by one
|
204
199
|
zip_file.each do |entry|
|
205
|
-
dest_file = File.join(tmp_save_dir, entry.name)
|
200
|
+
dest_file = File.join(config.tmp_save_dir, entry.name)
|
206
201
|
FileUtils.remove_entry(dest_file, true)
|
207
202
|
entry.extract(dest_file)
|
208
203
|
end
|
209
204
|
end
|
210
205
|
|
211
206
|
rescue Exception => e
|
212
|
-
abort "Unable to unzip #{zip_path} into #{tmp_save_dir}: #{e.message}"
|
207
|
+
abort "Unable to unzip #{zip_path} into #{config.tmp_save_dir}: #{e.message}"
|
213
208
|
end
|
214
209
|
|
215
210
|
begin
|
216
|
-
FileUtils.remove_dir(instance_dir, true)
|
217
|
-
FileUtils.cp_r File.join(tmp_save_dir, File.basename(download_url, ".zip")), instance_dir
|
218
|
-
self.extracted_version = version
|
219
|
-
FileUtils.chmod 0755, solr_binary
|
211
|
+
FileUtils.remove_dir(config.instance_dir, true)
|
212
|
+
FileUtils.cp_r File.join(config.tmp_save_dir, File.basename(config.download_url, ".zip")), config.instance_dir
|
213
|
+
self.extracted_version = config.version
|
214
|
+
FileUtils.chmod 0755, config.solr_binary
|
220
215
|
rescue Exception => e
|
221
|
-
abort "Unable to copy #{tmp_save_dir} to #{instance_dir}: #{e.message}"
|
216
|
+
abort "Unable to copy #{config.tmp_save_dir} to #{config.instance_dir}: #{e.message}"
|
222
217
|
end
|
223
218
|
|
224
|
-
instance_dir
|
219
|
+
config.instance_dir
|
225
220
|
ensure
|
226
|
-
FileUtils.remove_entry tmp_save_dir if File.exists? tmp_save_dir
|
221
|
+
FileUtils.remove_entry config.tmp_save_dir if File.exists? config.tmp_save_dir
|
227
222
|
end
|
228
223
|
# rubocop:enable Lint/RescueException
|
229
224
|
|
230
|
-
def version
|
231
|
-
@version ||= options.fetch(:version, SolrWrapper.default_solr_version)
|
232
|
-
end
|
233
|
-
|
234
225
|
protected
|
235
226
|
|
236
227
|
def extracted?
|
237
|
-
File.exists?(solr_binary) && extracted_version == version
|
228
|
+
File.exists?(config.solr_binary) && extracted_version == config.version
|
238
229
|
end
|
239
230
|
|
240
231
|
def download
|
241
|
-
unless File.exists?(download_path) && validate?(download_path)
|
242
|
-
fetch_with_progressbar download_url, download_path
|
243
|
-
validate! download_path
|
244
|
-
end
|
245
|
-
download_path
|
246
|
-
end
|
247
|
-
|
248
|
-
def validate?(file)
|
249
|
-
return true if options[:validate] == false
|
250
|
-
|
251
|
-
Digest::MD5.file(file).hexdigest == expected_md5sum
|
252
|
-
end
|
253
|
-
|
254
|
-
def validate!(file)
|
255
|
-
unless validate? file
|
256
|
-
raise "MD5 mismatch" unless options[:ignore_md5sum]
|
232
|
+
unless File.exists?(config.download_path) && md5.validate?(config.download_path)
|
233
|
+
Downloader.fetch_with_progressbar config.download_url, config.download_path
|
234
|
+
md5.validate! config.download_path
|
257
235
|
end
|
236
|
+
config.download_path
|
258
237
|
end
|
259
238
|
|
260
239
|
##
|
@@ -270,7 +249,7 @@ module SolrWrapper
|
|
270
249
|
def exec(cmd, options = {})
|
271
250
|
silence_output = !options.delete(:output)
|
272
251
|
|
273
|
-
args = [solr_binary, cmd] + solr_options.merge(options).map do |k, v|
|
252
|
+
args = [config.solr_binary, cmd] + config.solr_options.merge(options).map do |k, v|
|
274
253
|
case v
|
275
254
|
when true
|
276
255
|
"-#{k}"
|
@@ -283,11 +262,11 @@ module SolrWrapper
|
|
283
262
|
|
284
263
|
if IO.respond_to? :popen4
|
285
264
|
# JRuby
|
286
|
-
env_str = env.map { |k, v| "#{Shellwords.escape(k)}=#{Shellwords.escape(v)}" }.join(" ")
|
265
|
+
env_str = config.env.map { |k, v| "#{Shellwords.escape(k)}=#{Shellwords.escape(v)}" }.join(" ")
|
287
266
|
pid, input, output, error = IO.popen4(env_str + " " + args.join(" "))
|
288
267
|
@pid = pid
|
289
268
|
stringio = StringIO.new
|
290
|
-
if verbose? && !silence_output
|
269
|
+
if config.verbose? && !silence_output
|
291
270
|
IO.copy_stream(output, $stderr)
|
292
271
|
IO.copy_stream(error, $stderr)
|
293
272
|
else
|
@@ -300,10 +279,10 @@ module SolrWrapper
|
|
300
279
|
error.close
|
301
280
|
exit_status = Process.waitpid2(@pid).last
|
302
281
|
else
|
303
|
-
IO.popen(env, args + [err: [:child, :out]]) do |io|
|
282
|
+
IO.popen(config.env, args + [err: [:child, :out]]) do |io|
|
304
283
|
stringio = StringIO.new
|
305
284
|
|
306
|
-
if verbose? && !silence_output
|
285
|
+
if config.verbose? && !silence_output
|
307
286
|
IO.copy_stream(io, $stderr)
|
308
287
|
else
|
309
288
|
IO.copy_stream(io, stringio)
|
@@ -325,119 +304,18 @@ module SolrWrapper
|
|
325
304
|
|
326
305
|
private
|
327
306
|
|
328
|
-
def download_url
|
329
|
-
@download_url ||= options.fetch(:url) { default_download_url }
|
330
|
-
end
|
331
|
-
|
332
|
-
def default_download_url
|
333
|
-
@default_url ||= begin
|
334
|
-
mirror_url = "http://www.apache.org/dyn/closer.lua/lucene/solr/#{version}/solr-#{version}.zip?asjson=true"
|
335
|
-
json = open(mirror_url).read
|
336
|
-
doc = JSON.parse(json)
|
337
|
-
doc['preferred'] + doc['path_info']
|
338
|
-
end
|
339
|
-
rescue SocketError
|
340
|
-
"http://www.us.apache.org/dist/lucene/solr/#{version}/solr-#{version}.zip"
|
341
|
-
end
|
342
|
-
|
343
|
-
def md5url
|
344
|
-
"http://www.us.apache.org/dist/lucene/solr/#{version}/solr-#{version}.zip.md5"
|
345
|
-
end
|
346
|
-
|
347
|
-
def solr_options
|
348
|
-
options.fetch(:solr_options, {})
|
349
|
-
end
|
350
|
-
|
351
|
-
def env
|
352
|
-
options.fetch(:env, {})
|
353
|
-
end
|
354
|
-
|
355
|
-
def download_path
|
356
|
-
@download_path ||= options.fetch(:download_path, default_download_path)
|
357
|
-
end
|
358
|
-
|
359
|
-
def default_download_path
|
360
|
-
File.join(download_dir, File.basename(download_url))
|
361
|
-
end
|
362
|
-
|
363
|
-
def download_dir
|
364
|
-
@download_dir ||= options.fetch(:download_dir, Dir.tmpdir)
|
365
|
-
FileUtils.mkdir_p @download_dir
|
366
|
-
@download_dir
|
367
|
-
end
|
368
|
-
|
369
|
-
def verbose?
|
370
|
-
!!options.fetch(:verbose, false)
|
371
|
-
end
|
372
|
-
|
373
|
-
def managed?
|
374
|
-
File.exists?(instance_dir)
|
375
|
-
end
|
376
|
-
|
377
|
-
def version_file
|
378
|
-
options.fetch(:version_file, File.join(instance_dir, "VERSION"))
|
379
|
-
end
|
380
|
-
|
381
|
-
def expected_md5sum
|
382
|
-
@md5sum ||= options.fetch(:md5sum, open(md5file).read.split(" ").first)
|
383
|
-
end
|
384
|
-
|
385
|
-
def solr_binary
|
386
|
-
File.join(instance_dir, "bin", "solr")
|
387
|
-
end
|
388
|
-
|
389
|
-
def md5sum_path
|
390
|
-
File.join(download_dir, File.basename(md5url))
|
391
|
-
end
|
392
|
-
|
393
|
-
def tmp_save_dir
|
394
|
-
@tmp_save_dir ||= Dir.mktmpdir
|
395
|
-
end
|
396
|
-
|
397
|
-
def fetch_with_progressbar(url, output)
|
398
|
-
pbar = ProgressBar.create(title: File.basename(url), total: nil, format: "%t: |%B| %p%% (%e )")
|
399
|
-
open(url, content_length_proc: lambda do|t|
|
400
|
-
if t && 0 < t
|
401
|
-
pbar.total = t
|
402
|
-
end
|
403
|
-
end,
|
404
|
-
progress_proc: lambda do|s|
|
405
|
-
pbar.progress = s
|
406
|
-
end) do |io|
|
407
|
-
IO.copy_stream(io, output)
|
408
|
-
end
|
409
|
-
end
|
410
|
-
|
411
|
-
def md5file
|
412
|
-
unless File.exists? md5sum_path
|
413
|
-
fetch_with_progressbar md5url, md5sum_path
|
414
|
-
end
|
415
|
-
|
416
|
-
md5sum_path
|
417
|
-
end
|
418
|
-
|
419
307
|
def extracted_version
|
420
|
-
File.read(version_file).strip if File.exists? version_file
|
308
|
+
File.read(config.version_file).strip if File.exists? config.version_file
|
421
309
|
end
|
422
310
|
|
423
311
|
def extracted_version=(version)
|
424
|
-
File.open(version_file, "w") do |f|
|
312
|
+
File.open(config.version_file, "w") do |f|
|
425
313
|
f.puts version
|
426
314
|
end
|
427
315
|
end
|
428
316
|
|
429
|
-
def random_open_port
|
430
|
-
socket = Socket.new(:INET, :STREAM, 0)
|
431
|
-
begin
|
432
|
-
socket.bind(Addrinfo.tcp('127.0.0.1', 0))
|
433
|
-
socket.local_address.ip_port
|
434
|
-
ensure
|
435
|
-
socket.close
|
436
|
-
end
|
437
|
-
end
|
438
|
-
|
439
317
|
def raise_error_unless_extracted
|
440
|
-
raise RuntimeError, "there is no solr instance at #{instance_dir}. Run SolrWrapper.extract first." unless extracted?
|
318
|
+
raise RuntimeError, "there is no solr instance at #{config.instance_dir}. Run SolrWrapper.extract first." unless extracted?
|
441
319
|
end
|
442
320
|
end
|
443
321
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module SolrWrapper
|
2
|
+
class MD5
|
3
|
+
attr_reader :config
|
4
|
+
def initialize(config)
|
5
|
+
@config = config
|
6
|
+
end
|
7
|
+
|
8
|
+
def clean!
|
9
|
+
FileUtils.remove_entry(config.md5sum_path) if File.exists? config.md5sum_path
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate?(file)
|
13
|
+
return true if config.validate == false
|
14
|
+
|
15
|
+
Digest::MD5.file(file).hexdigest == expected_sum
|
16
|
+
end
|
17
|
+
|
18
|
+
def validate!(file)
|
19
|
+
unless validate? file
|
20
|
+
raise "MD5 mismatch" unless config.ignore_md5sum
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def expected_sum
|
27
|
+
@md5sum ||= config.md5sum
|
28
|
+
@md5sum ||= read_file
|
29
|
+
end
|
30
|
+
|
31
|
+
def read_file
|
32
|
+
open(md5file).read.split(" ").first
|
33
|
+
end
|
34
|
+
|
35
|
+
def md5file
|
36
|
+
unless File.exists? config.md5sum_path
|
37
|
+
Downloader.fetch_with_progressbar config.md5url, config.md5sum_path
|
38
|
+
end
|
39
|
+
|
40
|
+
config.md5sum_path
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module SolrWrapper
|
2
|
+
# Configuraton that comes from static and dynamic sources.
|
3
|
+
class Settings < Delegator
|
4
|
+
|
5
|
+
def __getobj__
|
6
|
+
@static_config # return object we are delegating to, required
|
7
|
+
end
|
8
|
+
|
9
|
+
alias static_config __getobj__
|
10
|
+
|
11
|
+
def __setobj__(obj)
|
12
|
+
@static_config = obj
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(static_config)
|
16
|
+
super
|
17
|
+
@static_config = static_config
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Get the host this Solr instance is bound to
|
22
|
+
def host
|
23
|
+
'127.0.0.1'
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Get the port this Solr instance is running at
|
28
|
+
def port
|
29
|
+
@port ||= static_config.port
|
30
|
+
@port ||= random_open_port.to_s
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Get a (likely) URL to the solr instance
|
35
|
+
def url
|
36
|
+
"http://#{host}:#{port}/solr/"
|
37
|
+
end
|
38
|
+
|
39
|
+
def instance_dir
|
40
|
+
@instance_dir ||= static_config.instance_dir
|
41
|
+
@instance_dir ||= File.join(Dir.tmpdir, File.basename(download_url, ".zip"))
|
42
|
+
end
|
43
|
+
|
44
|
+
def managed?
|
45
|
+
File.exists?(instance_dir)
|
46
|
+
end
|
47
|
+
|
48
|
+
def download_url
|
49
|
+
@download_url ||= static_config.url
|
50
|
+
@download_url ||= default_download_url
|
51
|
+
end
|
52
|
+
|
53
|
+
def download_path
|
54
|
+
@download_path ||= static_config.download_path
|
55
|
+
@download_path ||= default_download_path
|
56
|
+
end
|
57
|
+
|
58
|
+
def version_file
|
59
|
+
static_config.version_file || File.join(instance_dir, "VERSION")
|
60
|
+
end
|
61
|
+
|
62
|
+
def md5url
|
63
|
+
"http://www.us.apache.org/dist/lucene/solr/#{static_config.version}/solr-#{static_config.version}.zip.md5"
|
64
|
+
end
|
65
|
+
|
66
|
+
def md5sum_path
|
67
|
+
File.join(download_dir, File.basename(md5url))
|
68
|
+
end
|
69
|
+
|
70
|
+
def solr_binary
|
71
|
+
File.join(instance_dir, "bin", "solr")
|
72
|
+
end
|
73
|
+
|
74
|
+
def tmp_save_dir
|
75
|
+
@tmp_save_dir ||= Dir.mktmpdir
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def default_download_path
|
81
|
+
File.join(download_dir, File.basename(download_url))
|
82
|
+
end
|
83
|
+
|
84
|
+
def download_dir
|
85
|
+
@download_dir ||= static_config.download_dir
|
86
|
+
@download_dir ||= Dir.tmpdir
|
87
|
+
FileUtils.mkdir_p @download_dir
|
88
|
+
@download_dir
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
def default_download_url
|
93
|
+
@default_url ||= begin
|
94
|
+
json = open(static_config.mirror_url).read
|
95
|
+
doc = JSON.parse(json)
|
96
|
+
doc['preferred'] + doc['path_info']
|
97
|
+
end
|
98
|
+
rescue SocketError
|
99
|
+
"http://www.us.apache.org/dist/lucene/solr/#{static_config.version}/solr-#{static_config.version}.zip"
|
100
|
+
end
|
101
|
+
|
102
|
+
def random_open_port
|
103
|
+
socket = Socket.new(:INET, :STREAM, 0)
|
104
|
+
begin
|
105
|
+
socket.bind(Addrinfo.tcp('127.0.0.1', 0))
|
106
|
+
socket.local_address.ip_port
|
107
|
+
ensure
|
108
|
+
socket.close
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
data/lib/solr_wrapper/version.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SolrWrapper::Configuration do
|
4
|
+
let(:config) { described_class.new options }
|
5
|
+
|
6
|
+
describe "#port" do
|
7
|
+
subject { config.port }
|
8
|
+
|
9
|
+
context "when port is set to nil" do
|
10
|
+
let(:options) { { port: nil } }
|
11
|
+
it { is_expected.to eq nil }
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when port is not set" do
|
15
|
+
let(:options) { {} }
|
16
|
+
it { is_expected.to eq '8983' }
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when a port is provided" do
|
20
|
+
let(:options) { { port: '8888' } }
|
21
|
+
it { is_expected.to eq '8888' }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -4,8 +4,9 @@ describe SolrWrapper::Instance do
|
|
4
4
|
let(:solr_instance) { SolrWrapper::Instance.new }
|
5
5
|
subject { solr_instance }
|
6
6
|
let(:client) { SimpleSolrClient::Client.new(subject.url) }
|
7
|
+
|
7
8
|
describe "#with_collection" do
|
8
|
-
it "
|
9
|
+
it "creates a new anonymous collection" do
|
9
10
|
subject.wrap do |solr|
|
10
11
|
solr.with_collection(dir: File.join(FIXTURES_DIR, "basic_configs")) do |collection_name|
|
11
12
|
core = client.core(collection_name)
|
@@ -17,6 +18,7 @@ describe SolrWrapper::Instance do
|
|
17
18
|
end
|
18
19
|
end
|
19
20
|
end
|
21
|
+
|
20
22
|
describe 'exec' do
|
21
23
|
let(:cmd) { 'start' }
|
22
24
|
let(:options) { { p: '4098', help: true } }
|
@@ -38,4 +40,29 @@ describe SolrWrapper::Instance do
|
|
38
40
|
end
|
39
41
|
end
|
40
42
|
end
|
43
|
+
|
44
|
+
describe "#host" do
|
45
|
+
subject { solr_instance.host }
|
46
|
+
it { is_expected.to eq '127.0.0.1' }
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "#port" do
|
50
|
+
subject { solr_instance.port }
|
51
|
+
it { is_expected.to eq '8983' }
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#url" do
|
55
|
+
subject { solr_instance.url }
|
56
|
+
it { is_expected.to eq 'http://127.0.0.1:8983/solr/' }
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#version" do
|
60
|
+
subject { solr_instance.version }
|
61
|
+
it { is_expected.to eq '5.4.1' }
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#md5" do
|
65
|
+
subject { solr_instance.md5 }
|
66
|
+
it { is_expected.to be_instance_of SolrWrapper::MD5 }
|
67
|
+
end
|
41
68
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solr_wrapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Beer
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rubyzip
|
@@ -129,8 +129,12 @@ files:
|
|
129
129
|
- coveralls.yml
|
130
130
|
- exe/solr_wrapper
|
131
131
|
- lib/solr_wrapper.rb
|
132
|
+
- lib/solr_wrapper/configuration.rb
|
133
|
+
- lib/solr_wrapper/downloader.rb
|
132
134
|
- lib/solr_wrapper/instance.rb
|
135
|
+
- lib/solr_wrapper/md5.rb
|
133
136
|
- lib/solr_wrapper/rake_task.rb
|
137
|
+
- lib/solr_wrapper/settings.rb
|
134
138
|
- lib/solr_wrapper/tasks/solr_wrapper.rake
|
135
139
|
- lib/solr_wrapper/version.rb
|
136
140
|
- solr_wrapper.gemspec
|
@@ -142,6 +146,7 @@ files:
|
|
142
146
|
- spec/fixtures/basic_configs/solrconfig.xml
|
143
147
|
- spec/fixtures/basic_configs/stopwords.txt
|
144
148
|
- spec/fixtures/basic_configs/synonyms.txt
|
149
|
+
- spec/lib/solr_wrapper/configuration_spec.rb
|
145
150
|
- spec/lib/solr_wrapper/instance_spec.rb
|
146
151
|
- spec/lib/solr_wrapper_spec.rb
|
147
152
|
- spec/spec_helper.rb
|
@@ -165,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
170
|
version: '0'
|
166
171
|
requirements: []
|
167
172
|
rubyforge_project:
|
168
|
-
rubygems_version: 2.
|
173
|
+
rubygems_version: 2.5.1
|
169
174
|
signing_key:
|
170
175
|
specification_version: 4
|
171
176
|
summary: Solr 5 service wrapper
|
@@ -178,6 +183,8 @@ test_files:
|
|
178
183
|
- spec/fixtures/basic_configs/solrconfig.xml
|
179
184
|
- spec/fixtures/basic_configs/stopwords.txt
|
180
185
|
- spec/fixtures/basic_configs/synonyms.txt
|
186
|
+
- spec/lib/solr_wrapper/configuration_spec.rb
|
181
187
|
- spec/lib/solr_wrapper/instance_spec.rb
|
182
188
|
- spec/lib/solr_wrapper_spec.rb
|
183
189
|
- spec/spec_helper.rb
|
190
|
+
has_rdoc:
|