Class: RightScale::BalancedHttpClient
- Defined in:
- lib/right_agent/clients/balanced_http_client.rb
Overview
HTTP REST client for request-balanced access to RightScale servers Requests can be made using the EventMachine asynchronous HTTP interface in an efficient i/o non-blocking fashion using fibers or they can be made using the RestClient interface; either way they are synchronous to the client For the non-blocking i/o approach this class must be used from a spawned fiber rather than the root fiber This class is intended for use by instance agents and by infrastructure servers and therefore supports both session cookie and global session-based authentication
Defined Under Namespace
Classes: NotResponding
Constant Summary collapse
- RETRY_STATUS_CODES =
HTTP status codes for which a retry is warranted, which is limited to when server is not accessible for some reason (408, 502, 503) or server response indicates that the request could not be routed for some retryable reason (504)
[408, 502, 503, 504]
- DEFAULT_OPEN_TIMEOUT =
Default time for HTTP connection to open
2
- HEALTH_CHECK_TIMEOUT =
Time to wait for health check response
5
- DEFAULT_REQUEST_TIMEOUT =
Default time to wait for response from request
30
- CONNECTION_REUSE_TIMEOUT =
Maximum time between uses of an HTTP connection
5
- DEFAULT_HEALTH_CHECK_PATH =
Default health check path
"/health-check"
- FILTERED_PARAM_VALUE =
Text used for filtered parameter value
"<hidden>"
- CONTENT_FILTERED_PARAMS =
Parameters whose contents are also to have filtering applied
["payload"]
- PROXY_ENVIRONMENT_VARIABLES =
Environment variables to examine for proxy settings, in order
['HTTPS_PROXY', 'https_proxy', 'HTTP_PROXY', 'http_proxy', 'ALL_PROXY']
Class Method Summary collapse
-
.exception_text(exception) ⇒ String
Extract text of exception for logging For RestClient exceptions extract useful info from http_body attribute.
-
.format(params) ⇒ String
Format query parameters for inclusion in URI It can only handle parameters that can be converted to a string or arrays of same, not hashes or arrays/hashes that recursively contain arrays and/or hashes.
-
.response(code, body, headers, decode) ⇒ Object
Process HTTP response to produce result for client Extract result from location header for 201 response JSON-decode body of other 2xx responses except for 204 Raise exception if request failed.
Instance Method Summary collapse
-
#check_health(host = nil) ⇒ Object
Check health of server.
-
#close(reason) ⇒ TrueClass
Close all persistent connections.
- #delete(*args) ⇒ Object
- #get(*args) ⇒ Object
-
#initialize(urls, options = {}) ⇒ BalancedHttpClient
constructor
Create client for making HTTP REST requests.
- #poll(*args) ⇒ Object
- #post(*args) ⇒ Object
- #put(*args) ⇒ Object
-
#request(verb, path, params = {}, options = {}) ⇒ Object
Make HTTP request If polling, continue to poll until receive data, timeout, or hit error Encode request parameters and response using JSON Apply configured authorization scheme Log request/response with filtered parameters included for failure or debug mode.
Constructor Details
#initialize(urls, options = {}) ⇒ BalancedHttpClient
Create client for making HTTP REST requests
81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 81 def initialize(urls, = {}) @urls = split(urls) @api_version = [:api_version] @server_name = [:server_name] @filter_params = ([:filter_params] || []).map { |p| p.to_s } # Create appropriate underlying HTTP client @http_client = [:non_blocking] ? NonBlockingClient.new() : BlockingClient.new() # Initialize health check and its use in request balancer = {:policy => RightSupport::Net::LB::HealthCheck, :health_check => @http_client.health_check_proc } @balancer = RightSupport::Net::RequestBalancer.new(@urls, ) end |
Class Method Details
.exception_text(exception) ⇒ String
Extract text of exception for logging For RestClient exceptions extract useful info from http_body attribute
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 465 def self.exception_text(exception) case exception when String exception when HttpException, RestClient::Exception if exception.http_body.nil? || exception.http_body.empty? || exception.http_body =~ /^<html>| html / exception. else exception.inspect end when RightSupport::Net::NoResult, NotResponding "#{exception.class}: #{exception.}" when Exception backtrace = exception.backtrace ? " in\n" + exception.backtrace.join("\n") : "" "#{exception.class}: #{exception.}" + backtrace else "" end end |
.format(params) ⇒ String
Format query parameters for inclusion in URI It can only handle parameters that can be converted to a string or arrays of same, not hashes or arrays/hashes that recursively contain arrays and/or hashes
416 417 418 419 420 421 422 423 424 425 426 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 416 def self.format(params) p = [] params.each do |k, v| if v.is_a?(Array) v.each { |v2| p << "#{k.to_s}[]=#{CGI.escape(v2.to_s)}" } else p << "#{k.to_s}=#{CGI.escape(v.to_s)}" end end p.join("&") end |
.response(code, body, headers, decode) ⇒ Object
Process HTTP response to produce result for client Extract result from location header for 201 response JSON-decode body of other 2xx responses except for 204 Raise exception if request failed
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 441 def self.response(code, body, headers, decode) if (200..207).include?(code) if code == 201 result = headers[:location] elsif code == 204 || body.nil? || (body.respond_to?(:empty?) && body.empty?) result = nil elsif decode result = JSON.legacy_load(body) result = nil if result.respond_to?(:empty?) && result.empty? else result = body end else raise HttpExceptions.create(code, body, headers) end result end |
Instance Method Details
#check_health(host = nil) ⇒ Object
Check health of server
102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 102 def check_health(host = nil) begin @http_client.health_check_proc.call(host || @urls.first) rescue StandardError => e if e.respond_to?(:http_code) && RETRY_STATUS_CODES.include?(e.http_code) raise NotResponding.new("#{@server_name || host} not responding", e) else raise end end end |
#close(reason) ⇒ TrueClass
Close all persistent connections
195 196 197 198 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 195 def close(reason) @http_client.close(reason) if @http_client true end |
#delete(*args) ⇒ Object
130 131 132 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 130 def delete(*args) request(:delete, *args) end |
#get(*args) ⇒ Object
114 115 116 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 114 def get(*args) request(:get, *args) end |
#poll(*args) ⇒ Object
126 127 128 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 126 def poll(*args) request(:poll, *args) end |
#post(*args) ⇒ Object
118 119 120 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 118 def post(*args) request(:post, *args) end |
#put(*args) ⇒ Object
122 123 124 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 122 def put(*args) request(:put, *args) end |
#request(verb, path, params = {}, options = {}) ⇒ Object
Make HTTP request If polling, continue to poll until receive data, timeout, or hit error Encode request parameters and response using JSON Apply configured authorization scheme Log request/response with filtered parameters included for failure or debug mode
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 159 def request(verb, path, params = {}, = {}) started_at = Time.now filter = @filter_params + ([:filter_params] || []).map { |p| p.to_s } log_level = [:log_level] || :info request_uuid = [:request_uuid] || RightSupport::Data::UUID.generate , = @http_client.(verb, path, params, request_headers(request_uuid, ), ) Log.send(log_level, "Requesting #{verb.to_s.upcase} <#{request_uuid}> " + log_text(path, params, filter)) used = {} result, code, body, headers = if verb != :poll rest_request(verb, path, , , used) else poll_request(path, , , [:request_timeout], started_at, used) end log_success(result, code, body, headers, used[:host], path, request_uuid, started_at, log_level) result rescue RightSupport::Net::NoResult => e handle_no_result(e, used[:host]) do |e2| log_failure(used[:host], path, params, filter, request_uuid, started_at, e2) end rescue RestClient::Exception => e e2 = HttpExceptions.convert(e) log_failure(used[:host], path, params, filter, request_uuid, started_at, e2) raise e2 rescue StandardError => e log_failure(used[:host], path, params, filter, request_uuid, started_at, e) raise end |