aws-sdk-core 2.0.18 → 2.0.19
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/apis/CloudFormation.resources.json +55 -20
- data/apis/CloudFront.waiters.json +35 -17
- data/apis/DynamoDB.waiters.json +27 -17
- data/apis/EC2.api.json +5 -0
- data/apis/EC2.resources.json +449 -319
- data/apis/EC2.waiters.json +389 -139
- data/apis/{EMR.waiters2.json → EMR.waiters.json} +0 -0
- data/apis/ElasticTranscoder.api.json +34 -3
- data/apis/ElasticTranscoder.waiters.json +22 -8
- data/apis/Glacier.resources.json +215 -117
- data/apis/Glacier.waiters.json +31 -15
- data/apis/IAM.resources.json +380 -169
- data/apis/{Kinesis.waiters2.json → Kinesis.waiters.json} +0 -0
- data/apis/OpsWorks.resources.json +51 -17
- data/apis/RDS.waiters.json +87 -26
- data/apis/Redshift.waiters.json +54 -29
- data/apis/S3.resources.json +404 -143
- data/apis/S3.waiters.json +47 -16
- data/apis/SES.waiters.json +11 -7
- data/apis/SNS.resources.json +67 -33
- data/apis/SQS.resources.json +57 -30
- data/lib/aws-sdk-core.rb +1 -0
- data/lib/aws-sdk-core/api/documenter.rb +4 -3
- data/lib/aws-sdk-core/api/service_customizations.rb +0 -6
- data/lib/aws-sdk-core/client_waiters.rb +65 -50
- data/lib/aws-sdk-core/emr.rb +1 -0
- data/lib/aws-sdk-core/errors.rb +4 -0
- data/lib/aws-sdk-core/instance_profile_credentials.rb +1 -0
- data/lib/aws-sdk-core/kinesis.rb +1 -0
- data/lib/aws-sdk-core/paging/pager.rb +5 -1
- data/lib/aws-sdk-core/refreshing_credentials.rb +2 -0
- data/lib/aws-sdk-core/version.rb +1 -1
- data/lib/aws-sdk-core/waiters/errors.rb +50 -12
- data/lib/aws-sdk-core/waiters/poller.rb +105 -0
- data/lib/aws-sdk-core/waiters/provider.rb +11 -30
- data/lib/aws-sdk-core/waiters/waiter.rb +42 -102
- metadata +5 -12
- data/apis/CloudFront.waiters2.json +0 -47
- data/apis/DynamoDB.waiters2.json +0 -35
- data/apis/EC2.waiters2.json +0 -341
- data/apis/ElasticTranscoder.waiters2.json +0 -30
- data/apis/RDS.waiters2.json +0 -97
- data/apis/Redshift.waiters2.json +0 -97
- data/apis/S3.waiters2.json +0 -63
- data/apis/SES.waiters2.json +0 -18
data/lib/aws-sdk-core.rb
CHANGED
@@ -182,6 +182,7 @@ module Aws
|
|
182
182
|
end
|
183
183
|
|
184
184
|
module Waiters
|
185
|
+
autoload :Poller, 'aws-sdk-core/waiters/poller'
|
185
186
|
autoload :Errors, 'aws-sdk-core/waiters/errors'
|
186
187
|
autoload :NullProvider, 'aws-sdk-core/waiters/null_provider'
|
187
188
|
autoload :Provider, 'aws-sdk-core/waiters/provider'
|
@@ -175,15 +175,16 @@ Constructs an API client.
|
|
175
175
|
m.docstring = YARD::Registry['Aws::ClientWaiters#wait_until'].docstring
|
176
176
|
|
177
177
|
waiters = @client_class.waiters.waiter_names.sort.inject('') do |w,name|
|
178
|
-
|
179
|
-
|
178
|
+
waiter = @client_class.waiters.waiter(name)
|
179
|
+
operation = waiter.poller.operation_name
|
180
|
+
w << "<tr><td><tt>:#{name}</tt></td><td>{##{operation}}</td><td>#{waiter.delay}</td><td>#{waiter.max_attempts}</td></tr>"
|
180
181
|
end
|
181
182
|
docstring = <<-DOCSTRING
|
182
183
|
Returns the list of supported waiters. The following table lists the supported
|
183
184
|
waiters and the client method they call:
|
184
185
|
<table>
|
185
186
|
<thead>
|
186
|
-
<tr><th>Waiter Name</th><th>Client Method</th></tr>
|
187
|
+
<tr><th>Waiter Name</th><th>Client Method</th><th>Delay</th><th>Max Attempts</th></tr>
|
187
188
|
</thead>
|
188
189
|
<tbody>
|
189
190
|
#{waiters}
|
@@ -114,12 +114,6 @@ module Aws
|
|
114
114
|
# parsing of the output
|
115
115
|
client_class.api.operation(:get_bucket_location).
|
116
116
|
instance_variable_set("@output", nil)
|
117
|
-
|
118
|
-
defs = client_class.waiters.instance_variable_get("@definitions")
|
119
|
-
defs[:bucket_exists]['ignore_errors'] = ['NotFound']
|
120
|
-
defs[:object_exists]['ignore_errors'] = ['NotFound']
|
121
|
-
defs[:bucket_not_exists]['success_value'] = 'NotFound'
|
122
|
-
defs[:object_not_exists]['success_value'] = 'NotFound'
|
123
117
|
end
|
124
118
|
|
125
119
|
customize 'sqs' do
|
@@ -23,76 +23,91 @@ module Aws
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
#
|
27
|
-
#
|
28
|
-
# data or errors. Waiters each have a default duration max attempts
|
29
|
-
# which are configurable. Additionally, you can register callbacks
|
30
|
-
# and stop waiters by throwing `:success` or `:failure`.
|
31
|
-
#
|
32
|
-
# @example Basic usage
|
33
|
-
# client.wait_until(:waiter_name)
|
34
|
-
#
|
35
|
-
# @example Configuring interval and maximum attempts
|
36
|
-
# client.wait_until(:waiter_name) do |w|
|
37
|
-
# w.interval = 10 # number of seconds to sleep between attempts
|
38
|
-
# w.max_attempts = 6 # maximum number of polling attempts
|
39
|
-
# end
|
26
|
+
# Waiters polls an API operation until a resource enters a desired
|
27
|
+
# state.
|
40
28
|
#
|
41
|
-
#
|
42
|
-
# begin
|
43
|
-
# client.wait_until(:waiter_name)
|
44
|
-
# rescue Aws::Waiters::Errors::WaiterFailed
|
45
|
-
# # gave up waiting
|
46
|
-
# end
|
29
|
+
# ## Basic Usage
|
47
30
|
#
|
48
|
-
#
|
49
|
-
#
|
31
|
+
# Waiters will poll until they are succesful, they fail by
|
32
|
+
# entering a terminal state, or until a maximum number of attempts
|
33
|
+
# are made.
|
50
34
|
#
|
51
|
-
#
|
52
|
-
#
|
53
|
-
#
|
54
|
-
#
|
35
|
+
# # polls in a loop, sleeping between attempts
|
36
|
+
# client.waiter_until(waiter_name, params)
|
37
|
+
#
|
38
|
+
# ## Configuration
|
55
39
|
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
40
|
+
# You can configure the maximum number of polling attempts, and the
|
41
|
+
# delay (in seconds) between each polling attempt. You configure
|
42
|
+
# waiters by passing a block to #{wait_until}:
|
43
|
+
#
|
44
|
+
# # poll for ~25 seconds
|
45
|
+
# client.wait_until(...) do |w|
|
46
|
+
# w.max_attempts = 5
|
47
|
+
# w.delay = 5
|
60
48
|
# end
|
61
|
-
# end
|
62
49
|
#
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
50
|
+
# ## Callbacks
|
51
|
+
#
|
52
|
+
# You can be notified before each polling attempt and before each
|
53
|
+
# delay. If you throw `:success` or `:failure` from these callbacks,
|
54
|
+
# it will terminate the waiter.
|
55
|
+
#
|
56
|
+
# started_at = Time.now
|
57
|
+
# client.wait_until(...) do |w|
|
58
|
+
#
|
59
|
+
# # disable max attempts
|
60
|
+
# w.max_attempts = nil
|
61
|
+
#
|
62
|
+
# # poll for 1 hour, instead of a number of attempts
|
63
|
+
# before_wait do |attempts, response|
|
64
|
+
# throw :failure if Time.now - started_at > 3600
|
65
|
+
# end
|
66
|
+
#
|
70
67
|
# end
|
68
|
+
#
|
69
|
+
# ## Handling Errors
|
70
|
+
#
|
71
|
+
# When a waiter is successful, it returns `true`. When a waiter
|
72
|
+
# fails, it raises an error. **All errors raised extend from
|
73
|
+
# {Aws::Waiters::Errors::WaiterFailed}**.
|
74
|
+
#
|
75
|
+
# begin
|
76
|
+
# client.wait_until(...)
|
77
|
+
# rescue Aws::Waiters::Errors::WaiterFailed
|
78
|
+
# # resource did not enter the desired state in time
|
71
79
|
# end
|
72
80
|
#
|
73
81
|
# @param [Symbol] waiter_name The name of the waiter. See {#waiter_names}
|
74
82
|
# for a full list of supported waiters.
|
83
|
+
#
|
75
84
|
# @param [Hash] params Additional request parameters. See the {#waiter_names}
|
76
85
|
# for a list of supported waiters and what request they call. The
|
77
86
|
# called request determines the list of accepted parameters.
|
78
|
-
#
|
79
|
-
#
|
80
|
-
# then the 2nd argument to `#throw` is returned.
|
81
|
-
# @yieldparam [Waiters::Waiter] waiter Yields a {Waiters::Waiter Waiter}
|
87
|
+
#
|
88
|
+
# @yieldparam [Waiters::Waiter] waiter Yields a {Waiters::Waiter Waiter}
|
82
89
|
# object that can be configured prior to waiting.
|
83
|
-
# @raise [Waiters::Errors::NoSuchWaiter] Raised when the named waiter
|
84
|
-
# is not defined.
|
85
|
-
# @raise [Waiters::Errors::WaiterFailed] Raised when one of the
|
86
|
-
# following conditions is met:
|
87
90
|
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
+
# @raise [Errors::FailureStateError] Raised when the waiter terminates
|
92
|
+
# because the waiter has entered a state that it will not transition
|
93
|
+
# out of, preventing success.
|
94
|
+
#
|
95
|
+
# @raise [Errors::TooManyAttemptsError] Raised when the configured
|
96
|
+
# maximum number of attempts have been made, and the waiter is not
|
97
|
+
# yet successful.
|
98
|
+
#
|
99
|
+
# @raise [Errors::UnexpectedError] Raised when an error is encounted
|
100
|
+
# while polling for a resource that is not expected.
|
101
|
+
#
|
102
|
+
# @raise [Errors::NoSuchWaiterError] Raised when you request to wait
|
103
|
+
# for an unknown state.
|
104
|
+
#
|
105
|
+
# @return [Boolean] Returns `true` if the waiter was successful.
|
91
106
|
#
|
92
107
|
def wait_until(waiter_name, params = {}, &block)
|
93
108
|
waiter = self.class.waiters.waiter(waiter_name)
|
94
109
|
yield(waiter) if block_given?
|
95
|
-
waiter.wait(self, params)
|
110
|
+
waiter.wait(client:self, params:params)
|
96
111
|
end
|
97
112
|
|
98
113
|
# Returns the list of supported waiters.
|
data/lib/aws-sdk-core/emr.rb
CHANGED
data/lib/aws-sdk-core/errors.rb
CHANGED
@@ -14,10 +14,14 @@ module Aws
|
|
14
14
|
# @param [Seahorse::Client::RequestContext] context
|
15
15
|
# @param [String] message
|
16
16
|
def initialize(context, message)
|
17
|
+
@code = self.class.code
|
17
18
|
@context = context
|
18
19
|
super(message)
|
19
20
|
end
|
20
21
|
|
22
|
+
# @return [String]
|
23
|
+
attr_reader :code
|
24
|
+
|
21
25
|
# @return [Seahorse::Client::RequestContext] The context of the request
|
22
26
|
# that triggered the remote service to return this error.
|
23
27
|
attr_reader :context
|
data/lib/aws-sdk-core/kinesis.rb
CHANGED
@@ -20,7 +20,7 @@ module Aws
|
|
20
20
|
def next_tokens(response)
|
21
21
|
@tokens.each.with_object({}) do |(source, target), next_tokens|
|
22
22
|
value = JMESPath.search(source, response.data)
|
23
|
-
next_tokens[target.to_sym] = value unless value
|
23
|
+
next_tokens[target.to_sym] = value unless empty_value?(value)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -51,6 +51,10 @@ module Aws
|
|
51
51
|
gsub(/\w+/) { |part| Seahorse::Util.underscore(part) }
|
52
52
|
end
|
53
53
|
|
54
|
+
def empty_value?(value)
|
55
|
+
value.nil? || value == [] || value == {}
|
56
|
+
end
|
57
|
+
|
54
58
|
end
|
55
59
|
end
|
56
60
|
end
|
data/lib/aws-sdk-core/version.rb
CHANGED
@@ -6,23 +6,61 @@ module Aws
|
|
6
6
|
# succeed.
|
7
7
|
class WaiterFailed < StandardError; end
|
8
8
|
|
9
|
+
class FailureStateError < WaiterFailed
|
10
|
+
|
11
|
+
MSG = "stopped waiting, encountered a failure state"
|
12
|
+
|
13
|
+
def initialize(response)
|
14
|
+
@response = response
|
15
|
+
super(MSG)
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [Seahorse::Client::Response] The response that matched
|
19
|
+
# the failure state.
|
20
|
+
attr_reader :response
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
class TooManyAttemptsError < WaiterFailed
|
25
|
+
|
26
|
+
MSG = "stopped waiting after %d attempts without success"
|
27
|
+
|
28
|
+
def initialize(attempts)
|
29
|
+
@attempts = attempts
|
30
|
+
super(MSG % [attempts])
|
31
|
+
end
|
32
|
+
|
33
|
+
# @return [Integer]
|
34
|
+
attr_reader :attempts
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
class UnexpectedError < WaiterFailed
|
39
|
+
|
40
|
+
MSG = "stopped waiting due to an unexpected error: %s"
|
41
|
+
|
42
|
+
def initialize(error)
|
43
|
+
@error = error
|
44
|
+
super(MSG % [error.message])
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Exception] The unexpected error.
|
48
|
+
attr_reader :error
|
49
|
+
|
50
|
+
end
|
51
|
+
|
9
52
|
# Raised when attempting to get a waiter by name and the waiter has not
|
10
53
|
# been defined.
|
11
|
-
class
|
54
|
+
class NoSuchWaiterError < ArgumentError
|
55
|
+
|
56
|
+
MSG = "no such waiter %s; valid waiter names are: %s"
|
57
|
+
|
12
58
|
def initialize(waiter_name, waiter_names)
|
13
|
-
|
14
|
-
|
15
|
-
waiter_names.sort.each.with_index do |name, n|
|
16
|
-
if n % 3 == 0
|
17
|
-
msg << "\n #{name.inspect}"
|
18
|
-
else
|
19
|
-
msg << ", #{name.inspect}"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
super(msg)
|
59
|
+
waiter_names = waiter_names.map(&:inspect).join(', ')
|
60
|
+
super(MSG % [waiter_name.inspect, waiter_names])
|
23
61
|
end
|
24
|
-
end
|
25
62
|
|
63
|
+
end
|
26
64
|
end
|
27
65
|
end
|
28
66
|
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module Aws
|
2
|
+
module Waiters
|
3
|
+
|
4
|
+
# Polls a single API operation inspecting the response data and/or error
|
5
|
+
# for states matching one of its acceptors.
|
6
|
+
# @api private
|
7
|
+
class Poller
|
8
|
+
|
9
|
+
# @api private
|
10
|
+
RAISE_HANDLER = Seahorse::Client::Plugins::RaiseResponseErrors::Handler
|
11
|
+
|
12
|
+
# @api private
|
13
|
+
def initialize(options = {})
|
14
|
+
@operation_name = underscore(options['operation']).to_sym
|
15
|
+
@acceptors = options['acceptors'] || []
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [Symbol]
|
19
|
+
attr_reader :operation_name
|
20
|
+
|
21
|
+
# Makes an API call, returning the resultant state and the response.
|
22
|
+
#
|
23
|
+
# * `:success` - A success state has been matched.
|
24
|
+
# * `:failure` - A terminate failure state has been matched.
|
25
|
+
# * `:retry` - The waiter may be retried.
|
26
|
+
# * `:error` - The waiter encountered an un-expected error.
|
27
|
+
#
|
28
|
+
# @example A trival (bad) example of a waiter that polls indefinetly.
|
29
|
+
#
|
30
|
+
# loop do
|
31
|
+
#
|
32
|
+
# state, resp = poller.call(client:client, params:{})
|
33
|
+
#
|
34
|
+
# case state
|
35
|
+
# when :success then return true
|
36
|
+
# when :failure then return false
|
37
|
+
# when :retry then next
|
38
|
+
# when :error then raise 'oops'
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# @option options [required,Client] :client
|
44
|
+
# @option options [required,Hash] :params
|
45
|
+
# @return [Array<Symbol,Response>]
|
46
|
+
def call(options = {})
|
47
|
+
response = send_request(options)
|
48
|
+
@acceptors.each do |acceptor|
|
49
|
+
if acceptor_matches?(acceptor, response)
|
50
|
+
return [acceptor['state'].to_sym, response]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
[response.error ? :error : :retry, response]
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def send_request(options)
|
59
|
+
req = options[:client].build_request(@operation_name, options[:params])
|
60
|
+
req.handlers.remove(RAISE_HANDLER)
|
61
|
+
req.send_request
|
62
|
+
end
|
63
|
+
|
64
|
+
def acceptor_matches?(acceptor, response)
|
65
|
+
send("matches_#{acceptor['matcher']}?", acceptor, response)
|
66
|
+
end
|
67
|
+
|
68
|
+
def matches_path?(acceptor, response)
|
69
|
+
JMESPath.search(path(acceptor), response.data) == acceptor['expected']
|
70
|
+
end
|
71
|
+
|
72
|
+
def matches_pathAll?(acceptor, response)
|
73
|
+
values = JMESPath.search(path(acceptor), response.data)
|
74
|
+
Array === values &&
|
75
|
+
values.count > 0 &&
|
76
|
+
values.all? { |value| value == acceptor['expected'] }
|
77
|
+
end
|
78
|
+
|
79
|
+
def matches_pathAny?(acceptor, response)
|
80
|
+
values = JMESPath.search(path(acceptor), response.data)
|
81
|
+
Array === values &&
|
82
|
+
values.count > 0 &&
|
83
|
+
values.any? { |value| value == acceptor['expected'] }
|
84
|
+
end
|
85
|
+
|
86
|
+
def matches_status?(acceptor, response)
|
87
|
+
response.context.http_response.status_code == acceptor['expected']
|
88
|
+
end
|
89
|
+
|
90
|
+
def matches_error?(acceptor, response)
|
91
|
+
Aws::Errors::ServiceError === response.error &&
|
92
|
+
response.error.code == acceptor['expected']
|
93
|
+
end
|
94
|
+
|
95
|
+
def path(acceptor)
|
96
|
+
acceptor['argument'].gsub(/\w+/) { |s| Seahorse::Util.underscore(s) }
|
97
|
+
end
|
98
|
+
|
99
|
+
def underscore(str)
|
100
|
+
Seahorse::Util.underscore(str)
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -1,54 +1,35 @@
|
|
1
|
-
require 'set'
|
2
|
-
|
3
1
|
module Aws
|
4
2
|
module Waiters
|
5
3
|
# @api private
|
6
4
|
class Provider
|
7
5
|
|
8
6
|
def initialize(definitions)
|
9
|
-
@
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
h[name] = v
|
17
|
-
end
|
18
|
-
end
|
7
|
+
@waiters = {}
|
8
|
+
definitions['waiters'].each do |waiter_name, definition|
|
9
|
+
@waiters[Seahorse::Util.underscore(waiter_name).to_sym] = {
|
10
|
+
poller: Poller.new(definition),
|
11
|
+
max_attempts: definition['maxAttempts'],
|
12
|
+
delay: definition['delay'],
|
13
|
+
}
|
19
14
|
end
|
20
15
|
end
|
21
16
|
|
22
17
|
# @return [Array<Symbol>]
|
23
18
|
def waiter_names
|
24
|
-
@
|
19
|
+
@waiters.keys
|
25
20
|
end
|
26
21
|
|
27
22
|
# @param [Symbol] waiter_name
|
28
23
|
# @return [Waiter]
|
29
24
|
# @raise [ArgumentError]
|
30
25
|
def waiter(waiter_name)
|
31
|
-
if @
|
32
|
-
Waiter.new(
|
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))
|
26
|
+
if @waiters.key?(waiter_name)
|
27
|
+
Waiter.new(@waiters[waiter_name])
|
43
28
|
else
|
44
|
-
|
29
|
+
raise Errors::NoSuchWaiterError.new(waiter_name, waiter_names)
|
45
30
|
end
|
46
31
|
end
|
47
32
|
|
48
|
-
def underscore(str)
|
49
|
-
str.gsub(/\w+/) { |part| Seahorse::Util.underscore(part) }
|
50
|
-
end
|
51
|
-
|
52
33
|
end
|
53
34
|
end
|
54
35
|
end
|