Module: Rightscale::RightSlicehostInterface
- Included in:
- Slicehost
- Defined in:
- lib/slicehost_base.rb
Constant Summary collapse
- DEFAULT_SLICEHOST_URL =
'https://api.slicehost.com'
- SLICEHOST_PROBLEMS =
Text, if found in an error message returned by Slicehost, indicates that this may be a transient error. Transient errors are automatically retried with exponential back-off. TODO: gather Slicehost errors here
[ ]
- @@slicehost_problems =
SLICEHOST_PROBLEMS
- @@caching =
false
- @@bench =
SlicehostBenchmarkingBlock.new
Instance Attribute Summary collapse
-
#cache ⇒ Object
readonly
Cache.
-
#connection ⇒ Object
readonly
RightHttpConnection instance.
-
#last_errors ⇒ Object
Last Slicehost errors list (used by SlicehostErrorHandler).
-
#last_request ⇒ Object
readonly
Last HTTP request object.
-
#last_response ⇒ Object
readonly
Last HTTP response object.
-
#logger ⇒ Object
Logger object.
-
#params ⇒ Object
Initial params hash.
-
#slicehost_pasword ⇒ Object
readonly
Current Slicehost API key.
Class Method Summary collapse
- .bench_parser ⇒ Object
- .bench_slicehost ⇒ Object
- .caching ⇒ Object
- .caching=(caching) ⇒ Object
-
.slicehost_problems ⇒ Object
Returns a list of Slicehost responses which are known to be transient problems.
Instance Method Summary collapse
-
#cache_hits?(function, response, do_raise = :raise) ⇒ Boolean
Check if the slicehost function response hits the cache or not.
-
#caching? ⇒ Boolean
Returns
true
if the describe_xxx responses are being cached. -
#cgi_escape_params(params) ⇒ Object
:nodoc:.
-
#generate_request(method, path, params = {}) ⇒ Object
Generate a handy request hash.
-
#init(slicehost_pasword, params = {}) ⇒ Object
Params: :slicehost_url :logger :multi_thread.
-
#multi_thread ⇒ Object
Return
true
if this instance works in multi_thread mode andfalse
otherwise. -
#on_exception(options = {:raise=>true, :log=>true}) ⇒ Object
:nodoc:.
-
#request_cache_or_info(method, request_hash, parser_class, use_cache = true) ⇒ Object
Perform a request.
-
#request_info(request, parser) ⇒ Object
Perform a request.
-
#update_cache(function, hash) ⇒ Object
:nodoc:.
Instance Attribute Details
#cache ⇒ Object (readonly)
Cache
85 86 87 |
# File 'lib/slicehost_base.rb', line 85 def cache @cache end |
#connection ⇒ Object (readonly)
RightHttpConnection instance
83 84 85 |
# File 'lib/slicehost_base.rb', line 83 def connection @connection end |
#last_errors ⇒ Object
Last Slicehost errors list (used by SlicehostErrorHandler)
77 78 79 |
# File 'lib/slicehost_base.rb', line 77 def last_errors @last_errors end |
#last_request ⇒ Object (readonly)
Last HTTP request object
73 74 75 |
# File 'lib/slicehost_base.rb', line 73 def last_request @last_request end |
#last_response ⇒ Object (readonly)
Last HTTP response object
75 76 77 |
# File 'lib/slicehost_base.rb', line 75 def last_response @last_response end |
#logger ⇒ Object
Logger object
79 80 81 |
# File 'lib/slicehost_base.rb', line 79 def logger @logger end |
#params ⇒ Object
Initial params hash
81 82 83 |
# File 'lib/slicehost_base.rb', line 81 def params @params end |
#slicehost_pasword ⇒ Object (readonly)
Current Slicehost API key
71 72 73 |
# File 'lib/slicehost_base.rb', line 71 def slicehost_pasword @slicehost_pasword end |
Class Method Details
.bench_parser ⇒ Object
63 64 65 |
# File 'lib/slicehost_base.rb', line 63 def self.bench_parser @@bench.parser end |
.bench_slicehost ⇒ Object
66 67 68 |
# File 'lib/slicehost_base.rb', line 66 def self.bench_slicehost @@bench.service end |
.caching ⇒ Object
55 56 57 |
# File 'lib/slicehost_base.rb', line 55 def self.caching @@caching end |
.caching=(caching) ⇒ Object
58 59 60 |
# File 'lib/slicehost_base.rb', line 58 def self.caching=(caching) @@caching = caching end |
.slicehost_problems ⇒ Object
Returns a list of Slicehost responses which are known to be transient problems. We have to re-request if we get any of them, because the problem will probably disappear. By default this method returns the same value as the SLICEHOST_PROBLEMS const.
50 51 52 |
# File 'lib/slicehost_base.rb', line 50 def self.slicehost_problems @@slicehost_problems end |
Instance Method Details
#cache_hits?(function, response, do_raise = :raise) ⇒ Boolean
Check if the slicehost function response hits the cache or not. If the cache hits:
-
raises an
SlicehostNoChange
exception ifdo_raise
==:raise
. -
returnes parsed response from the cache if it exists or
true
otherwise.
If the cache miss or the caching is off then returns false
.
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
# File 'lib/slicehost_base.rb', line 228 def cache_hits?(function, response, do_raise=:raise) # :nodoc: result = false if caching? function = function.to_sym response_md5 = MD5.md5(response).to_s # well, the response is new, reset cache data unless @cache[function] && @cache[function][:response_md5] == response_md5 update_cache(function, {:response_md5 => response_md5, :timestamp => Time.now, :hits => 0, :parsed => nil}) else # aha, cache hits, update the data and throw an exception if needed @cache[function][:hits] += 1 if do_raise == :raise raise(SlicehostNoChange, "Cache hit: #{function} response has not changed since "+ "#{@cache[function][:timestamp].strftime('%Y-%m-%d %H:%M:%S')}, "+ "hits: #{@cache[function][:hits]}.") else result = @cache[function][:parsed] || true end end end result end |
#caching? ⇒ Boolean
Returns true
if the describe_xxx responses are being cached
219 220 221 |
# File 'lib/slicehost_base.rb', line 219 def caching? @params.key?(:cache) ? @params[:cache] : @@caching end |
#cgi_escape_params(params) ⇒ Object
:nodoc:
129 130 131 |
# File 'lib/slicehost_base.rb', line 129 def cgi_escape_params(params) # :nodoc: params.map {|k,v| "#{CGI.escape(k.to_s)}=#{CGI.escape(v.to_s)}" }.join("&") end |
#generate_request(method, path, params = {}) ⇒ Object
Generate a handy request hash.
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/slicehost_base.rb', line 138 def generate_request(method, path, params={}) # :nodoc: # default request params params = cgi_escape_params(params) request_url = "#{@params[:service]}/#{path}" request_url << "?#{params}" unless params.blank? request = method.new(request_url) case method.name[/([^:]*)$/] && $1 when 'Post' request['Accept'] = '*/*' request['Content-Type'] = 'application/xml' when 'Put' request['Accept'] = '*/*' request['Content-Type'] = 'application/xml' else request['Accept'] = 'application/xml' end request.basic_auth(@slicehost_pasword,'') { :request => request, :server => @params[:server], :port => @params[:port], :protocol => @params[:protocol] } end |
#init(slicehost_pasword, params = {}) ⇒ Object
Params:
:slicehost_url
:logger
:multi_thread
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/slicehost_base.rb', line 94 def init(slicehost_pasword, params={}) #:nodoc: @params = params @cache = {} @error_handler = nil # deny working without credentials if slicehost_pasword.blank? raise SlicehostError.new("Slicehost password is required to operate on Slicehost API service") end @slicehost_pasword = slicehost_pasword # parse Slicehost URL @params[:slicehost_url] ||= ENV['SLICEHOST_URL'] || DEFAULT_SLICEHOST_URL @params[:server] = URI.parse(@params[:slicehost_url]).host @params[:port] = URI.parse(@params[:slicehost_url]).port @params[:service] = URI.parse(@params[:slicehost_url]).path @params[:protocol] = URI.parse(@params[:slicehost_url]).scheme # other params @params[:multi_thread] ||= defined?(SLICEHOST_DAEMON) @logger = @params[:logger] || (defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER) || Logger.new(STDOUT) @logger.info "New #{self.class.name} using #{@params[:multi_thread] ? 'multi' : 'single'}-threaded mode" end |
#multi_thread ⇒ Object
Return true
if this instance works in multi_thread mode and false
otherwise.
125 126 127 |
# File 'lib/slicehost_base.rb', line 125 def multi_thread @params[:multi_thread] end |
#on_exception(options = {:raise=>true, :log=>true}) ⇒ Object
:nodoc:
115 116 117 118 |
# File 'lib/slicehost_base.rb', line 115 def on_exception(={:raise=>true, :log=>true}) # :nodoc: raise if $!.is_a?(SlicehostNoChange) SlicehostError::on_slicehost_exception(self, ) end |
#request_cache_or_info(method, request_hash, parser_class, use_cache = true) ⇒ Object
Perform a request. Skips a response parsing if caching is used.
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/slicehost_base.rb', line 202 def request_cache_or_info(method, request_hash, parser_class, use_cache=true) #:nodoc: # We do not want to break the logic of parsing hence will use a dummy parser to process all the standard # steps (errors checking etc). The dummy parser does nothig - just returns back the params it received. # If the caching is enabled and hit then throw SlicehostNoChange. # P.S. caching works for the whole images list only! (when the list param is blank) response = request_info(request_hash, SlicehostDummyParser.new) # check cache cache_hits?(method.to_sym, response.body) if use_cache parser = parser_class.new(:logger => @logger) @@bench.parser.add!{ parser.parse(response) } result = block_given? ? yield(parser) : parser.result # update parsed data update_cache(method.to_sym, :parsed => result) if use_cache result end |
#request_info(request, parser) ⇒ Object
Perform a request. (4xx and 5xx error handling is being made through SlicehostErrorHandler)
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/slicehost_base.rb', line 167 def request_info(request, parser) #:nodoc: # check single/multi threading mode thread = @params[:multi_thread] ? Thread.current : Thread.main # create a connection if needed thread[:connection] ||= Rightscale::HttpConnection.new(:exception => SlicehostError, :logger => @logger) @connection = thread[:connection] @last_request = request[:request] @last_response = nil # perform a request @@bench.service.add!{ @last_response = @connection.request(request) } # check response for success... if @last_response.is_a?(Net::HTTPSuccess) @error_handler = nil @@bench.parser.add! { parser.parse(@last_response) } return parser.result else @error_handler ||= SlicehostErrorHandler.new(self, parser, :errors_list => @@slicehost_problems) check_result = @error_handler.check(request) if check_result @error_handler = nil return check_result end raise SlicehostError.new(@last_errors, @last_response.code) end rescue @error_handler = nil raise end |
#update_cache(function, hash) ⇒ Object
:nodoc:
254 255 256 |
# File 'lib/slicehost_base.rb', line 254 def update_cache(function, hash) # :nodoc: (@cache[function.to_sym] ||= {}).merge!(hash) if caching? end |