solr_wrapper 0.0.7 → 1.0.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: ad8d234af6fa4899c3f7b644e6248777e4bf06d6
4
- data.tar.gz: ac6a83319475f98f193647760afd044a8c35a33a
3
+ metadata.gz: '092270d968ea024833bc6185caf854c05c8e623e'
4
+ data.tar.gz: 83d3dd71ca0de7c18ee9090a06ff051b174dbf4a
5
5
  SHA512:
6
- metadata.gz: 5bc27e00fceb2043c300f75e814ba38461b279ebe7f62d522408ea8020bea031bbcc915f8a9aab921f648e269dd48573ccdafc8121a365402893ba78c14dafa6
7
- data.tar.gz: b2e501bf7e1e92d57d3c11c80db9e29b4910a51057cf3b1913a6dfb8c233ae95e2f02fc3b26cabe70b7013abc5e3f8b3fa7412bc744d353a62ee65220133712a
6
+ metadata.gz: c4da5d83939b7d10b089d4453b79fb778aa499809cbd114d634fe8e7e790a21896c73320055fa43d3682559768fcb5729f2062bde7ab1ee9beeb92e967c1cf50
7
+ data.tar.gz: c7373e52dcd5520e541947655b1e95c6fcd53e9ccf7b356d7bf2efa37f60bb36555508451bc46546c92b3b1899859040453072802e54ba9fd59238fed106553d
data/.hound.yml ADDED
@@ -0,0 +1,2 @@
1
+ ruby:
2
+ config_file: .rubocop.yml
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,16 @@
1
+ inherit_from:
2
+ - .rubocop_todo.yml
3
+
4
+ AllCops:
5
+ Exclude:
6
+ - "*.gemspec"
7
+
8
+ Metrics/LineLength:
9
+ Enabled: false
10
+
11
+ # Offense count: 61
12
+ Metrics/AbcSize:
13
+ Max: 59
14
+
15
+ Style/RescueModifier:
16
+ Enabled: false
data/.rubocop_todo.yml ADDED
File without changes
data/.travis.yml CHANGED
@@ -1,8 +1,13 @@
1
1
  language: ruby
2
2
  sudo: false
3
3
  rvm:
4
- - 2.2.0
5
- - jruby
6
- cache:
7
- directories:
8
- - /tmp/solr-5.0.0
4
+ - 2.4.1
5
+ - 2.3.4
6
+ - jruby-9.1.8.0
7
+
8
+ jdk:
9
+ - oraclejdk8
10
+
11
+ env:
12
+ global:
13
+ JRUBY_OPTS=-J-Xmx2g
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in solr_wrapper.gemspec
4
- gemspec
4
+ gemspec
data/README.md CHANGED
@@ -11,18 +11,93 @@ end
11
11
  Or with Solr and a solr collection:
12
12
 
13
13
  ```ruby
14
- subject.wrap do |solr|
15
- solr.with_collection(dir: File.join(FIXTURES_DIR, "basic_configs")) do |collection_name|
16
- end
14
+ SolrWrapper.wrap do |solr|
15
+ solr.with_collection(dir: File.join(FIXTURES_DIR, "basic_configs")) do |collection_name|
17
16
  end
17
+ end
18
18
  ```
19
19
 
20
20
  ## Basic Options
21
21
 
