rsolr 1.1.2 → 2.3.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 +5 -5
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -13
- data/CHANGES.txt +11 -0
- data/Gemfile +0 -4
- data/README.rdoc +26 -9
- data/Rakefile +16 -3
- data/lib/rsolr.rb +38 -12
- data/lib/rsolr/char.rb +3 -21
- data/lib/rsolr/client.rb +75 -75
- data/lib/rsolr/document.rb +59 -0
- data/lib/rsolr/field.rb +87 -0
- data/lib/rsolr/generator.rb +5 -0
- data/lib/rsolr/json.rb +60 -0
- data/lib/rsolr/response.rb +2 -2
- data/lib/rsolr/uri.rb +2 -52
- data/lib/rsolr/version.rb +1 -1
- data/lib/rsolr/xml.rb +38 -107
- data/rsolr.gemspec +7 -3
- data/spec/api/client_spec.rb +90 -92
- data/spec/api/document_spec.rb +48 -0
- data/spec/api/error_spec.rb +2 -1
- data/spec/api/json_spec.rb +198 -0
- data/spec/api/pagination_spec.rb +3 -9
- data/spec/api/rsolr_spec.rb +3 -11
- data/spec/api/uri_spec.rb +2 -93
- data/spec/api/xml_spec.rb +45 -11
- data/spec/integration/solr5_spec.rb +9 -1
- data/spec/spec_helper.rb +88 -2
- metadata +44 -15
- data/lib/rsolr/connection.rb +0 -74
- data/spec/api/char_spec.rb +0 -23
- data/spec/api/connection_spec.rb +0 -140
- data/tasks/rdoc.rake +0 -11
- data/tasks/rsolr.rake +0 -10
- data/tasks/spec.rake +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1ca1fd66200c07e8e4ffc42bc8d71e6735a7294b7c53485ed8b49f8cfc99ac68
|
4
|
+
data.tar.gz: 3a0b50c5807543beed8ddc533cb8d446909176d61d1022ef0d8bb26ee1250648
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a4bf74cc57d3523c4774f86c895b2e4a6bed229cc67499278fad4cf320575c68df1774d1fb0615108ca5ced0267798cea42a3e4c96723d6f2fb0f4294f38bcb
|
7
|
+
data.tar.gz: a51ec9142aba1761511058ed8614f600325e32551e6ae23b1638e2654b67e8a5ef3b8db1f6653171b67c492264079f368f95a0856ce1d7db5d1e5a06998b32d8
|
data/.gitignore
CHANGED
data/.rspec
ADDED
data/.travis.yml
CHANGED
@@ -1,21 +1,14 @@
|
|
1
|
-
addons:
|
2
|
-
apt:
|
3
|
-
packages:
|
4
|
-
- libgmp-dev
|
5
1
|
language: ruby
|
6
2
|
sudo: false
|
7
3
|
rvm:
|
8
|
-
- 2.
|
9
|
-
- 2.
|
10
|
-
-
|
11
|
-
|
12
|
-
notifications:
|
13
|
-
irc: "irc.freenode.org#blacklight"
|
14
|
-
email:
|
15
|
-
- blacklight-commits@googlegroups.com
|
4
|
+
- 2.6
|
5
|
+
- 2.5
|
6
|
+
- 2.4
|
7
|
+
- jruby
|
16
8
|
|
17
9
|
env:
|
18
10
|
global:
|
19
11
|
- JRUBY_OPTS="-J-Xms512m -J-Xmx1024m"
|
20
12
|
- NOKOGIRI_USE_SYSTEM_LIBRARIES=true
|
21
|
-
|
13
|
+
|
14
|
+
jdk: openjdk8
|
data/CHANGES.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
2.0.0.pre1
|
2
|
+
|
3
|
+
In this release, we've added many new features, including:
|
4
|
+
|
5
|
+
- a new JSON request generator (enabled by default, replacing the XML-based requests) (@mootprinter)
|
6
|
+
- using Faraday for added flexibility for HTTP configuration
|
7
|
+
- native support for nested child documents and atomic updates in RSolr::Document and RSolr::Client.add
|
8
|
+
- better support for custom field value converters (@solenko)
|
9
|
+
- removing code deprecated in RSolr 1.x (@vipulnsward, and others)
|
10
|
+
|
11
|
+
|
1
12
|
1.0.12
|
2
13
|
- Fix bug where specifying the wt property as a string, would add the supplied value to the default ('ruby') rather than overriding it.
|
3
14
|
|
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -11,7 +11,6 @@ The code docs http://www.rubydoc.info/gems/rsolr
|
|
11
11
|
gem install rsolr
|
12
12
|
|
13
13
|
== Example:
|
14
|
-
require 'rubygems'
|
15
14
|
require 'rsolr'
|
16
15
|
|
17
16
|
# Direct connection
|
@@ -19,7 +18,17 @@ The code docs http://www.rubydoc.info/gems/rsolr
|
|
19
18
|
|
20
19
|
# Connecting over a proxy server
|
21
20
|
solr = RSolr.connect :url => 'http://solrserver.com', :proxy=>'http://user:pass@proxy.example.com:8080'
|
21
|
+
|
22
|
+
# Using an alternate Faraday adapter
|
23
|
+
solr = RSolr.connect :url => 'http://solrserver.com', :adapter => :em_http
|
22
24
|
|
25
|
+
# Using a custom Faraday connection
|
26
|
+
conn = Faraday.new do |faraday|
|
27
|
+
faraday.response :logger # log requests to STDOUT
|
28
|
+
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
|
29
|
+
end
|
30
|
+
solr = RSolr.connect conn, :url => 'http://solrserver.com'
|
31
|
+
|
23
32
|
# send a request to /select
|
24
33
|
response = solr.get 'select', :params => {:q => '*:*'}
|
25
34
|
|
@@ -34,6 +43,14 @@ The +:request+ attribute contains the original request context. You can use this
|
|
34
43
|
|
35
44
|
The +:response+ attribute contains the original response. This object contains the +:status+, +:body+ and +:headers+ keys.
|
36
45
|
|
46
|
+
== Request formats
|
47
|
+
|
48
|
+
By default, RSolr uses the Solr JSON command format for all requests.
|
49
|
+
|
50
|
+
RSolr.connect :url => 'http://solrserver.com', update_format: :json # the default
|
51
|
+
# or
|
52
|
+
RSolr.connect :url => 'http://solrserver.com', update_format: :xml
|
53
|
+
|
37
54
|
== Timeouts
|
38
55
|
The read and connect timeout settings can be set when creating a new instance of RSolr:
|
39
56
|
solr = RSolr.connect(:read_timeout => 120, :open_timeout => 120)
|
@@ -44,6 +61,7 @@ A 503 is usually a temporary error which RSolr may retry if requested. You may s
|
|
44
61
|
Only requests which specify a Retry-After header will be retried, after waiting the indicated retry interval, otherwise RSolr will treat the request as a 500. You may specify a maximum Retry-After interval to wait with the +:retry_after_limit+ option (default: one second).
|
45
62
|
solr = RSolr.connect(:retry_503 => 1, :retry_after_limit => 1)
|
46
63
|
|
64
|
+
For additional control, consider using a custom Faraday connection (see above) using its `retry` middleware.
|
47
65
|
|
48
66
|
== Querying
|
49
67
|
Use the #get / #post method to send search requests to the /select handler:
|
@@ -119,9 +137,9 @@ Multiple documents via #add
|
|
119
137
|
The optional +:add_attributes+ hash can also be used to set Solr "add" document attributes:
|
120
138
|
solr.add documents, :add_attributes => {:commitWithin => 10}
|
121
139
|
|
122
|
-
Raw
|
123
|
-
solr.update :
|
124
|
-
solr.update :
|
140
|
+
Raw commands via #update
|
141
|
+
solr.update data: '<commit/>', headers: { 'Content-Type' => 'text/xml' }
|
142
|
+
solr.update data: { optimize: true }.to_json, headers: { 'Content-Type' => 'application/json' }
|
125
143
|
|
126
144
|
When adding, you can also supply "add" xml element attributes and/or a block for manipulating other "add" related elements (docs and fields) by calling the +xml+ method directly:
|
127
145
|
|
@@ -155,14 +173,13 @@ Delete by array of queries
|
|
155
173
|
== Response Formats
|
156
174
|
The default response format is Ruby. When the +:wt+ param is set to +:ruby+, the response is eval'd resulting in a Hash. You can get a raw response by setting the +:wt+ to +"ruby"+ - notice, the string -- not a symbol. RSolr will eval the Ruby string ONLY if the :wt value is :ruby. All other response formats are available as expected, +:wt=>'xml'+ etc..
|
157
175
|
|
158
|
-
===Evaluated Ruby
|
176
|
+
===Evaluated Ruby:
|
159
177
|
solr.get 'select', :params => {:wt => :ruby} # notice :ruby is a Symbol
|
160
|
-
===Raw Ruby
|
178
|
+
===Raw Ruby:
|
161
179
|
solr.get 'select', :params => {:wt => 'ruby'} # notice 'ruby' is a String
|
162
|
-
|
163
180
|
===XML:
|
164
181
|
solr.get 'select', :params => {:wt => :xml}
|
165
|
-
===JSON:
|
182
|
+
===JSON (default):
|
166
183
|
solr.get 'select', :params => {:wt => :json}
|
167
184
|
|
168
185
|
==Related Resources & Projects
|
@@ -170,7 +187,7 @@ The default response format is Ruby. When the +:wt+ param is set to +:ruby+, the
|
|
170
187
|
* {rsolr-ext}[http://github.com/mwmitchell/rsolr-ext] -- An extension kit for RSolr
|
171
188
|
* {rsolr-direct}[http://github.com/mwmitchell/rsolr-direct] -- JRuby direct connection for RSolr
|
172
189
|
* {rsolr-nokogiri}[http://github.com/mwmitchell/rsolr-nokogiri] -- Gives RSolr Nokogiri for XML generation.
|
173
|
-
* {SunSpot}[http://github.com/
|
190
|
+
* {SunSpot}[http://github.com/sunspot/sunspot] -- An awesome Solr DSL, built with RSolr
|
174
191
|
* {Blacklight}[http://blacklightopac.org] -- A "next generation" Library OPAC, built with RSolr
|
175
192
|
* {java_bin}[http://github.com/kennyj/java_bin] -- Provides javabin/binary parsing for RSolr
|
176
193
|
* {Solr}[http://lucene.apache.org/solr/] -- The Apache Solr project
|
data/Rakefile
CHANGED
@@ -1,6 +1,19 @@
|
|
1
|
-
require 'rake'
|
2
1
|
require 'bundler/gem_tasks'
|
3
2
|
|
4
|
-
|
3
|
+
task default: ['spec']
|
5
4
|
|
6
|
-
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
|
9
|
+
# Rdoc
|
10
|
+
require 'rdoc/task'
|
11
|
+
|
12
|
+
desc 'Generate documentation for the rsolr gem.'
|
13
|
+
RDoc::Task.new(:doc) do |rdoc|
|
14
|
+
rdoc.rdoc_dir = 'doc'
|
15
|
+
rdoc.title = 'RSolr'
|
16
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
17
|
+
rdoc.rdoc_files.include('README.rdoc')
|
18
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
19
|
+
end
|
data/lib/rsolr.rb
CHANGED
@@ -1,16 +1,27 @@
|
|
1
1
|
module RSolr
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
require 'rsolr/version'
|
3
|
+
|
4
|
+
autoload :Char, 'rsolr/char'
|
5
|
+
autoload :Client, 'rsolr/client'
|
6
|
+
autoload :Document, 'rsolr/document'
|
7
|
+
autoload :Error, 'rsolr/error'
|
8
|
+
autoload :Field, 'rsolr/field'
|
9
|
+
autoload :Generator, 'rsolr/generator'
|
10
|
+
autoload :HashWithResponse, 'rsolr/response'
|
11
|
+
autoload :JSON, 'rsolr/json'
|
12
|
+
autoload :Response, 'rsolr/response'
|
13
|
+
autoload :Uri, 'rsolr/uri'
|
14
|
+
autoload :Xml, 'rsolr/xml'
|
15
|
+
|
5
16
|
def self.connect *args
|
6
|
-
|
7
|
-
opts
|
8
|
-
|
17
|
+
opts = args.pop if args.last.is_a?(::Hash)
|
18
|
+
opts ||= {}
|
19
|
+
|
20
|
+
connection = args.first
|
21
|
+
|
22
|
+
Client.new connection, opts
|
9
23
|
end
|
10
|
-
|
11
|
-
# RSolr.escape, which is deprecated as of 2015-02
|
12
|
-
extend Char
|
13
|
-
|
24
|
+
|
14
25
|
# backslash escape characters that have special meaning to Solr query parser
|
15
26
|
# per http://lucene.apache.org/core/4_0_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#Escaping_Special_Characters
|
16
27
|
# + - & | ! ( ) { } [ ] ^ " ~ * ? : \ /
|
@@ -22,5 +33,20 @@ module RSolr
|
|
22
33
|
# so the result sent to Solr is ultimately a single backslash in front of the particular character
|
23
34
|
str.gsub(/([+\-&|!\(\)\{\}\[\]\^"~\*\?:\\\/])/, '\\\\\1')
|
24
35
|
end
|
25
|
-
|
26
|
-
|
36
|
+
|
37
|
+
module Array
|
38
|
+
def self.wrap(object)
|
39
|
+
if object.nil?
|
40
|
+
[nil]
|
41
|
+
elsif object.respond_to?(:to_ary)
|
42
|
+
object.to_ary || [object]
|
43
|
+
elsif object.is_a? Hash
|
44
|
+
[object]
|
45
|
+
elsif object.is_a? Enumerable
|
46
|
+
object
|
47
|
+
else
|
48
|
+
[object]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/rsolr/char.rb
CHANGED
@@ -1,24 +1,6 @@
|
|
1
|
-
#
|
2
|
-
# @deprecated remove this module when we remove the method (duh)
|
1
|
+
# :nodoc:
|
3
2
|
module RSolr::Char
|
4
|
-
|
5
|
-
|
6
|
-
# that isn't a word character
|
7
|
-
# @deprecated - this is incorrect Solr escaping
|
8
|
-
def escape value
|
9
|
-
warn "[DEPRECATION] `RSolr.escape` is deprecated (and incorrect). Use `RSolr.solr_escape` instead."
|
10
|
-
value.gsub(/(\W)/, '\\\\\1')
|
3
|
+
def self.included(*)
|
4
|
+
warn 'RSolr::Char is deprecated without replacement, and will be removed in RSolr 3.x'
|
11
5
|
end
|
12
|
-
|
13
|
-
# LUCENE_CHAR_RX = /([\+\-\!\(\)\[\]\^\"\~\*\?\:\\]+)/
|
14
|
-
# LUCENE_WORD_RX = /(OR|AND|NOT)/
|
15
|
-
#
|
16
|
-
# # More specific/lucene escape sequence
|
17
|
-
# def lucene_escape string
|
18
|
-
# delim = " "
|
19
|
-
# string.gsub(LUCENE_CHAR_RX, '\\\\\1').split(delim).map { |v|
|
20
|
-
# v.gsub(LUCENE_WORD_RX, '\\\\\1')
|
21
|
-
# }.join(delim)
|
22
|
-
# end
|
23
|
-
|
24
6
|
end
|
data/lib/rsolr/client.rb
CHANGED
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'faraday'
|
5
|
+
require 'uri'
|
5
6
|
|
6
7
|
class RSolr::Client
|
8
|
+
DEFAULT_URL = 'http://127.0.0.1:8983/solr/'
|
7
9
|
|
8
10
|
class << self
|
9
11
|
def default_wt
|
10
|
-
@default_wt
|
12
|
+
@default_wt ||= :json
|
11
13
|
end
|
12
14
|
|
13
15
|
def default_wt= value
|
@@ -15,33 +17,41 @@ class RSolr::Client
|
|
15
17
|
end
|
16
18
|
end
|
17
19
|
|
18
|
-
attr_reader :
|
20
|
+
attr_reader :uri, :proxy, :update_format, :options, :update_path
|
19
21
|
|
20
22
|
def initialize connection, options = {}
|
21
23
|
@proxy = @uri = nil
|
22
24
|
@connection = connection
|
23
25
|
unless false === options[:url]
|
24
|
-
|
25
|
-
url << "/" unless url[-1] == ?/
|
26
|
-
@uri = RSolr::Uri.create url
|
26
|
+
@uri = extract_url_from_options(options)
|
27
27
|
if options[:proxy]
|
28
28
|
proxy_url = options[:proxy].dup
|
29
29
|
proxy_url << "/" unless proxy_url.nil? or proxy_url[-1] == ?/
|
30
|
-
@proxy =
|
30
|
+
@proxy = ::URI.parse proxy_url if proxy_url
|
31
31
|
elsif options[:proxy] == false
|
32
32
|
@proxy = false # used to avoid setting the proxy from the environment.
|
33
33
|
end
|
34
34
|
end
|
35
|
+
@update_format = options.delete(:update_format) || RSolr::JSON::Generator
|
35
36
|
@update_path = options.fetch(:update_path, 'update')
|
36
37
|
@options = options
|
37
38
|
end
|
38
39
|
|
40
|
+
def extract_url_from_options(options)
|
41
|
+
url = options[:url] ? options[:url].dup : DEFAULT_URL
|
42
|
+
url << "/" unless url[-1] == ?/
|
43
|
+
uri = ::URI.parse(url)
|
44
|
+
# URI::HTTPS is a subclass of URI::HTTP, so this check accepts HTTP(S)
|
45
|
+
raise ArgumentError, "You must provide an HTTP(S) url." unless uri.kind_of?(URI::HTTP)
|
46
|
+
uri
|
47
|
+
end
|
48
|
+
|
39
49
|
# returns the request uri object.
|
40
50
|
def base_request_uri
|
41
51
|
base_uri.request_uri if base_uri
|
42
52
|
end
|
43
53
|
|
44
|
-
# returns the
|
54
|
+
# returns the URI uri object.
|
45
55
|
def base_uri
|
46
56
|
@uri
|
47
57
|
end
|
@@ -80,11 +90,10 @@ class RSolr::Client
|
|
80
90
|
#
|
81
91
|
def update opts = {}
|
82
92
|
opts[:headers] ||= {}
|
83
|
-
opts[:headers]['Content-Type'] ||=
|
93
|
+
opts[:headers]['Content-Type'] ||= builder.content_type
|
84
94
|
post opts.fetch(:path, update_path), opts
|
85
95
|
end
|
86
96
|
|
87
|
-
#
|
88
97
|
# +add+ creates xml "add" documents and sends the xml data to the +update+ method
|
89
98
|
#
|
90
99
|
# http://wiki.apache.org/solr/UpdateXmlMessages#add.2BAC8-update
|
@@ -101,7 +110,7 @@ class RSolr::Client
|
|
101
110
|
#
|
102
111
|
def add doc, opts = {}
|
103
112
|
add_attributes = opts.delete :add_attributes
|
104
|
-
update opts.merge(:data =>
|
113
|
+
update opts.merge(:data => builder.add(doc, add_attributes))
|
105
114
|
end
|
106
115
|
|
107
116
|
# send "commit" xml with opts
|
@@ -110,7 +119,7 @@ class RSolr::Client
|
|
110
119
|
#
|
111
120
|
def commit opts = {}
|
112
121
|
commit_attrs = opts.delete :commit_attributes
|
113
|
-
update opts.merge(:data =>
|
122
|
+
update opts.merge(:data => builder.commit( commit_attrs ))
|
114
123
|
end
|
115
124
|
|
116
125
|
# send "optimize" xml with opts.
|
@@ -119,7 +128,7 @@ class RSolr::Client
|
|
119
128
|
#
|
120
129
|
def optimize opts = {}
|
121
130
|
optimize_attributes = opts.delete :optimize_attributes
|
122
|
-
update opts.merge(:data =>
|
131
|
+
update opts.merge(:data => builder.optimize(optimize_attributes))
|
123
132
|
end
|
124
133
|
|
125
134
|
# send </rollback>
|
@@ -128,14 +137,14 @@ class RSolr::Client
|
|
128
137
|
#
|
129
138
|
# NOTE: solr 1.4 only
|
130
139
|
def rollback opts = {}
|
131
|
-
update opts.merge(:data =>
|
140
|
+
update opts.merge(:data => builder.rollback)
|
132
141
|
end
|
133
142
|
|
134
143
|
# Delete one or many documents by id
|
135
144
|
# solr.delete_by_id 10
|
136
145
|
# solr.delete_by_id([12, 41, 199])
|
137
146
|
def delete_by_id id, opts = {}
|
138
|
-
update opts.merge(:data =>
|
147
|
+
update opts.merge(:data => builder.delete_by_id(id))
|
139
148
|
end
|
140
149
|
|
141
150
|
# delete one or many documents by query.
|
@@ -145,12 +154,19 @@ class RSolr::Client
|
|
145
154
|
# solr.delete_by_query 'available:0'
|
146
155
|
# solr.delete_by_query ['quantity:0', 'manu:"FQ"']
|
147
156
|
def delete_by_query query, opts = {}
|
148
|
-
update opts.merge(:data =>
|
157
|
+
update opts.merge(:data => builder.delete_by_query(query))
|
149
158
|
end
|
150
159
|
|
151
|
-
|
152
|
-
|
153
|
-
|
160
|
+
def builder
|
161
|
+
@builder ||= if update_format.is_a? Class
|
162
|
+
update_format.new
|
163
|
+
elsif update_format == :json
|
164
|
+
RSolr::JSON::Generator.new
|
165
|
+
elsif update_format == :xml
|
166
|
+
RSolr::Xml::Generator.new
|
167
|
+
else
|
168
|
+
update_format
|
169
|
+
end
|
154
170
|
end
|
155
171
|
|
156
172
|
# +send_and_receive+ is the main request method responsible for sending requests to the +connection+ object.
|
@@ -177,48 +193,21 @@ class RSolr::Client
|
|
177
193
|
|
178
194
|
#
|
179
195
|
def execute request_context
|
196
|
+
raw_response = begin
|
197
|
+
response = connection.send(request_context[:method], request_context[:uri].to_s) do |req|
|
198
|
+
req.body = request_context[:data] if request_context[:method] == :post and request_context[:data]
|
199
|
+
req.headers.merge!(request_context[:headers]) if request_context[:headers]
|
200
|
+
end
|
180
201
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
raw_response = connection.execute self, request_context
|
202
|
+
{ status: response.status.to_i, headers: response.headers, body: response.body.force_encoding('utf-8') }
|
203
|
+
rescue Errno::ECONNREFUSED, defined?(Faraday::ConnectionFailed) ? Faraday::ConnectionFailed : Faraday::Error::ConnectionFailed
|
204
|
+
raise RSolr::Error::ConnectionRefused, request_context.inspect
|
205
|
+
rescue Faraday::Error => e
|
206
|
+
raise RSolr::Error::Http.new(request_context, e.response)
|
187
207
|
end
|
188
|
-
|
189
208
|
adapt_response(request_context, raw_response) unless raw_response.nil?
|
190
209
|
end
|
191
210
|
|
192
|
-
def retry_503?(request_context, response)
|
193
|
-
return false if response.nil?
|
194
|
-
status = response[:status] && response[:status].to_i
|
195
|
-
return false unless status == 503
|
196
|
-
retry_503 = request_context[:retry_503]
|
197
|
-
return false unless retry_503 && retry_503 > 0
|
198
|
-
retry_after_limit = request_context[:retry_after_limit] || 1
|
199
|
-
retry_after = retry_after(response)
|
200
|
-
return false unless retry_after && retry_after <= retry_after_limit
|
201
|
-
true
|
202
|
-
end
|
203
|
-
|
204
|
-
# Retry-After can be a relative number of seconds from now, or an RFC 1123 Date.
|
205
|
-
# If the latter, attempt to convert it to a relative time in seconds.
|
206
|
-
def retry_after(response)
|
207
|
-
retry_after = Array(response[:headers]['Retry-After'] || response[:headers]['retry-after']).flatten.first.to_s
|
208
|
-
if retry_after =~ /\A[0-9]+\Z/
|
209
|
-
retry_after = retry_after.to_i
|
210
|
-
else
|
211
|
-
begin
|
212
|
-
retry_after_date = DateTime.parse(retry_after)
|
213
|
-
retry_after = retry_after_date.to_time - Time.now
|
214
|
-
retry_after = nil if retry_after < 0
|
215
|
-
rescue ArgumentError
|
216
|
-
retry_after = retry_after.to_i
|
217
|
-
end
|
218
|
-
end
|
219
|
-
retry_after
|
220
|
-
end
|
221
|
-
|
222
211
|
# +build_request+ accepts a path and options hash,
|
223
212
|
# then prepares a normalized hash to return for sending
|
224
213
|
# to a solr connection driver.
|
@@ -250,10 +239,6 @@ class RSolr::Client
|
|
250
239
|
opts[:path] = path
|
251
240
|
opts[:uri] = base_uri.merge(path.to_s + (query ? "?#{query}" : "")) if base_uri
|
252
241
|
|
253
|
-
[:open_timeout, :read_timeout, :retry_503, :retry_after_limit].each do |k|
|
254
|
-
opts[k] = @options[k]
|
255
|
-
end
|
256
|
-
|
257
242
|
opts
|
258
243
|
end
|
259
244
|
|
@@ -285,7 +270,6 @@ class RSolr::Client
|
|
285
270
|
def adapt_response request, response
|
286
271
|
raise "The response does not have the correct keys => :body, :headers, :status" unless
|
287
272
|
%W(body headers status) == response.keys.map{|k|k.to_s}.sort
|
288
|
-
raise RSolr::Error::Http.new request, response unless [200,302].include? response[:status]
|
289
273
|
|
290
274
|
result = if respond_to? "evaluate_#{request[:params][:wt]}_response", true
|
291
275
|
send "evaluate_#{request[:params][:wt]}_response", request, response
|
@@ -299,6 +283,26 @@ class RSolr::Client
|
|
299
283
|
|
300
284
|
result
|
301
285
|
end
|
286
|
+
|
287
|
+
def connection
|
288
|
+
@connection ||= begin
|
289
|
+
conn_opts = { request: {} }
|
290
|
+
conn_opts[:url] = uri.to_s
|
291
|
+
conn_opts[:proxy] = proxy if proxy
|
292
|
+
conn_opts[:request][:open_timeout] = options[:open_timeout] if options[:open_timeout]
|
293
|
+
conn_opts[:request][:timeout] = options[:read_timeout] if options[:read_timeout]
|
294
|
+
conn_opts[:request][:params_encoder] = Faraday::FlatParamsEncoder
|
295
|
+
|
296
|
+
Faraday.new(conn_opts) do |conn|
|
297
|
+
conn.basic_auth(uri.user, uri.password) if uri.user && uri.password
|
298
|
+
conn.response :raise_error
|
299
|
+
conn.request :retry, max: options[:retry_after_limit], interval: 0.05,
|
300
|
+
interval_randomness: 0.5, backoff_factor: 2,
|
301
|
+
exceptions: ['Faraday::Error', 'Timeout::Error'] if options[:retry_503]
|
302
|
+
conn.adapter options[:adapter] || Faraday.default_adapter
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
302
306
|
|
303
307
|
protected
|
304
308
|
|
@@ -319,21 +323,17 @@ class RSolr::Client
|
|
319
323
|
# instead, giving full access to the
|
320
324
|
# request/response objects.
|
321
325
|
def evaluate_ruby_response request, response
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
raise RSolr::Error::InvalidRubyResponse.new request, response
|
326
|
-
end
|
326
|
+
Kernel.eval response[:body].to_s
|
327
|
+
rescue SyntaxError
|
328
|
+
raise RSolr::Error::InvalidRubyResponse.new request, response
|
327
329
|
end
|
328
330
|
|
329
331
|
def evaluate_json_response request, response
|
330
|
-
return response[:body]
|
332
|
+
return if response[:body].nil? || response[:body].empty?
|
331
333
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
raise RSolr::Error::InvalidJsonResponse.new request, response
|
336
|
-
end
|
334
|
+
JSON.parse response[:body].to_s
|
335
|
+
rescue JSON::ParserError
|
336
|
+
raise RSolr::Error::InvalidJsonResponse.new request, response
|
337
337
|
end
|
338
338
|
|
339
339
|
def default_wt
|