right_cloud_api_base 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/HISTORY +2 -0
- data/LICENSE +19 -0
- data/README.md +14 -0
- data/Rakefile +37 -0
- data/lib/base/api_manager.rb +707 -0
- data/lib/base/helpers/cloud_api_logger.rb +214 -0
- data/lib/base/helpers/http_headers.rb +239 -0
- data/lib/base/helpers/http_parent.rb +103 -0
- data/lib/base/helpers/http_request.rb +173 -0
- data/lib/base/helpers/http_response.rb +122 -0
- data/lib/base/helpers/net_http_patch.rb +31 -0
- data/lib/base/helpers/query_api_patterns.rb +862 -0
- data/lib/base/helpers/support.rb +270 -0
- data/lib/base/helpers/support.xml.rb +306 -0
- data/lib/base/helpers/utils.rb +380 -0
- data/lib/base/manager.rb +122 -0
- data/lib/base/parsers/json.rb +38 -0
- data/lib/base/parsers/plain.rb +36 -0
- data/lib/base/parsers/rexml.rb +83 -0
- data/lib/base/parsers/sax.rb +200 -0
- data/lib/base/routines/cache_validator.rb +184 -0
- data/lib/base/routines/connection_proxies/net_http_persistent_proxy.rb +194 -0
- data/lib/base/routines/connection_proxies/right_http_connection_proxy.rb +224 -0
- data/lib/base/routines/connection_proxy.rb +66 -0
- data/lib/base/routines/request_analyzer.rb +122 -0
- data/lib/base/routines/request_generator.rb +48 -0
- data/lib/base/routines/request_initializer.rb +52 -0
- data/lib/base/routines/response_analyzer.rb +152 -0
- data/lib/base/routines/response_parser.rb +79 -0
- data/lib/base/routines/result_wrapper.rb +75 -0
- data/lib/base/routines/retry_manager.rb +106 -0
- data/lib/base/routines/routine.rb +98 -0
- data/lib/right_cloud_api_base.rb +72 -0
- data/lib/right_cloud_api_base_version.rb +37 -0
- data/right_cloud_api_base.gemspec +63 -0
- data/spec/helpers/query_api_pattern_spec.rb +312 -0
- data/spec/helpers/support_spec.rb +211 -0
- data/spec/helpers/support_xml_spec.rb +207 -0
- data/spec/helpers/utils_spec.rb +179 -0
- data/spec/routines/connection_proxies/test_net_http_persistent_proxy_spec.rb +143 -0
- data/spec/routines/test_cache_validator_spec.rb +152 -0
- data/spec/routines/test_connection_proxy_spec.rb +44 -0
- data/spec/routines/test_request_analyzer_spec.rb +106 -0
- data/spec/routines/test_response_analyzer_spec.rb +132 -0
- data/spec/routines/test_response_parser_spec.rb +228 -0
- data/spec/routines/test_result_wrapper_spec.rb +63 -0
- data/spec/routines/test_retry_manager_spec.rb +84 -0
- data/spec/spec_helper.rb +15 -0
- metadata +215 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2013 RightScale, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# 'Software'), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
18
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
19
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
20
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
21
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
module RightScale
|
25
|
+
module CloudApi
|
26
|
+
|
27
|
+
# The routine parses the current response.
|
28
|
+
#
|
29
|
+
# The supportes content-types are: xml and json.
|
30
|
+
# In the case of any other content-type it does nothing.
|
31
|
+
#
|
32
|
+
class ResponseParser < Routine
|
33
|
+
|
34
|
+
# Main entry point.
|
35
|
+
#
|
36
|
+
def process
|
37
|
+
# There is no way to parse an IO response
|
38
|
+
return nil if data[:response][:instance].is_io?
|
39
|
+
|
40
|
+
xml_parser = Utils::get_xml_parser_class(data[:options][:xml_parser])
|
41
|
+
content_type = (data[:response][:instance].headers || {})["content-type"].to_s
|
42
|
+
body = data[:response][:instance].body.to_s
|
43
|
+
|
44
|
+
# If it was explicitly requested not to parse the response then return it as is.
|
45
|
+
if data[:options][:raw_response]
|
46
|
+
data[:result] = body
|
47
|
+
return
|
48
|
+
end
|
49
|
+
|
50
|
+
# Find the appropriate parser.
|
51
|
+
parser = if body._blank?
|
52
|
+
Parser::Plain
|
53
|
+
else
|
54
|
+
case content_type
|
55
|
+
when /xml/ then xml_parser
|
56
|
+
when /json|javascript/ then Parser::Json
|
57
|
+
else
|
58
|
+
if data[:response][:instance].body.to_s[/\A<\?xml /]
|
59
|
+
# Sometimes Amazon does not set a proper header
|
60
|
+
xml_parser
|
61
|
+
else
|
62
|
+
Parser::Plain
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
# Parse the response
|
67
|
+
with_timer("Response parsing with #{parser}") do
|
68
|
+
options = {}
|
69
|
+
options[:encoding] = 'UTF-8' if /utf-8/i === content_type
|
70
|
+
#
|
71
|
+
cloud_api_logger.log("Attempting to parse cloud response with: '#{options[:encoding] || 'DEFAULT'}' encoding", :response_parser)
|
72
|
+
data[:response][:parsed] = parser::parse(body, options)
|
73
|
+
end
|
74
|
+
data[:result] = data[:response][:parsed]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2013 RightScale, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# 'Software'), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
18
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
19
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
20
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
21
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
module RightScale
|
25
|
+
module CloudApi
|
26
|
+
|
27
|
+
# The Routine adds metadata to the result.
|
28
|
+
#
|
29
|
+
# @example:
|
30
|
+
# response = ec2.DescribeSecurityGroups #=> A list of SecurityGroups
|
31
|
+
# response.metadata #=>
|
32
|
+
# {:headers=>
|
33
|
+
# {"content-type"=>["text/xml;charset=UTF-8"],
|
34
|
+
# "transfer-encoding"=>["chunked"],
|
35
|
+
# "date"=>["Fri, 22 Feb 2013 00:02:43 GMT"],
|
36
|
+
# "server"=>["AmazonEC2"]},
|
37
|
+
# :code=>"200",
|
38
|
+
# :cache=>
|
39
|
+
# {:key=>"DescribeSecurityGroups",
|
40
|
+
# :record=>
|
41
|
+
# {:timestamp=>2013-02-22 00:02:44 UTC,
|
42
|
+
# :md5=>"0e3e12e1c18237d9f9510e90e7b8950e",
|
43
|
+
# :hits=>0}}}
|
44
|
+
#
|
45
|
+
class ResultWrapper < Routine
|
46
|
+
|
47
|
+
class Result < BlankSlate
|
48
|
+
attr_reader :metadata
|
49
|
+
|
50
|
+
def initialize(response, metadata)
|
51
|
+
@response = response
|
52
|
+
@metadata = metadata
|
53
|
+
end
|
54
|
+
|
55
|
+
# Feed all the missing methods to the original object.
|
56
|
+
def method_missing(method, *params, &block)
|
57
|
+
@response.send(method, *params, &block)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Main entry point.
|
62
|
+
#
|
63
|
+
def process
|
64
|
+
cache = data._at(:vars, :cache, :default => nil)
|
65
|
+
metadata = {}
|
66
|
+
metadata[:headers] = data[:response][:instance].headers
|
67
|
+
metadata[:code] = data[:response][:instance].code
|
68
|
+
metadata[:cache] = cache if cache
|
69
|
+
#
|
70
|
+
data[:result] = Result::new(data[:result], metadata)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2013 RightScale, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# 'Software'), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
18
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
19
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
20
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
21
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
module RightScale
|
25
|
+
module CloudApi
|
26
|
+
|
27
|
+
# The routine is responsible for retries/reiterations.
|
28
|
+
#
|
29
|
+
# If retries are enabled then a singe API call may perform upto DEFAULT_RETRY_COUNT request
|
30
|
+
# attempts who may take upto DEFAULT_REITERATION_TIME secsons.
|
31
|
+
#
|
32
|
+
class RetryManager < Routine
|
33
|
+
class Error < CloudApi::HttpError
|
34
|
+
end
|
35
|
+
|
36
|
+
DEFAULT_RETRY_COUNT = 2
|
37
|
+
DEFAULT_REITERATION_TIME = 10
|
38
|
+
DEFAULT_SLEEP_TIME = 0.2
|
39
|
+
|
40
|
+
# Retries manager.
|
41
|
+
#
|
42
|
+
# The manager usually takes the very first position in routines chain.
|
43
|
+
# It just increments its counters if we did not reach a possible count of retries or
|
44
|
+
# complains if there are no attempts left or if API request time is over.
|
45
|
+
#
|
46
|
+
# There are 2 possible reasons for a retry to be performed:
|
47
|
+
# 1. There was a redirect request (HTTP 3xx code)
|
48
|
+
# 2. There was an error (HTTP 5xx, 4xx) and
|
49
|
+
#
|
50
|
+
def process
|
51
|
+
retry_options = data[:options][:retry] || {}
|
52
|
+
max_retry_count = retry_options[:count] || DEFAULT_RETRY_COUNT
|
53
|
+
reiteration_time = retry_options[:reiteration_time] || DEFAULT_REITERATION_TIME
|
54
|
+
sleep_time = retry_options[:sleep_time] || DEFAULT_SLEEP_TIME
|
55
|
+
|
56
|
+
# Initialize things on the first run for the current request.
|
57
|
+
unless data[:vars][:retry]
|
58
|
+
data[:vars][:retry] = {}
|
59
|
+
data[:vars][:retry][:count] = 0
|
60
|
+
data[:vars][:retry][:sleep_time] = 0
|
61
|
+
# if body is a IO object - remember its initial position in a file
|
62
|
+
data[:vars][:retry][:orig_body_stream_pos] = data[:request][:body].is_a?(IO) && data[:request][:body].pos
|
63
|
+
else
|
64
|
+
# Increment retry attempts count
|
65
|
+
data[:vars][:retry][:count] += 1
|
66
|
+
end
|
67
|
+
|
68
|
+
# Complain on any issue
|
69
|
+
if max_retry_count < @data[:vars][:retry][:count]
|
70
|
+
error_message = "RetryManager: No more retries left."
|
71
|
+
elsif Time.now > @data[:vars][:system][:started_at] + reiteration_time
|
72
|
+
error_message = "RetryManager: Retry timeout of #{reiteration_time} seconds has been reached."
|
73
|
+
end
|
74
|
+
|
75
|
+
# Raise exception if request runs out-of-time or attempts.
|
76
|
+
if error_message
|
77
|
+
http_data = @data[:vars][:retry][:http]
|
78
|
+
http_code = http_data && http_data[:code]
|
79
|
+
http_message = http_data && http_data[:message]
|
80
|
+
error_message = "#{http_message}\n#{error_message}" if http_message
|
81
|
+
raise Error::new(http_code, error_message)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Continue (with a delay when needed)
|
85
|
+
if data[:vars][:retry][:sleep_time] > 0
|
86
|
+
cloud_api_logger.log("Sleeping for #{data[:vars][:retry][:sleep_time]} seconds before retry attempt ##{data[:vars][:retry][:count]}", :retry_manager)
|
87
|
+
sleep data[:vars][:retry][:sleep_time]
|
88
|
+
data[:vars][:retry][:sleep_time] *= 2
|
89
|
+
else
|
90
|
+
data[:vars][:retry][:sleep_time] = sleep_time
|
91
|
+
end
|
92
|
+
|
93
|
+
# Restore file pointer in IO body case.
|
94
|
+
if data[:request][:instance] &&
|
95
|
+
data[:request][:instance].is_io? &&
|
96
|
+
data[:request][:instance].body.respond_to?('pos') &&
|
97
|
+
data[:request][:instance].body.respond_to?('pos=') &&
|
98
|
+
data[:request][:instance].body.pos != data[:vars][:retry][:orig_body_stream_pos]
|
99
|
+
cloud_api_logger.log("Restoring file position to #{data[:vars][:retry][:orig_body_stream_pos]}", :retry_manager)
|
100
|
+
data[:request][:instance].body.pos = data[:vars][:retry][:orig_body_stream_pos]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2013 RightScale, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# 'Software'), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
18
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
19
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
20
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
21
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
module RightScale
|
25
|
+
module CloudApi
|
26
|
+
|
27
|
+
# This is a parent class for all the other routines.
|
28
|
+
#
|
29
|
+
# The routine is a very simple object that does a simple task in the API call processing stack
|
30
|
+
# and exits. In most cases a single routine knows nothing about any other routines. It just
|
31
|
+
# takes incoming params from @data hash, processes it and stores back to the @adata attribute.
|
32
|
+
#
|
33
|
+
class Routine
|
34
|
+
attr_reader :data
|
35
|
+
|
36
|
+
# Initializes the @data attribute. Is called before *process* method.
|
37
|
+
#
|
38
|
+
# @param [Hash] data See ApiManager for better explanation what data is.
|
39
|
+
#
|
40
|
+
def reset(data=nil)
|
41
|
+
@data = data
|
42
|
+
end
|
43
|
+
|
44
|
+
# Main entry point. The method must be overriden by sub-classes.
|
45
|
+
def process
|
46
|
+
raise Error::new("This method should be implemented by a subclass")
|
47
|
+
end
|
48
|
+
|
49
|
+
# Initialize and process the routine. Is usially called from unit tests.
|
50
|
+
def execute(data)
|
51
|
+
reset(data)
|
52
|
+
process
|
53
|
+
end
|
54
|
+
|
55
|
+
# Current options.
|
56
|
+
#
|
57
|
+
# @return [Hash]
|
58
|
+
#
|
59
|
+
def options
|
60
|
+
@data[:options]
|
61
|
+
end
|
62
|
+
|
63
|
+
# Current logger.
|
64
|
+
#
|
65
|
+
# @return [CloudApiLogger]
|
66
|
+
#
|
67
|
+
def cloud_api_logger
|
68
|
+
options[:cloud_api_logger]
|
69
|
+
end
|
70
|
+
|
71
|
+
# The method takes a block of code and logs how much time the given block took to execute.
|
72
|
+
#
|
73
|
+
# @param [String] description The prefix that is added to every logged line.
|
74
|
+
# @param [Symbol] log_key The log key (see {RightScale::CloudApi::CloudApiLogger}).
|
75
|
+
#
|
76
|
+
def with_timer(description = 'Timer', log_key = :timer, &block)
|
77
|
+
cloud_api_logger.log("#{description} started...",:timer)
|
78
|
+
start = Time::now
|
79
|
+
result = block.call
|
80
|
+
cloud_api_logger.log("#{description} completed (#{'%.6f' % (Time::now - start)} sec)", log_key)
|
81
|
+
result
|
82
|
+
end
|
83
|
+
|
84
|
+
# A helper method for invoking callbacks.
|
85
|
+
#
|
86
|
+
# The method checks if the given Proc exists and invokes it with the given set of arguments.
|
87
|
+
# In the case when proc==nil the method does nothing.
|
88
|
+
#
|
89
|
+
# @param [Proc] proc The callback.
|
90
|
+
# @param [Any] args A set of callback method arguments.
|
91
|
+
#
|
92
|
+
def invoke_callback_method(proc, *args) # :nodoc:
|
93
|
+
proc.call(*args) if proc.is_a?(Proc)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2013 RightScale, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# 'Software'), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
18
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
19
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
20
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
21
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
require 'rubygems'
|
25
|
+
require 'time'
|
26
|
+
require 'openssl'
|
27
|
+
require 'net/https'
|
28
|
+
require 'base64'
|
29
|
+
require 'cgi'
|
30
|
+
require 'logger'
|
31
|
+
require 'digest/md5'
|
32
|
+
|
33
|
+
$:.unshift(File::expand_path(File::dirname(__FILE__)))
|
34
|
+
|
35
|
+
require "right_cloud_api_base_version"
|
36
|
+
|
37
|
+
# Helpers
|
38
|
+
require "base/helpers/support"
|
39
|
+
require "base/helpers/support.xml"
|
40
|
+
require "base/helpers/utils"
|
41
|
+
require "base/helpers/net_http_patch"
|
42
|
+
require "base/helpers/http_headers"
|
43
|
+
require "base/helpers/http_parent"
|
44
|
+
require "base/helpers/http_request"
|
45
|
+
require "base/helpers/http_response"
|
46
|
+
require "base/helpers/query_api_patterns"
|
47
|
+
require "base/helpers/cloud_api_logger"
|
48
|
+
|
49
|
+
# Managers
|
50
|
+
require "base/manager"
|
51
|
+
require "base/api_manager"
|
52
|
+
|
53
|
+
# Default parsers
|
54
|
+
require "base/parsers/plain"
|
55
|
+
require "base/parsers/json"
|
56
|
+
require "base/parsers/rexml"
|
57
|
+
require "base/parsers/sax"
|
58
|
+
|
59
|
+
# Default routines
|
60
|
+
require "base/routines/routine"
|
61
|
+
require "base/routines/retry_manager"
|
62
|
+
require "base/routines/request_initializer"
|
63
|
+
require "base/routines/request_generator"
|
64
|
+
require "base/routines/connection_proxy"
|
65
|
+
require "base/routines/connection_proxies/right_http_connection_proxy"
|
66
|
+
require "base/routines/connection_proxies/net_http_persistent_proxy"
|
67
|
+
require "base/routines/response_parser"
|
68
|
+
require "base/routines/request_analyzer"
|
69
|
+
require "base/routines/response_analyzer"
|
70
|
+
require "base/routines/cache_validator"
|
71
|
+
require "base/routines/result_wrapper"
|
72
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2013 RightScale, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# 'Software'), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
18
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
19
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
20
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
21
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
# RightScale namespace
|
25
|
+
#
|
26
|
+
# @api public
|
27
|
+
#
|
28
|
+
module RightScale
|
29
|
+
# CloudApi gem namespace
|
30
|
+
module CloudApi
|
31
|
+
# CloudApi gem version namespace
|
32
|
+
module VERSION
|
33
|
+
# The gem version
|
34
|
+
STRING = '0.1.0'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#-- -*- mode: ruby; encoding: utf-8 -*-
|
2
|
+
# Copyright (c) 2013 RightScale, Inc.
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# 'Software'), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
18
|
+
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
19
|
+
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
20
|
+
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
21
|
+
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#++
|
23
|
+
|
24
|
+
require 'rubygems'
|
25
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'lib/right_cloud_api_base_version'))
|
26
|
+
|
27
|
+
Gem::Specification.new do |spec|
|
28
|
+
spec.name = 'right_cloud_api_base'
|
29
|
+
spec.version = RightScale::CloudApi::VERSION::STRING
|
30
|
+
spec.authors = ['RightScale, Inc.']
|
31
|
+
spec.email = 'support@rightscale.com'
|
32
|
+
spec.summary = 'The gem provides base Query and REST API management functionalities for ' +
|
33
|
+
'Amazon, OpenStack, Rackspace, CloudStack, etc cloud services'
|
34
|
+
spec.rdoc_options = ['--main', 'README.md', '--title', '']
|
35
|
+
spec.extra_rdoc_files = ['README.md']
|
36
|
+
spec.require_path = 'lib'
|
37
|
+
spec.required_ruby_version = '>= 1.8.7'
|
38
|
+
|
39
|
+
spec.add_dependency 'json', '>= 1.0.0'
|
40
|
+
spec.add_dependency 'ruby-hmac', '>= 0.4.0'
|
41
|
+
spec.add_dependency 'libxml-ruby', '>= 1.0.0'
|
42
|
+
spec.add_dependency 'net-http-persistent', '>= 2.9.0'
|
43
|
+
|
44
|
+
spec.add_dependency 'redcarpet', (RUBY_VERSION < '1.9') ? '= 2.3.0' : '>= 3.0.0'
|
45
|
+
|
46
|
+
spec.add_development_dependency 'rspec', '>= 2.14.0'
|
47
|
+
spec.add_development_dependency 'rake'
|
48
|
+
|
49
|
+
spec.description = <<-EOF
|
50
|
+
== DESCRIPTION:
|
51
|
+
|
52
|
+
right_cloud_api_base gem.
|
53
|
+
|
54
|
+
The gem provides base Query and REST API management functionalities for
|
55
|
+
Amazon, OpenStack, Rackspace, CloudStack, etc cloud services.
|
56
|
+
|
57
|
+
EOF
|
58
|
+
|
59
|
+
candidates = Dir.glob('{lib,spec}/**/*') +
|
60
|
+
['LICENSE', 'HISTORY', 'README.md', 'Rakefile', 'right_cloud_api_base.gemspec']
|
61
|
+
spec.files = candidates.sort
|
62
|
+
spec.test_files = Dir.glob('spec/**/*')
|
63
|
+
end
|