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}
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)


91
92
93
94
95
# File 'lib/chef/solr_query/solr_http_request.rb', line 91

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



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

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
48
49
# File 'lib/chef/solr_query/solr_http_request.rb', line 42

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

.select(params = {}) ⇒ Object



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

def self.select(params={})
  url = "#{url_prefix}/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



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

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

.update(doc) ⇒ Object



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

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

.url_join(params_hash = {}) ⇒ Object



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

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

.url_prefixObject



51
52
53
54
55
56
57
58
59
60
# File 'lib/chef/solr_query/solr_http_request.rb', line 51

def self.url_prefix
  @url_prefix ||= begin
    uri = URI.parse(solr_url)
    if uri.path == ""
      "/solr"
    else
      uri.path.gsub(%r{/$}, '')
    end
  end
end

Instance Method Details

#http_clientObject



97
98
99
# File 'lib/chef/solr_query/solr_http_request.rb', line 97

def http_client
  self.class.http_client
end

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



122
123
124
125
126
127
128
# File 'lib/chef/solr_query/solr_http_request.rb', line 122

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



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/chef/solr_query/solr_http_request.rb', line 105

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



101
102
103
# File 'lib/chef/solr_query/solr_http_request.rb', line 101

def solr_url
  self.class.solr_url
end