aws-sdk-core 2.0.0.rc15 → 2.0.0.rc16

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/apis/DynamoDB.paginators.json +0 -1
  3. data/apis/EC2.resources.json +16 -0
  4. data/apis/ElasticBeanstalk.api.json +4 -1
  5. data/apis/Glacier.resources.json +5 -9
  6. data/apis/IAM.resources.json +1 -1
  7. data/apis/Kinesis.api.json +158 -0
  8. data/apis/Kinesis.paginators.json +0 -6
  9. data/apis/OpsWorks.api.json +36 -5
  10. data/apis/OpsWorks.resources.json +181 -0
  11. data/apis/S3.resources.json +13 -2
  12. data/apis/SQS.resources.json +0 -10
  13. data/bin/aws.rb +9 -0
  14. data/lib/aws.rb +30 -1
  15. data/lib/aws/api/docstrings.rb +35 -0
  16. data/lib/aws/api/documenter.rb +31 -28
  17. data/lib/aws/client.rb +83 -0
  18. data/lib/aws/credential_provider_chain.rb +3 -1
  19. data/lib/aws/errors.rb +16 -7
  20. data/lib/aws/pageable_response.rb +1 -1
  21. data/lib/aws/plugins/csd_conditional_signing.rb +5 -0
  22. data/lib/aws/plugins/response_paging.rb +9 -3
  23. data/lib/aws/plugins/s3_url_encoded_keys.rb +7 -7
  24. data/lib/aws/query/handler.rb +4 -5
  25. data/lib/aws/version.rb +1 -1
  26. data/lib/aws/waiters/errors.rb +30 -0
  27. data/lib/aws/waiters/null_provider.rb +12 -0
  28. data/lib/aws/waiters/provider.rb +54 -0
  29. data/lib/aws/waiters/waiter.rb +194 -0
  30. data/lib/aws/xml/default_list.rb +10 -0
  31. data/lib/aws/xml/parser.rb +6 -1
  32. data/lib/seahorse.rb +0 -2
  33. data/lib/seahorse/client/base.rb +45 -20
  34. data/lib/seahorse/client/handler_list.rb +7 -0
  35. data/lib/seahorse/client/param_converter.rb +2 -2
  36. data/lib/seahorse/client/plugins/restful_bindings.rb +1 -1
  37. data/lib/seahorse/client/request.rb +1 -1
  38. data/lib/seahorse/client/response.rb +0 -2
  39. data/lib/seahorse/model/shapes.rb +6 -2
  40. metadata +15 -11
  41. data/LICENSE.txt +0 -12
  42. data/README.md +0 -301
  43. data/lib/seahorse/client/plugins/api.rb +0 -11
@@ -9,7 +9,7 @@ module Aws
9
9
  def resolve
10
10
  providers.each do |method_name, options|
11
11
  credentials = send(method_name, options.merge(config: @config))
12
- return credentials if credentials.set?
12
+ return credentials if credentials && credentials.set?
13
13
  end
14
14
  nil
15
15
  end
@@ -50,6 +50,8 @@ module Aws
50
50
 
51
51
  def shared_credentials(options = {})
52
52
  SharedCredentials.new(profile_name: options[:config].profile)
53
+ rescue Errors::NoSuchProfileError
54
+ nil
53
55
  end
54
56
 
55
57
  def instance_profile_credentials(*args)
data/lib/aws/errors.rb CHANGED
@@ -34,10 +34,6 @@ module Aws
34
34
  # This error indicates a checksum failed.
35
35
  class ChecksumError < RuntimeError; end
36
36
 
37
- # Raised when a {Service} is constructed an no suitable API
38
- # version is found based on configuration.
39
- class NoSuchApiVersionError < RuntimeError; end
40
-
41
37
  # Raised when a {Service} is constructed and the specified shared
42
38
  # credentials profile does not exist.
43
39
  class NoSuchProfileError < RuntimeError; end
@@ -80,9 +76,7 @@ module Aws
80
76
  #
81
77
  # @api private
82
78
  def error_class(error_code)
83
- constant = error_code.to_s
84
- constant = constant.gsub(/http:\/\/.*$/, '') # remove http namespaces
85
- constant = constant.gsub(/[^a-zA-Z0-9]/, '').to_sym
79
+ constant = error_class_constant(error_code)
86
80
  if error_const_set?(constant)
87
81
  const_get(constant)
88
82
  else
@@ -92,6 +86,21 @@ module Aws
92
86
 
93
87
  private
94
88
 