22
22
  ```ruby
23
- SolrWrapper.wrap port: 8983, verbose: true, managed: true
23
+ SolrWrapper.wrap port: 8983,
24
+ verbose: true,
25
+ managed: true,
26
+ instance_dir: '/opt/solr'
27
+ ```
28
+
29
+ ### Valid ruby and YAML options
30
+
31
+ |Option | |
32
+ |---------------|-----------------------------------------|
33
+ | instance_dir | Directory to store the solr index files |
34
+ | url | URL of the Zip file to download |
35
+ | version | Solr version to download and install |
36
+ | port | port to run Solr on |
37
+ | version_file | Local path to store the currently installed version |
38
+ | download_dir | Local path for storing the downloaded Solr zip file |
39
+ | solr_zip_path | Local path to the Solr zip file |
40
+ | md5sum | Path/URL to MD5 checksum |
41
+ | solr_xml | Path to Solr configuration |
42
+ | verbose | (Boolean) |
43
+ | managed | (Boolean) |
44
+ | ignore_md5sum | (Boolean) |
45
+ | solr_options | (Hash) |
46
+ | env | (Hash) |
47
+ | persist | (Boolean) Preserves the data in you collection between startups |
48
+
49
+ ```ruby
50
+ solr.with_collection(name: 'collection_name', dir: 'path_to_solr_configs')
51
+ ```
52
+
53
+ ## From the command line
54
+
55
+ ```console
56
+ $ solr_wrapper -p 8983
57
+ ```
58
+ To see a list of valid options when using solr_wrapper to launch a Solr instance from the command line:
59
+ ```
60
+ $ solr_wrapper -h
61
+ ```
62
+
63
+ ### Configuration file
64
+ SolrWrapper can read configuration options from a YAML configuration file.
65
+ By default, it looks for configuration files at `.solr_wrapper` and `~/.solr_wrapper`.
66
+
67
+ You can also specify a configuration file when launching from the command line as follows:
68
+ ```
69
+ $ solr_wrapper -config <path_to_config_file>
70
+ ```
71
+
72
+ ### Cleaning your repository from the command line
73
+
74
+ By defualt SorlWrapper will clean out your data when it shuts down.
75
+ If you utilize the preserve option your data will remain between runs.
76
+
77
+ To clean out data that is being preserved explicitly run:
78
+ ```
79
+ $ solr_wrapper <configuration options> clean
80
+ ```
81
+ ***Note*** You must use the same configuration options on the clean command as you do on the run command to clean the correct instance.
82
+
83
+ ## Rake tasks
84
+
85
+ SolrWrapper provides rake tasks for installing, starting and stopping solr. To include the tasks in your Rake environment, add this to your Rakefile
86
+
87
+ ```ruby
88
+ require 'solr_wrapper/rake_task'
24
89
  ```
25
90
 
