Class: Chef::SolrQuery::SolrHTTPRequest

Inherits:
Object
  • Object
show all
Defined in:
lib/chef/solr_query/solr_http_request.rb

Constant Summary collapse

CLASS_FOR_METHOD =
{:GET => Net::HTTP::Get, :POST => Net::HTTP::Post}
UPDATE_URL =
'/solr/update'
TEXT_XML =
{"Content-Type" => "text/xml"}

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(method, url, headers = nil) {|@request| ... } ⇒ SolrHTTPRequest

Returns a new instance of SolrHTTPRequest.

Yields:

  • (@request)


77
78
79
80
81
# File 'lib/chef/solr_query/solr_http_request.rb', line 77

def initialize(method, url, headers=nil)
  args = headers ? [url, headers] : url
  @request = CLASS_FOR_METHOD[method].new(*args)
  yield @request if block_given?
end

Class Method Details

.escape(s) ⇒ Object



71
72
73
74
75
# File 'lib/chef/solr_query/solr_http_request.rb', line 71

def self.escape(s)
  s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) {
    '%'+$1.unpack('H2'*$1.size).join('%').upcase
  }.tr(' ', '+')
end

.http_clientObject



42
43
44
45
46
47
# File 'lib/chef/solr_query/solr_http_request.rb', line 42

def self.http_client
  @http_client ||= begin
    uri = URI.parse(solr_url)
    Net::HTTP.new(uri.host, uri.port)
  end
end

.select(params = {}) ⇒ Object



49
50
51
52
53
54
55
# File 'lib/chef/solr_query/solr_http_request.rb', line 49

def self.select(params={})
  url = "/solr/select?#{url_join(params)}"
  Chef::Log.debug("Sending #{url} to Solr")
  request = new(:GET, url)
  json_response = request.run("Search Query to Solr '#{solr_url}#{url}'")
  Chef::JSONCompat.from_json(json_response)
end

.solr_urlObject



38
39
40
# File 'lib/chef/solr_query/solr_http_request.rb', line 38

def self.solr_url
  @solr_url || Chef::Config[:solr_url]
end

.solr_url=(solr_url) ⇒ Object



33
34
35
36
# File 'lib/chef/solr_query/solr_http_request.rb', line 33

def self.solr_url=(solr_url)
  @solr_url = solr_url
  @http_client = nil
end

.update(doc) ⇒ Object



57
58
59
60
61
# File 'lib/chef/solr_query/solr_http_request.rb', line 57

def self.update(doc)
  Chef::Log.debug("POSTing document to SOLR:\n#{doc}")
  request = new(:POST, UPDATE_URL, TEXT_XML) { |req| req.body = doc.to_s }
  request.run("POST to Solr '#{UPDATE_URL}', data: #{doc}")
end

.url_join(params_hash = {}) ⇒ Object



63
64
65
66
67
68
69
# File 'lib/chef/solr_query/solr_http_request.rb', line 63

def self.url_join(params_hash={})
  params = params_hash.inject("") do |param_str, params|
    param_str << "#{params[0]}=#{escape(params[1])}&"
  end
  params.chop! # trailing &
  params
end

Instance Method Details

#http_clientObject



83
84
85
# File 'lib/chef/solr_query/solr_http_request.rb', line 83

def http_client
  self.class.http_client
end

#request_failed!(response, description = 'HTTP call') ⇒ Object



108
109
110
111
112
113
114
# File 'lib/chef/solr_query/solr_http_request.rb', line 108

def request_failed!(response, description='HTTP call')
  Chef::Log.fatal("#{description} failed (#{response.class} #{response.code} #{response.message})")
  response.error!
rescue Timeout::Error, Errno::EINVAL, EOFError, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError, Net::ProtocolError, Errno::ECONNREFUSED, Errno::ECONNRESET, Errno::ETIMEDOUT => e
  Chef::Log.debug(e.backtrace.join("\n"))
  raise Chef::Exceptions::SolrConnectionError, "#{e.class.name}: #{e.to_s}"
end

#run(description = "HTTP Request to Solr") ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/chef/solr_query/solr_http_request.rb', line 91

def run(description="HTTP Request to Solr")
  response = http_client.request(@request)
  request_failed!(response, description) unless response.kind_of?(Net::HTTPSuccess)
  response.body
rescue NoMethodError => e
  # http://redmine.ruby-lang.org/issues/show/2708
  # http://redmine.ruby-lang.org/issues/show/2758
  if e.to_s =~ /#{Regexp.escape(%q|undefined method 'closed?' for nil:NilClass|)}/
    Chef::Log.fatal("#{description} failed.  Chef::Exceptions::SolrConnectionError exception: Errno::ECONNREFUSED (net/http undefined method closed?) attempting to contact #{solr_url}")
    Chef::Log.debug("Rescued error in http connect, treating it as Errno::ECONNREFUSED to hide bug in net/http")
    Chef::Log.debug(e.backtrace.join("\n"))
    raise Chef::Exceptions::SolrConnectionError, "Errno::ECONNREFUSED: Connection refused attempting to contact #{solr_url}"
  else
    raise
  end
end

#solr_urlObject



87
88
89
# File 'lib/chef/solr_query/solr_http_request.rb', line 87

def solr_url
  self.class.solr_url
end