mss-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.yardopts +9 -0
- data/LICENSE.txt +0 -0
- data/README.md +192 -0
- data/bin/mss-rb +178 -0
- data/ca-bundle.crt +3554 -0
- data/lib/mss/core/async_handle.rb +89 -0
- data/lib/mss/core/cacheable.rb +76 -0
- data/lib/mss/core/client.rb +786 -0
- data/lib/mss/core/collection/simple.rb +81 -0
- data/lib/mss/core/collection/with_limit_and_next_token.rb +70 -0
- data/lib/mss/core/collection/with_next_token.rb +96 -0
- data/lib/mss/core/collection.rb +262 -0
- data/lib/mss/core/configuration.rb +527 -0
- data/lib/mss/core/credential_providers.rb +653 -0
- data/lib/mss/core/data.rb +251 -0
- data/lib/mss/core/deprecations.rb +83 -0
- data/lib/mss/core/endpoints.rb +36 -0
- data/lib/mss/core/http/connection_pool.rb +374 -0
- data/lib/mss/core/http/curb_handler.rb +150 -0
- data/lib/mss/core/http/handler.rb +88 -0
- data/lib/mss/core/http/net_http_handler.rb +144 -0
- data/lib/mss/core/http/patch.rb +98 -0
- data/lib/mss/core/http/request.rb +258 -0
- data/lib/mss/core/http/response.rb +80 -0
- data/lib/mss/core/indifferent_hash.rb +87 -0
- data/lib/mss/core/inflection.rb +55 -0
- data/lib/mss/core/ini_parser.rb +41 -0
- data/lib/mss/core/json_client.rb +46 -0
- data/lib/mss/core/json_parser.rb +75 -0
- data/lib/mss/core/json_request_builder.rb +34 -0
- data/lib/mss/core/json_response_parser.rb +78 -0
- data/lib/mss/core/lazy_error_classes.rb +107 -0
- data/lib/mss/core/log_formatter.rb +426 -0
- data/lib/mss/core/managed_file.rb +31 -0
- data/lib/mss/core/meta_utils.rb +44 -0
- data/lib/mss/core/model.rb +61 -0
- data/lib/mss/core/naming.rb +29 -0
- data/lib/mss/core/option_grammar.rb +737 -0
- data/lib/mss/core/options/json_serializer.rb +81 -0
- data/lib/mss/core/options/validator.rb +154 -0
- data/lib/mss/core/options/xml_serializer.rb +117 -0
- data/lib/mss/core/page_result.rb +74 -0
- data/lib/mss/core/policy.rb +938 -0
- data/lib/mss/core/query_client.rb +40 -0
- data/lib/mss/core/query_error_parser.rb +23 -0
- data/lib/mss/core/query_request_builder.rb +46 -0
- data/lib/mss/core/query_response_parser.rb +34 -0
- data/lib/mss/core/region.rb +84 -0
- data/lib/mss/core/region_collection.rb +79 -0
- data/lib/mss/core/resource.rb +412 -0
- data/lib/mss/core/resource_cache.rb +39 -0
- data/lib/mss/core/response.rb +214 -0
- data/lib/mss/core/response_cache.rb +49 -0
- data/lib/mss/core/rest_error_parser.rb +23 -0
- data/lib/mss/core/rest_json_client.rb +39 -0
- data/lib/mss/core/rest_request_builder.rb +153 -0
- data/lib/mss/core/rest_response_parser.rb +65 -0
- data/lib/mss/core/rest_xml_client.rb +46 -0
- data/lib/mss/core/service_interface.rb +82 -0
- data/lib/mss/core/signers/base.rb +45 -0
- data/lib/mss/core/signers/cloud_front.rb +55 -0
- data/lib/mss/core/signers/s3.rb +158 -0
- data/lib/mss/core/signers/version_2.rb +71 -0
- data/lib/mss/core/signers/version_3.rb +85 -0
- data/lib/mss/core/signers/version_3_https.rb +60 -0
- data/lib/mss/core/signers/version_4/chunk_signed_stream.rb +190 -0
- data/lib/mss/core/signers/version_4.rb +227 -0
- data/lib/mss/core/uri_escape.rb +43 -0
- data/lib/mss/core/xml/frame.rb +245 -0
- data/lib/mss/core/xml/frame_stack.rb +84 -0
- data/lib/mss/core/xml/grammar.rb +306 -0
- data/lib/mss/core/xml/parser.rb +69 -0
- data/lib/mss/core/xml/root_frame.rb +64 -0
- data/lib/mss/core/xml/sax_handlers/libxml.rb +46 -0
- data/lib/mss/core/xml/sax_handlers/nokogiri.rb +55 -0
- data/lib/mss/core/xml/sax_handlers/ox.rb +40 -0
- data/lib/mss/core/xml/sax_handlers/rexml.rb +46 -0
- data/lib/mss/core/xml/stub.rb +122 -0
- data/lib/mss/core.rb +602 -0
- data/lib/mss/errors.rb +161 -0
- data/lib/mss/rails.rb +194 -0
- data/lib/mss/s3/access_control_list.rb +262 -0
- data/lib/mss/s3/acl_object.rb +263 -0
- data/lib/mss/s3/acl_options.rb +200 -0
- data/lib/mss/s3/bucket.rb +757 -0
- data/lib/mss/s3/bucket_collection.rb +161 -0
- data/lib/mss/s3/bucket_lifecycle_configuration.rb +472 -0
- data/lib/mss/s3/bucket_region_cache.rb +51 -0
- data/lib/mss/s3/bucket_tag_collection.rb +110 -0
- data/lib/mss/s3/bucket_version_collection.rb +78 -0
- data/lib/mss/s3/cipher_io.rb +119 -0
- data/lib/mss/s3/client/xml.rb +265 -0
- data/lib/mss/s3/client.rb +2076 -0
- data/lib/mss/s3/config.rb +60 -0
- data/lib/mss/s3/cors_rule.rb +107 -0
- data/lib/mss/s3/cors_rule_collection.rb +193 -0
- data/lib/mss/s3/data_options.rb +190 -0
- data/lib/mss/s3/encryption_utils.rb +145 -0
- data/lib/mss/s3/errors.rb +93 -0
- data/lib/mss/s3/multipart_upload.rb +353 -0
- data/lib/mss/s3/multipart_upload_collection.rb +75 -0
- data/lib/mss/s3/object_collection.rb +355 -0
- data/lib/mss/s3/object_metadata.rb +102 -0
- data/lib/mss/s3/object_upload_collection.rb +76 -0
- data/lib/mss/s3/object_version.rb +153 -0
- data/lib/mss/s3/object_version_collection.rb +88 -0
- data/lib/mss/s3/paginated_collection.rb +74 -0
- data/lib/mss/s3/policy.rb +73 -0
- data/lib/mss/s3/prefix_and_delimiter_collection.rb +46 -0
- data/lib/mss/s3/prefixed_collection.rb +84 -0
- data/lib/mss/s3/presign_v4.rb +135 -0
- data/lib/mss/s3/presigned_post.rb +574 -0
- data/lib/mss/s3/region_detection.rb +75 -0
- data/lib/mss/s3/request.rb +61 -0
- data/lib/mss/s3/s3_object.rb +1795 -0
- data/lib/mss/s3/tree/branch_node.rb +67 -0
- data/lib/mss/s3/tree/child_collection.rb +103 -0
- data/lib/mss/s3/tree/leaf_node.rb +93 -0
- data/lib/mss/s3/tree/node.rb +21 -0
- data/lib/mss/s3/tree/parent.rb +86 -0
- data/lib/mss/s3/tree.rb +115 -0
- data/lib/mss/s3/uploaded_part.rb +81 -0
- data/lib/mss/s3/uploaded_part_collection.rb +83 -0
- data/lib/mss/s3/website_configuration.rb +101 -0
- data/lib/mss/s3.rb +161 -0
- data/lib/mss/version.rb +16 -0
- data/lib/mss-sdk.rb +2 -0
- data/lib/mss.rb +14 -0
- data/rails/init.rb +14 -0
- metadata +201 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
module MSS
|
14
|
+
module Core
|
15
|
+
|
16
|
+
# @api private
|
17
|
+
module Inflection
|
18
|
+
|
19
|
+
def ruby_name mss_name
|
20
|
+
|
21
|
+
inflector = Hash.new do |hash,key|
|
22
|
+
|
23
|
+
key.
|
24
|
+
sub(/^.*:/, ''). # strip namespace
|
25
|
+
gsub(/([A-Z0-9]+)([A-Z][a-z])/, '\1_\2'). # split acronyms
|
26
|
+
scan(/[a-z]+|\d+|[A-Z0-9]+[a-z]*/). # split words
|
27
|
+
join('_').downcase # join parts
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
# add a few irregular inflections
|
32
|
+
inflector['ETag'] = 'etag'
|
33
|
+
inflector['s3Bucket'] = 's3_bucket'
|
34
|
+
inflector['s3Key'] = 's3_key'
|
35
|
+
inflector['Ec2KeyName'] = 'ec2_key_name'
|
36
|
+
inflector['Ec2SubnetId'] = 'ec2_subnet_id'
|
37
|
+
inflector['Ec2VolumeId'] = 'ec2_volume_id'
|
38
|
+
inflector['Ec2InstanceId'] = 'ec2_instance_id'
|
39
|
+
inflector['ElastiCache'] = 'elasticache'
|
40
|
+
inflector['NotificationARNs'] = 'notification_arns'
|
41
|
+
|
42
|
+
inflector[mss_name]
|
43
|
+
|
44
|
+
end
|
45
|
+
module_function :ruby_name
|
46
|
+
|
47
|
+
def class_name(name)
|
48
|
+
name.sub(/^(.)/) { |m| m.upcase }.
|
49
|
+
gsub(/[-_]([a-z])/i) { |m| m[1,1].upcase }
|
50
|
+
end
|
51
|
+
module_function :class_name
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Copyright 2011-2014 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
module MSS
|
14
|
+
module Core
|
15
|
+
|
16
|
+
# @api private
|
17
|
+
module IniParser
|
18
|
+
|
19
|
+
def self.parse(ini)
|
20
|
+
current_section = {}
|
21
|
+
map = {}
|
22
|
+
ini.split(/\r?\n/).each do |line|
|
23
|
+
line = line.split(/^|\s;/).first # remove comments
|
24
|
+
section = line.match(/^\s*\[([^\[\]]+)\]\s*$/) unless line.nil?
|
25
|
+
if section
|
26
|
+
current_section = section[1]
|
27
|
+
elsif current_section
|
28
|
+
item = line.match(/^\s*(.+?)\s*=\s*(.+)\s*$/) unless line.nil?
|
29
|
+
if item
|
30
|
+
map[current_section] = map[current_section] || {}
|
31
|
+
map[current_section][item[1]] = item[2]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
map
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
module MSS
|
14
|
+
module Core
|
15
|
+
class JSONClient < Core::Client
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def self.request_builder_for api_config, operation
|
20
|
+
JSONRequestBuilder.new(api_config, operation)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.response_parser_for api_config, operation
|
24
|
+
JSONResponseParser.new(operation[:outputs])
|
25
|
+
end
|
26
|
+
|
27
|
+
def extract_error_details response
|
28
|
+
if
|
29
|
+
response.http_response.status >= 300 and
|
30
|
+
body = response.http_response.body and
|
31
|
+
json = (::JSON.load(body) rescue nil) and
|
32
|
+
type = json["__type"]
|
33
|
+
then
|
34
|
+
code = type.split('#').last
|
35
|
+
if code == 'RequestEntityTooLarge'
|
36
|
+
message = 'Request body must be less than 1 MB'
|
37
|
+
else
|
38
|
+
message = json['message'] || json['Message']
|
39
|
+
end
|
40
|
+
[code, message]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
require 'json'
|
14
|
+
require 'time'
|
15
|
+
require 'bigdecimal'
|
16
|
+
require 'base64'
|
17
|
+
|
18
|
+
module MSS
|
19
|
+
module Core
|
20
|
+
|
21
|
+
# @api private
|
22
|
+
class JSONParser
|
23
|
+
|
24
|
+
def initialize rules
|
25
|
+
@rules = rules
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :rules
|
29
|
+
|
30
|
+
def parse body
|
31
|
+
body = "{}" if [nil, ''].include?(body)
|
32
|
+
translate(JSON.load(body))
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
|
37
|
+
# @param [Hash] values
|
38
|
+
# @param [Hash] rules
|
39
|
+
# @return [Hash]
|
40
|
+
def translate values, rules = @rules
|
41
|
+
rules.inject({}) do |data,(key,rule)|
|
42
|
+
if values.key?(key) && !values[key].nil?
|
43
|
+
data.merge(rule[:sym] || key => translate_value(values[key], rule))
|
44
|
+
else
|
45
|
+
data
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def translate_hash values, rules
|
51
|
+
translate(values, rules[:members])
|
52
|
+
end
|
53
|
+
|
54
|
+
def translate_map values, rules
|
55
|
+
values.inject({}) do |data,(key,value)|
|
56
|
+
data.merge(key => translate_value(value, rules[:members]))
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def translate_value value, rule
|
61
|
+
case
|
62
|
+
when value.is_a?(Array) then value.map{|v| translate_value(v, rule) }
|
63
|
+
when rule[:type] == :hash then translate_hash(value, rule)
|
64
|
+
when rule[:type] == :map then translate_map(value, rule)
|
65
|
+
when rule[:type] == :blob then Base64.decode64(value)
|
66
|
+
when rule[:type] == :time then Time.at(value)
|
67
|
+
when rule[:type] == :big_decimal then BigDecimal.new(value)
|
68
|
+
else value
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
module MSS
|
14
|
+
module Core
|
15
|
+
|
16
|
+
# @api private
|
17
|
+
class JSONRequestBuilder
|
18
|
+
|
19
|
+
def initialize api, operation
|
20
|
+
@x_amz_target = api[:target_prefix] + operation[:name]
|
21
|
+
@content_type = "application/x-amz-json-#{api[:json_version] || 1.0}"
|
22
|
+
@grammar = OptionGrammar.customize(operation[:inputs])
|
23
|
+
end
|
24
|
+
|
25
|
+
def populate_request request, options
|
26
|
+
request.headers["content-type"] = @content_type
|
27
|
+
request.headers["x-amz-target"] = @x_amz_target
|
28
|
+
request.body = @grammar.to_json(options)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
require 'json'
|
14
|
+
require 'time'
|
15
|
+
require 'bigdecimal'
|
16
|
+
require 'base64'
|
17
|
+
|
18
|
+
module MSS
|
19
|
+
module Core
|
20
|
+
|
21
|
+
# @api private
|
22
|
+
class JSONResponseParser
|
23
|
+
|
24
|
+
def initialize rules
|
25
|
+
@rules = rules
|
26
|
+
end
|
27
|
+
|
28
|
+
def extract_data response
|
29
|
+
body = response.http_response.body
|
30
|
+
body = "{}" if [nil, ''].include?(body)
|
31
|
+
translate(JSON.load(body))
|
32
|
+
end
|
33
|
+
|
34
|
+
def simulate
|
35
|
+
{}
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
|
40
|
+
# @param [Hash] values
|
41
|
+
# @param [Hash] rules
|
42
|
+
# @return [Hash]
|
43
|
+
def translate values, rules = @rules
|
44
|
+
rules.inject({}) do |data,(key,rule)|
|
45
|
+
if values.key?(key)
|
46
|
+
data.merge(rule[:sym] || key => translate_value(values[key], rule))
|
47
|
+
else
|
48
|
+
data
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def translate_hash values, rules
|
54
|
+
translate(values, rules[:members])
|
55
|
+
end
|
56
|
+
|
57
|
+
def translate_map values, rules
|
58
|
+
values.inject({}) do |data,(key,value)|
|
59
|
+
data.merge(key => translate_value(value, rules[:members]))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def translate_value value, rule
|
64
|
+
case
|
65
|
+
when value.is_a?(Array) then value.map{|v| translate_value(v, rule) }
|
66
|
+
when rule[:type] == :hash then translate_hash(value, rule)
|
67
|
+
when rule[:type] == :map then translate_map(value, rule)
|
68
|
+
when rule[:type] == :blob then Base64.decode64(value)
|
69
|
+
when rule[:type] == :time then Time.at(value)
|
70
|
+
when rule[:type] == :big_decimal then BigDecimal.new(value)
|
71
|
+
else value
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# Copyright 2011-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License"). You
|
4
|
+
# may not use this file except in compliance with the License. A copy of
|
5
|
+
# the License is located at
|
6
|
+
#
|
7
|
+
#
|
8
|
+
# or in the "license" file accompanying this file. This file is
|
9
|
+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
10
|
+
# ANY KIND, either express or implied. See the License for the specific
|
11
|
+
# language governing permissions and limitations under the License.
|
12
|
+
|
13
|
+
require 'thread'
|
14
|
+
|
15
|
+
module MSS
|
16
|
+
module Core
|
17
|
+
|
18
|
+
# Provides lazy creation of error classes via {#const_missing}.
|
19
|
+
#
|
20
|
+
# Extend this module provides 3 benefits to another module:
|
21
|
+
#
|
22
|
+
# * A method that accepts strings and returns error classes.
|
23
|
+
# * Thread-safe dynamic error class creation via {#const_missing}
|
24
|
+
# * An error grammar for parsing MSS xml errors
|
25
|
+
#
|
26
|
+
# Here is an example of how it works:
|
27
|
+
#
|
28
|
+
# Class Foo
|
29
|
+
# module Errors
|
30
|
+
# extend MSS::Core::LazyErrorClasses
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# Foo::Errors.error_class('NoSuchKey')
|
35
|
+
# #=> Foo::Errors::NoSuckKey
|
36
|
+
#
|
37
|
+
# Foo::Errors.error_class('Nested.Error.Klasses')
|
38
|
+
# #=> Foo::Errors::Nested::Error::Klasses
|
39
|
+
#
|
40
|
+
# The errors returned from {#error_class} are subclasses
|
41
|
+
# of {MSS::Errors::Base}.
|
42
|
+
#
|
43
|
+
module LazyErrorClasses
|
44
|
+
|
45
|
+
# This grammar parses the defualt MSS XML error format
|
46
|
+
BASE_ERROR_GRAMMAR = XML::Grammar.customize do
|
47
|
+
element("Error") do
|
48
|
+
ignore
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# @api private
|
53
|
+
def self.extended base
|
54
|
+
|
55
|
+
unless base.const_defined?(:GRAMMAR)
|
56
|
+
base.const_set(:GRAMMAR, BASE_ERROR_GRAMMAR)
|
57
|
+
end
|
58
|
+
|
59
|
+
mutex = Mutex.new
|
60
|
+
MetaUtils.extend_method(base, :const_missing_mutex) { mutex }
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
# Defines a new error class.
|
65
|
+
# @param [String,Symbol] constant
|
66
|
+
# @return [nil]
|
67
|
+
def const_missing constant
|
68
|
+
const_missing_mutex.synchronize do
|
69
|
+
# It's possible the constant was defined by another thread while
|
70
|
+
# this thread was waiting on the mutex, check before setting.
|
71
|
+
if error_const_set?(constant)
|
72
|
+
const_get(constant)
|
73
|
+
else
|
74
|
+
const_set(constant, Class.new(Errors::Base) { extend LazyErrorClasses })
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Converts the error code into an error class constant.
|
80
|
+
#
|
81
|
+
# MSS::EC2::Errors.error_class('Non.Existent.Error')
|
82
|
+
# #=> MSS::EC2::Errors::Non::Existent::Error
|
83
|
+
#
|
84
|
+
# @param [String] code An MSS error code.
|
85
|
+
#
|
86
|
+
# @return [Class] Returns the error class defiend by the error code.
|
87
|
+
#
|
88
|
+
def error_class code
|
89
|
+
module_eval("#{self}::#{code.gsub('.Range','Range').gsub(".","::")}")
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
# @return [Boolean] Returns true if the constant is defined in the
|
95
|
+
# current module.
|
96
|
+
def error_const_set?(constant)
|
97
|
+
# Not using #const_defined? because in Ruby 1.9+, it returns true for
|
98
|
+
# constants not defined directly on the current module.
|
99
|
+
constant = constant.to_sym
|
100
|
+
# In Ruby 1.8, #constants returns an array of strings,
|
101
|
+
# in Ruby 1.9+, #constants returns an array of symbols.
|
102
|
+
constants.any? { |c| c.to_sym == constant }
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|