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>"
- 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
77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 77 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
454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 454 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
405 406 407 408 409 410 411 412 413 414 415 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 405 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
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 430 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.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
98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 98 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
191 192 193 194 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 191 def close(reason) @http_client.close(reason) if @http_client true end |
#delete(*args) ⇒ Object
126 127 128 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 126 def delete(*args) request(:delete, *args) end |
#get(*args) ⇒ Object
110 111 112 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 110 def get(*args) request(:get, *args) end |
#poll(*args) ⇒ Object
122 123 124 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 122 def poll(*args) request(:poll, *args) end |
#post(*args) ⇒ Object
114 115 116 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 114 def post(*args) request(:post, *args) end |
#put(*args) ⇒ Object
118 119 120 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 118 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
155 156 157 158 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 |
# File 'lib/right_agent/clients/balanced_http_client.rb', line 155 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 |