89
+ # Convert an error code to an error class name/constant.
90
+ # This requires filtering non-safe characters from the constant
91
+ # name and ensuring it begins with an uppercase letter.
92
+ # @param [String] error_code
93
+ # @return [Symbol] Returns a symbolized constant name for the given
94
+ # `error_code`.
95
+ def error_class_constant(error_code)
96
+ constant = error_code.to_s
97
+ constant = constant.gsub(/https?:.*$/, '')
98
+ constant = constant.gsub(/[^a-zA-Z0-9]/, '')
99
+ constant = 'Error' + constant unless constant.match(/^[a-z]/i)
100
+ constant = constant[0].upcase + constant[1..-1]
101
+ constant.to_sym
102
+ end
103
+
95
104
  def set_error_constant(constant)
96
105
  @const_set_mutex.synchronize do
97
106
  # Ensure the const was not defined while blocked by the mutex
@@ -101,7 +101,7 @@ module Aws
101
101
  # @return [Hash] Returns the hash of request parameters for the
102
102
  # next page, merging any given params.
103
103
  def next_page_params(params)
104
- context.params.merge(@pager.next_tokens(self).merge(params))
104
+ context[:original_params].merge(@pager.next_tokens(self).merge(params))
105
105
  end
106
106
 
107
107
  # Raised when calling {PageableResponse#next_page} on a pager that
@@ -11,6 +11,11 @@ module Aws
11
11
  #
12
12
  class CSDConditionalSigning < Seahorse::Client::Plugin
13
13
 
14
+ # Adding region as an option to avoid an issue when `Aws.config[:region]`
15
+ # is populated and the global configuration plugin merges options onto
16
+ # this client.
17
+ option(:region)
18
+
14
19
  option(:sigv4_region) do |cfg|
15
20
  # extract the region name from the cloud search domain endpoint
16
21
  if cfg.endpoint
@@ -6,13 +6,19 @@ module Aws
6
6
  class Handler < Seahorse::Client::Handler
7
7
 
8
8
  def call(context)
9
- pager = context.client.class.paginators.pager(context.operation.name)
10
- PageableResponse.new(@handler.call(context), pager)
9
+ context[:original_params] = context.params
10
+ PageableResponse.new(@handler.call(context), pager(context))
11
+ end
12
+
13
+ private
14
+
15
+ def pager(context)
16
+ context.client.class.paginators.pager(context.operation.name)
11
17
  end
12
18
 
13
19
  end
14
20
 
15
- handler(Handler)
21
+ handler(Handler, step: :initialize, priority: 90)
16
22
 
17
23
  end
18
24
  end
@@ -46,8 +46,8 @@ module Aws
46
46
  decode(:next_marker, data)
47
47
  decode(:prefix, data)
48
48
  decode(:delimiter, data)
49
- data.contents.each { |o| decode(:key, o) }
50
- data.common_prefixes.each { |o| decode(:prefix, o) }
49
+ data.contents.each { |o| decode(:key, o) } if data.contents
50
+ data.common_prefixes.each { |o| decode(:prefix, o) } if data.common_prefixes
51
51
  end
52
52
 
53
53
  def decode_list_object_versions_keys(data)
@@ -55,9 +55,9 @@ module Aws
55
55
  decode(:next_key_marker, data)
56
56
  decode(:prefix, data)
57
57
  decode(:delimiter, data)
58
- data.versions.each { |o| decode(:key, o) }
59
- data.delete_markers.each { |o| decode(:key, o) }
60
- data.common_prefixes.each { |o| decode(:prefix, o) }
58
+ data.versions.each { |o| decode(:key, o) } if data.versions
59
+ data.delete_markers.each { |o| decode(:key, o) } if data.delete_markers
60
+ data.common_prefixes.each { |o| decode(:prefix, o) } if data.common_prefixes
61
61
  end
62
62
 
63
63
  def decode_list_multipart_uploads_keys(data)
@@ -65,8 +65,8 @@ module Aws
65
65
  decode(:next_key_marker, data)
66
66
  decode(:prefix, data)
67
67
  decode(:delimiter, data)
68
- data.uploads.each { |o| decode(:key, o) }
69
- data.common_prefixes.each { |o| decode(:prefix, o) }
68
+ data.uploads.each { |o| decode(:key, o) } if data.uploads
69
+ data.common_prefixes.each { |o| decode(:prefix, o) } if data.common_prefixes
70
70
  end
71
71
 
72
72
  def decode(member, struct)
@@ -33,9 +33,8 @@ module Aws
33
33
 
34
34
  def parse_xml(context)
35
35
  if rules = context.operation.output
36
- rules = apply_wrapper(rules)
37
- data = Xml::Parser.new(rules).parse(xml(context))
38
- remove_wrapper(data, context)
36
+ data = Xml::Parser.new(apply_wrapper(rules)).parse(xml(context))
37
+ remove_wrapper(data, context, rules)
39
38
  else
40
39
  EmptyStructure.new
41
40
  end
@@ -59,10 +58,10 @@ module Aws
59
58
  }, shape_map: shape.shape_map)
60
59
  end