91
+ You can configure the tasks by setting `SolrWrapper.default_instance_options`. For example:
92
+
26
93
  ```ruby
27
- solr.with_collection(name: 'collection_name', dir: 'path_to_solr_confiigs')
28
- ```
94
+ SolrWrapper.default_instance_options = {
95
+ verbose: true,
96
+ cloud: true,
97
+ port: '8888',
98
+ version: '5.3.1',
99
+ instance_dir: 'solr',
100
+ download_dir: 'tmp'
101
+ }
102
+ require 'solr_wrapper/rake_task'
103
+ ```
data/Rakefile CHANGED
@@ -1,8 +1,7 @@
1
1
  require "bundler/gem_tasks"
2
2
 
3
-
4
3
  require 'rspec/core/rake_task'
5
4
 
6
5
  RSpec::Core::RakeTask.new(:spec)
7
6
 
8
- task default: ['spec']
7
+ task default: ['spec']
data/exe/solr_wrapper ADDED
@@ -0,0 +1,125 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'solr_wrapper'
4
+ require 'optparse'
5
+
6
+ options = {}
7
+ collection_options = {}
8
+ subtext = <<HELP
9
+ Commonly used command are:
10
+ clean : cleans all data from solr and configures a clean instance based on configuration options
11
+ dir : prints the solr instance dir
12
+ See 'solr_wrapper COMMAND --help' for more information on a specific command.
13
+ HELP
14
+
15
+ args = OptionParser.new do |opts|
16
+ opts.banner = "Usage: solr_wrapper [options] subcommand"
17
+
18
+ opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
19
+ options[:verbose] = v
20
+ end
21
+
22
+ opts.on("--config FILE", "Load configuration from a file") do |v|
23
+ options[:config] = v
24
+ end
25
+
26
+ opts.on("--version VERSION", "Specify a Solr version to download (default: #{SolrWrapper.default_solr_version})") do |v|
27
+ options[:version] = v
28
+ end
29
+
30
+ opts.on("-pPORT", "--port PORT", "Specify the port Solr should run at (default: #{SolrWrapper.default_solr_port})") do |p|
31
+ if p == 'random'
32
+ options[:port] = nil
33
+ else
34
+ options[:port] = p
35
+ end
36
+ end
37
+
38
+ opts.on("-c", "--cloud", "Run solr in cloud mode") do |c|
39
+ options[:cloud] = c
40
+ end
41
+
42
+ opts.on("--solr_zip_path PATH", "Download/use solr at the given path") do |d|
43
+ options[:solr_zip_path] = d
44
+ end
45
+
46
+ opts.on("-iDIR", "--instance_directory DIR", "Install/use solr at the given directory") do |d|
47
+ options[:instance_dir] = d
48
+ end
49
+
50
+ opts.on("-lDIR", "--lib_directory DIR", "Grab extra libs from this directory") do |d|
51
+ options[:extra_lib_dir] = d
52
+ end
53
+
54
+ opts.on("-nNAME", "--collection_name NAME", "Create a default solr collection with the given name") do |c|
55
+ collection_options[:name] = c
56
+ end
57
+
58
+ opts.on("-dDIR", "--collection_config DIR", "Create a default solr collection with the files from the given directory") do |d|
59
+ collection_options[:dir] = d
60
+ end
61
+
62
+ opts.on("--[no-]persist", "Persist the solr connection data") do |d|
63
+ collection_options[:persist] = d
64
+ end
65
+
66
+ opts.on("--no-checksum", "Skip running checksum validation on the downloaded file") do |d|
67
+ options[:ignore_md5sum] = true
68
+ end
69
+
70
+ opts.separator ""
71
+ opts.separator subtext
72
+ end
73
+
74
+
75
+ subcommands = {
76
+ 'clean' => OptionParser.new do |opts|
77
+ opts.banner = "Usage: clean"
78
+ end,
79
+ 'dir' => OptionParser.new do |opts|
80
+ opts.banner = "Usage: dir"
81
+ end,
82
+ }
83
+
84
+
85
+ begin
86
+ args.order!
87
+ command = ARGV.shift
88
+ if command
89
+ raise "Bad subcommand: #{command}" unless subcommands[command]
90
+ subcommands[command].order!
91
+ end
92
+ args.parse!
93
+ rescue => error
94
+ $stderr.puts "ERROR: #{error}\n"
95
+ $stderr.puts args.help
96
+ exit 1
97
+ end
98
+
99
+ instance = SolrWrapper.instance(options)
100
+
101
+ case command
102
+ when 'clean'
103
+ if instance.started?
104
+ $stderr.puts "Please stop solr before cleaning"
105
+ exit 1
106
+ end
107
+ $stderr.puts "cleaning #{instance.instance_dir}..."
108
+ instance.remove_instance_dir!
109
+ when 'dir'
110
+ puts instance.instance_dir
111
+ else
112
+ $stderr.print "Starting Solr #{instance.version} on port #{instance.port} ... "
113
+ instance.wrap do |conn|
114
+ conn.with_collection(collection_options) do
115
+ $stderr.puts "http://#{instance.host}:#{instance.port}/solr/"
116
+ begin
117
+ conn.wait
118
+ rescue Interrupt
119
+ Signal.trap("SIGTERM") {"IGNORE"}
120
+ Signal.trap("SIGINT") {"IGNORE"}
121
+ $stderr.puts "Solr is shutting down."
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,36 @@
1
+ require 'faraday'
2
+ require 'json'
3
+
4
+ module SolrWrapper
5
+ # Solr REST API client to get status information
6
+ class Client
7
+ attr_reader :url
8
+
9
+ def initialize(url)
10
+ @url = url
11
+ end
12
+
13
+ # Check if a core or collection exists
14
+ def exists?(core_or_collection_name)
15
+ collection?(core_or_collection_name) || core?(core_or_collection_name)
16
+ end
17
+
18
+ private
19
+
20
+ def collection?(name)
21
+ response = conn.get('admin/collections?action=LIST&wt=json')
22
+ data = JSON.parse(response.body)
23
+ return if data['error'] && data['error']['msg'] == 'Solr instance is not running in SolrCloud mode.'
24
+ data['collections'].include? name
25
+ end
26
+
27
+ def core?(name)
28
+ response = conn.get('admin/cores?action=STATUS&wt=json&core=' + name)
29
+ !JSON.parse(response.body)['status'][name].empty?
30
+ end
31
+
32
+ def conn
33
+ @conn ||= Faraday.new(url: url)
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,163 @@
1
+ require 'faraday'
2
+
3
+ module SolrWrapper
4
+ class Configuration
5
+ attr_reader :options
6
+
7
+ def initialize(options = {})
8
+ @config = options[:config]
9
+ @verbose = options[:verbose]
10
+
11
+ @options = load_configs(Array(options[:config])).merge(options)
12
+ end
13
+
14
+ def solr_xml
15
+ options[:solr_xml]
16
+ end
17
+
18
+ def extra_lib_dir
19
+ options[:extra_lib_dir]
20
+ end
21
+
22
+ def validate
23
+ options[:validate]
24
+ end
25
+
26
+ def ignore_md5sum
27
+ options[:ignore_md5sum]
28
+ end
29
+
30
+ def md5sum
31
+ options[:md5sum]
32
+ end
33
+
34
+ def url
35
+ options[:url]
36
+ end
37
+
38
+ def port
39
+ # Check if the port option has been explicitly set to nil.
40
+ # this means to start solr wrapper on a random open port
41
+ return nil if options.key?(:port) && !options[:port]
42
+ options.fetch(:port) { SolrWrapper.default_instance_options[:port] }.to_s
43
+ end
44
+
45
+ def zookeeper_host
46
+ options[:zookeeper_host]
47
+ end
48
+
49
+ def zookeeper_port
50
+ options[:zookeeper_port]
51
+ end
52
+
53
+ def solr_zip_path
54
+ options[:solr_zip_path]
55
+ end
56
+
57
+ def download_dir
58
+ options[:download_dir] || default_download_dir
59
+ end
60
+
61
+ def default_download_dir
62
+ if defined?(Rails) && Rails.respond_to?(:root) && Rails.root
63
+ File.join(Rails.root, 'tmp')
64
+ else
65
+ Dir.tmpdir
66
+ end
67
+ end
68
+
69
+ def solr_options
70
+ options.fetch(:solr_options, {})
71
+ end
72
+
73
+ def env
74
+ options.fetch(:env, {})
75
+ end
76
+
77
+ def instance_dir
78
+ options[:instance_dir]
79
+ end
80
+
81
+ def version
82
+ @version ||= begin
83
+ config_version = options.fetch(:version, SolrWrapper.default_instance_options[:version])
84
+ if config_version == 'latest'
85
+ fetch_latest_version
86
+ else
87
+ config_version
88
+ end
89
+ end
90
+ end
91
+
92
+ def mirror_url
93
+ "http://www.apache.org/dyn/closer.lua/lucene/solr/#{version}/solr-#{version}.zip?asjson=true"
94
+ end
95
+
96
+ def cloud
97
+ options[:cloud]
98
+ end
99
+
100
+ def verbose?
101
+ @verbose || (options && !!options.fetch(:verbose, false))
102
+ end
103
+
104
+ def version_file
105
+ options[:version_file]
106
+ end
107
+
108
+ def collection_options
109
+ hash = options.fetch(:collection, {})
110
+ Configuration.slice(convert_keys(hash), :name, :dir, :persist)
111
+ end
112
+
113
+ def configsets
114
+ configsets = options[:configsets] || []
115
+ configsets.map { |x| convert_keys(x) }
116
+ end
117
+
118
+ def poll_interval
119
+ options.fetch(:poll_interval, 1)
120
+ end
121
+
122
+ private
123
+
124
+ def self.slice(source, *keys)
125
+ keys.each_with_object({}) { |k, hash| hash[k] = source[k] if source.has_key?(k) }
126
+ end
127
+
128
+ def load_configs(config_files)
129
+ config = {}
130
+
131
+ (default_configuration_paths + config_files.compact).each do |p|
132
+ path = File.expand_path(p)
133
+ next unless File.exist? path
134
+ config.merge!(read_config(path))
135
+ end
136
+
137
+ config
138
+ end
139
+
140
+ def read_config(config_file)
141
+ $stdout.puts "Loading configuration from #{config_file}" if verbose?
142
+ config = YAML.load(ERB.new(IO.read(config_file)).result(binding))
143
+ unless config
144
+ $stderr.puts "Unable to parse config #{config_file}" if verbose?
145
+ return {}
146
+ end
147
+ convert_keys(config)
148
+ end
149
+
150
+ def convert_keys(hash)
151
+ hash.each_with_object({}) { |(k, v), h| h[k.to_sym] = v }
152
+ end
153
+
154
+ def default_configuration_paths
155
+ ['~/.solr_wrapper.yml', '~/.solr_wrapper', '.solr_wrapper.yml', '.solr_wrapper']
156
+ end
157
+
158
+ def fetch_latest_version
159
+ response = Faraday.get('https://svn.apache.org/repos/asf/lucene/cms/trunk/content/latestversion.mdtext')
160
+ response.body.strip
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,25 @@
1
+ require 'ruby-progressbar'
2
+
3
+ module SolrWrapper
4
+ class Downloader
5
+ def self.fetch_with_progressbar(url, output)
6
+ pbar = SafeProgressBar.new(title: File.basename(url), total: nil, format: '%t: |%B| %p%% (%e )')
7
+ open(url, content_length_proc: ->(bytes) { pbar.total = bytes }, progress_proc: ->(bytes) { pbar.progress = bytes }) do |io|
8
+ IO.copy_stream(io, output)
9
+ end
10
+ rescue OpenURI::HTTPError => e
11
+ raise SolrWrapperError, "Unable to download solr from #{url}\n#{e.message}: #{e.io.read}"
12
+ end
13
+
14
+ class SafeProgressBar < ProgressBar::Base
15
+ def progress=(new_progress)
16
+ self.total = new_progress if total <= new_progress
17
+ super
18
+ end
19
+
20
+ def total=(new_total)
21
+ super if new_total && new_total > 0
22
+ end
23
+ end
24
+ end
25
+ end