61
60
 
62
- def remove_wrapper(data, context)
61
+ def remove_wrapper(data, context, rules)
63
62
  if context.operation.output.metadata('resultWrapper')
64
63
  context[:request_id] = data.response_metadata.request_id
65
- data[data.members.first]
64
+ data[data.members.first] || Structure.new(rules.member_names)
66
65
  else
67
66
  data
68
67
  end
data/lib/aws/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Aws
2
- VERSION = '2.0.0.rc15'
2
+ VERSION = '2.0.0.rc16'
3
3
  end
@@ -0,0 +1,30 @@
1
+ require 'jamespath'
2
+
3
+ module Aws
4
+ module Waiters
5
+ module Errors
6
+
7
+ # Raised when a waiter detects a condition where the waiter can never
8
+ # succeed.
9
+ class WaiterFailed < StandardError; end
10
+
11
+ # Raised when attempting to get a waiter by name and the waiter has not
12
+ # been defined.
13
+ class NoSuchWaiter < ArgumentError
14
+ def initialize(waiter_name, waiter_names)
15
+ msg = "no definition found for #{waiter_name.inspect}"
16
+ msg << "; valid waiter names are:"
17
+ waiter_names.sort.each.with_index do |name, n|
18
+ if n % 3 == 0
19
+ msg << "\n #{name.inspect}"
20
+ else
21
+ msg << ", #{name.inspect}"
22
+ end
23
+ end
24
+ super(msg)
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,12 @@
1
+ module Aws
2
+ module Waiters
3
+ # @api private
4
+ class NullProvider < Provider
5
+
6
+ def initialize
7
+ super('waiters' => {})
8
+ end
9
+
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,54 @@
1
+ require 'set'
2
+
3
+ module Aws
4
+ module Waiters
5
+ # @api private
6
+ class Provider
7
+
8
+ def initialize(definitions)
9
+ @waiter_names = Set.new
10
+ @definitions = definitions['waiters'].each.with_object({}) do |(k,v),h|
11
+ if k.match(/^__/)
12
+ h[k] = v
13
+ else
14
+ underscore(k).to_sym.tap do |name|
15
+ @waiter_names << name
16
+ h[name] = v
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ # @return [Array<Symbol>]
23
+ def waiter_names
24
+ @waiter_names.to_a
25
+ end
26
+
27
+ # @param [Symbol] waiter_name
28
+ # @return [Waiter]
29
+ # @raise [ArgumentError]
30
+ def waiter(waiter_name)
31
+ if @waiter_names.include?(waiter_name)
32
+ Waiter.new(resolve('extends' => waiter_name))
33
+ else
34
+ raise Errors::NoSuchWaiter.new(waiter_name, waiter_names)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def resolve(definition)
41
+ if extends = definition.delete('extends')
42
+ resolve(@definitions[extends].merge(definition))
43
+ else
44
+ (@definitions['__default__'] || {}).merge(definition)
45
+ end
46
+ end
47
+
48
+ def underscore(str)
49
+ str.gsub(/\w+/) { |part| Seahorse::Util.underscore(part) }
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,194 @@
1
+ require 'jamespath'
2
+
3
+ module Aws
4
+ module Waiters
5
+ class Waiter
6
+
7
+ # @api private
8
+ RAISE_HANDLER = Seahorse::Client::Plugins::RaiseResponseErrors::Handler
9
+
10
+ # @api private
11
+ def initialize(definition = {})
12
+ @definition = definition
13
+ @interval = definition['interval']
14
+ @max_attempts = definition['max_attempts']
15
+ @before_attempt = []
16
+ @before_wait = []
17
+ end
18
+
19
+ # Register a callback that is invoked before every polling attempt.
20
+ # Yields the number of attempts made so far.
21
+ #
22
+ # waiter.before_attempt do |attempts|
23
+ # puts "#{attempts} made, about to make attempt #{attempts + 1}"
24
+ # end
25
+ #
26
+ # Throwing `:success` or `:failure` from the given block will stop
27
+ # the waiter and return or raise. You can pass a custom message to the
28
+ # throw:
29
+ #
30
+ # # raises Aws::Waiters::Errors::WaiterFailed
31
+ # waiter.before_attempt do |attempts|
32
+ # throw :failure, 'custom-error-message'
33
+ # end
34
+ #
35
+ # # cause the waiter to stop polling and return
36
+ # waiter.before_attempt do |attempts|
37
+ # throw :success
38
+ # end
39
+ #
40
+ # @yieldparam [Integer] attempts The number of attempts made.
41
+ def before_attempt(&block)
42
+ @before_attempt << Proc.new
43
+ end
44
+
45
+ # Register a callback that is invoked after an attempt but before
46
+ # sleeping. Yields the number of attempts made and the previous response.
47
+ #
48
+ # waiter.before_wait do |attempts, response|
49
+ # puts "#{attempts} made"
50
+ # puts response.error.inspect
51
+ # puts response.data.inspect
52
+ # end
53
+ #
54
+ # Throwing `:success` or `:failure` from the given block will stop
55
+ # the waiter and return or raise. You can pass a custom message to the
56
+ # throw:
57
+ #
58
+ # # raises Aws::Waiters::Errors::WaiterFailed
59
+ # waiter.before_attempt do |attempts|
60
+ # throw :failure, 'custom-error-message'
61
+ # end
62
+ #
63
+ # # cause the waiter to stop polling and return
64
+ # waiter.before_attempt do |attempts|
65
+ # throw :success
66
+ # end
67
+ #
68
+ #
69
+ # @yieldparam [Integer] attempts The number of attempts already made.
70
+ # @yieldparam [Seahorse::Client::Response] response The response from
71
+ # the previous polling attempts.
72
+ def before_wait(&block)
73
+ @before_wait << Proc.new
74
+ end
75
+
76
+ # @return [Float]
77
+ attr_accessor :interval
78
+
79
+ # @return [Integer]
80
+ attr_accessor :max_attempts
81
+
82
+ # @param [Client] client
83
+ # @param [Hash] params
84
+ def wait(client, params)
85
+ attempts = 0
86
+ catch(:success) do
87
+ failure = catch(:failure) do
88
+ loop do
89
+ trigger_callbacks(@before_attempt, attempts)
90
+ attempts += 1
91
+ resp = send_request(client, params)
92
+ throw :success, resp if successful?(resp)
93
+ throw :failure if failure?(resp)
94
+ throw :failure, resp.error unless error_ignored?(resp)
95
+ throw :failure, too_many(attempts) if attempts == max_attempts
96
+ trigger_callbacks(@before_wait, attempts, resp)
97
+ sleep(interval)
98
+ end
99
+ end
100
+ failure = 'waiter failed' if failure.nil?
101
+ raise String === failure ? Errors::WaiterFailed.new(failure) : failure
102
+ end
103
+ end
104
+
105
+ private
106
+
107
+ def successful?(response)
108
+ acceptor_matches?(:success, response)
109
+ end
110
+
111
+ def failure?(response)
112
+ acceptor_matches?(:failure, response)
113
+ end
114
+
115
+ def trigger_callbacks(callbacks, *args)
116
+ callbacks.each { |block| block.call(*args) }
117
+ end
118
+
119
+ def send_request(client, params)
120
+ req = client.build_request(operation_name, params)
121
+ req.handlers.remove(RAISE_HANDLER)
122
+ req.send_request
123
+ end
124
+
125
+ def operation_name
126
+ underscore(@definition['operation']).to_sym
127
+ end
128
+
129
+ def acceptor_matches?(acceptor, resp)
130
+ case type(acceptor)
131
+ when 'output' then output_matches?(resp, values(acceptor), path(acceptor))
132
+ when 'error' then error_matches?(resp.error, values(acceptor))
133
+ end
134
+ end
135
+
136
+ def type(acceptor)
137
+ @definition["#{acceptor}_type"] || @definition['acceptor_type']
138
+ end
139
+
140
+ def path(acceptor)
141
+ underscore(@definition["#{acceptor}_path"] || @definition['acceptor_path'])
142
+ end
143
+
144
+ def values(acceptor)
145
+ values = @definition["#{acceptor}_value"] || @definition['acceptor_value']
146
+ values.is_a?(Array) ? values : [values]
147
+ end
148
+
149
+ def output_matches?(resp, value, path)
150
+ if resp.error
151
+ false
152
+ elsif path
153
+ output_value_matches?(value, Jamespath.search(path, resp.data))
154
+ else
155
+ true
156
+ end
157
+ end
158
+
159
+ def output_value_matches?(expected, results)
160
+ if results.is_a?(Array)
161
+ results.all? { |result| expected.include?(result) }
162
+ else
163
+ expected.include?(results)
164
+ end
165
+ end
166
+
167
+ def error_ignored?(resp)
168
+ if resp.error
169
+ error_matches?(resp.error, @definition['ignore_errors'] || [])
170
+ else
171
+ true
172
+ end
173
+ end
174
+
175
+ def error_matches?(error, errors)
176
+ if error
177
+ errors.any? { |pattern| error.class.name.match(/#{pattern}$/) }
178
+ else
179
+ false
180
+ end
181
+ end
182
+
183
+ def too_many(attempts)
184
+ "too many attempts made, #{attempts} attempts made without " +
185
+ "success or failure"
186
+ end
187
+
188
+ def underscore(str)
189
+ str.gsub(/\w+/) { |part| Seahorse::Util.underscore(part) } if str
190
+ end
191
+
192
+ end
193
+ end
194
+ end