aws-sdk-core 3.46.2 → 3.47.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 +4 -4
- data/VERSION +1 -1
- data/lib/aws-sdk-core.rb +1 -0
- data/lib/aws-sdk-core/async_client_stubs.rb +80 -0
- data/lib/aws-sdk-core/binary.rb +3 -0
- data/lib/aws-sdk-core/binary/decode_handler.rb +21 -1
- data/lib/aws-sdk-core/binary/encode_handler.rb +32 -0
- data/lib/aws-sdk-core/binary/event_builder.rb +122 -0
- data/lib/aws-sdk-core/binary/event_parser.rb +48 -18
- data/lib/aws-sdk-core/binary/event_stream_decoder.rb +5 -2
- data/lib/aws-sdk-core/binary/event_stream_encoder.rb +53 -0
- data/lib/aws-sdk-core/client_stubs.rb +1 -1
- data/lib/aws-sdk-core/errors.rb +4 -0
- data/lib/aws-sdk-core/event_emitter.rb +42 -0
- data/lib/aws-sdk-core/json/handler.rb +19 -1
- data/lib/aws-sdk-core/param_validator.rb +9 -1
- data/lib/aws-sdk-core/plugins/event_stream_configuration.rb +14 -0
- data/lib/aws-sdk-core/plugins/invocation_id.rb +33 -0
- data/lib/aws-sdk-core/plugins/stub_responses.rb +19 -7
- data/lib/aws-sdk-core/stubbing/protocols/rest.rb +19 -0
- data/lib/aws-sdk-core/stubbing/stub_data.rb +1 -1
- data/lib/aws-sdk-sts.rb +1 -1
- data/lib/aws-sdk-sts/client.rb +1 -1
- data/lib/seahorse.rb +9 -0
- data/lib/seahorse/client/async_base.rb +50 -0
- data/lib/seahorse/client/async_response.rb +73 -0
- data/lib/seahorse/client/base.rb +1 -1
- data/lib/seahorse/client/h2/connection.rb +242 -0
- data/lib/seahorse/client/h2/handler.rb +149 -0
- data/lib/seahorse/client/http/async_response.rb +42 -0
- data/lib/seahorse/client/http/response.rb +10 -5
- data/lib/seahorse/client/networking_error.rb +28 -0
- data/lib/seahorse/client/plugins/h2.rb +64 -0
- data/lib/seahorse/model/api.rb +4 -0
- data/lib/seahorse/model/operation.rb +4 -0
- metadata +35 -4
@@ -291,7 +291,7 @@ module Aws
|
|
291
291
|
def data_to_http_resp(operation_name, data)
|
292
292
|
api = config.api
|
293
293
|
operation = api.operation(operation_name)
|
294
|
-
ParamValidator.
|
294
|
+
ParamValidator.new(operation.output, input: false).validate!(data)
|
295
295
|
protocol_helper.stub_data(api, operation, data)
|
296
296
|
end
|
297
297
|
|
data/lib/aws-sdk-core/errors.rb
CHANGED
@@ -62,6 +62,10 @@ module Aws
|
|
62
62
|
# a raw event message
|
63
63
|
class EventStreamParserError < RuntimeError; end
|
64
64
|
|
65
|
+
# Raise when EventStream Builder failed to build
|
66
|
+
# an event message with parameters provided
|
67
|
+
class EventStreamBuilderError < RuntimeError; end
|
68
|
+
|
65
69
|
# Error event in an event stream which has event_type :error
|
66
70
|
# error code and error message can be retrieved when available.
|
67
71
|
#
|
@@ -3,8 +3,18 @@ module Aws
|
|
3
3
|
|
4
4
|
def initialize
|
5
5
|
@listeners = {}
|
6
|
+
@validate_event = true
|
7
|
+
@buffer = Queue.new
|
6
8
|
end
|
7
9
|
|
10
|
+
attr_accessor :stream
|
11
|
+
|
12
|
+
attr_accessor :encoder
|
13
|
+
|
14
|
+
attr_accessor :validate_event
|
15
|
+
|
16
|
+
attr_reader :buffer
|
17
|
+
|
8
18
|
def on(type, callback)
|
9
19
|
(@listeners[type] ||= []) << callback
|
10
20
|
end
|
@@ -16,5 +26,37 @@ module Aws
|
|
16
26
|
end
|
17
27
|
end
|
18
28
|
|
29
|
+
def emit(type, params)
|
30
|
+
@buffer << Proc.new do
|
31
|
+
if @validate_event && type != :end_stream
|
32
|
+
Aws::ParamValidator.validate!(
|
33
|
+
@encoder.rules.shape.member(type), params)
|
34
|
+
end
|
35
|
+
@stream.data(
|
36
|
+
@encoder.encode(type, params),
|
37
|
+
end_stream: type == :end_stream
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
class Queue
|
45
|
+
|
46
|
+
def initialize(procs = [])
|
47
|
+
@procs = procs
|
48
|
+
@mutex = Mutex.new
|
49
|
+
end
|
50
|
+
|
51
|
+
def <<(callback)
|
52
|
+
@mutex.synchronize { @procs << callback }
|
53
|
+
end
|
54
|
+
|
55
|
+
def shift
|
56
|
+
@mutex.synchronize { @procs.shift }
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
19
61
|
end
|
20
62
|
end
|
@@ -40,7 +40,25 @@ module Aws
|
|
40
40
|
Json.load(context.http_response.body_contents)
|
41
41
|
elsif rules = context.operation.output
|
42
42
|
json = context.http_response.body_contents
|
43
|
-
|
43
|
+
if json.is_a?(Array)
|
44
|
+
# an array of emitted events
|
45
|
+
if json[0].respond_to?(:response)
|
46
|
+
# initial response exists
|
47
|
+
# it must be the first event arrived
|
48
|
+
resp_struct = json.shift.response
|
49
|
+
else
|
50
|
+
resp_struct = context.operation.output.shape.struct_class.new
|
51
|
+
end
|
52
|
+
|
53
|
+
rules.shape.members.each do |name, ref|
|
54
|
+
if ref.eventstream
|
55
|
+
resp_struct.send("#{name}=", json.to_enum)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
resp_struct
|
59
|
+
else
|
60
|
+
Parser.new(rules).parse(json == '' ? '{}' : json)
|
61
|
+
end
|
44
62
|
else
|
45
63
|
EmptyStructure.new
|
46
64
|
end
|
@@ -22,6 +22,7 @@ module Aws
|
|
22
22
|
ShapeRef.new(shape: shape)
|
23
23
|
end
|
24
24
|
@validate_required = options[:validate_required] != false
|
25
|
+
@input = options[:input].nil? ? true : !!options[:input]
|
25
26
|
end
|
26
27
|
|
27
28
|
# @param [Hash] params
|
@@ -39,6 +40,7 @@ module Aws
|
|
39
40
|
return unless correct_type?(ref, values, errors, context)
|
40
41
|
|
41
42
|
if ref.eventstream
|
43
|
+
# input eventstream is provided from event signals
|
42
44
|
values.each do |value|
|
43
45
|
# each event is structure type
|
44
46
|
case value[:message_type]
|
@@ -58,7 +60,8 @@ module Aws
|
|
58
60
|
# ensure required members are present
|
59
61
|
if @validate_required
|
60
62
|
shape.required.each do |member_name|
|
61
|
-
|
63
|
+
input_eventstream = ref.shape.member(member_name).eventstream && @input
|
64
|
+
if values[member_name].nil? && !input_eventstream
|
62
65
|
param = "#{context}[#{member_name.inspect}]"
|
63
66
|
errors << "missing required parameter #{param}"
|
64
67
|
end
|
@@ -147,6 +150,11 @@ module Aws
|
|
147
150
|
end
|
148
151
|
|
149
152
|
def correct_type?(ref, value, errors, context)
|
153
|
+
if ref.eventstream && @input
|
154
|
+
errors << "instead of providing value directly for eventstreams at input,"\
|
155
|
+
" expected to use #signal events per stream"
|
156
|
+
return false
|
157
|
+
end
|
150
158
|
case value
|
151
159
|
when Hash then true
|
152
160
|
when ref.shape.struct_class then true
|
@@ -10,6 +10,20 @@ module Aws
|
|
10
10
|
When an EventStream or Proc object is provided, it will be used as callback for each chunk of event stream response received along the way.
|
11
11
|
DOCS
|
12
12
|
|
13
|
+
option(:input_event_stream_handler,
|
14
|
+
default: nil,
|
15
|
+
doc_type: 'Proc',
|
16
|
+
docstring: <<-DOCS)
|
17
|
+
When an EventStream or Proc object is provided, it can be used for sending events for the event stream.
|
18
|
+
DOCS
|
19
|
+
|
20
|
+
option(:output_event_stream_handler,
|
21
|
+
default: nil,
|
22
|
+
doc_type: 'Proc',
|
23
|
+
docstring: <<-DOCS)
|
24
|
+
When an EventStream or Proc object is provided, it will be used as callback for each chunk of event stream response received along the way.
|
25
|
+
DOCS
|
26
|
+
|
13
27
|
end
|
14
28
|
|
15
29
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Aws
|
4
|
+
module Plugins
|
5
|
+
|
6
|
+
# @api private
|
7
|
+
class InvocationId < Seahorse::Client::Plugin
|
8
|
+
|
9
|
+
# @api private
|
10
|
+
class Handler < Seahorse::Client::Handler
|
11
|
+
|
12
|
+
def call(context)
|
13
|
+
apply_invocation_id(context)
|
14
|
+
@handler.call(context)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def apply_invocation_id(context)
|
20
|
+
context.http_request.headers['amz-sdk-invocation-id'] = SecureRandom.uuid
|
21
|
+
if context[:input_event_emitter]
|
22
|
+
# only used for eventstreaming at input
|
23
|
+
context.http_request.headers['x-amz-content-sha256'] = 'STREAMING-AWS4-HMAC-SHA256-EVENTS'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
handler(Handler, step: :initialize)
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -45,15 +45,18 @@ requests are made, and retries are disabled.
|
|
45
45
|
def call(context)
|
46
46
|
stub = context.client.next_stub(context)
|
47
47
|
resp = Seahorse::Client::Response.new(context: context)
|
48
|
-
|
49
|
-
resp
|
48
|
+
async_mode = context.client.is_a? Seahorse::Client::AsyncBase
|
49
|
+
apply_stub(stub, resp, async_mode)
|
50
|
+
|
51
|
+
async_mode ? Seahorse::Client::AsyncResponse.new(
|
52
|
+
context: context, stream: context[:input_event_stream_handler].event_emitter.stream, sync_queue: Queue.new) : resp
|
50
53
|
end
|
51
54
|
|
52
|
-
def apply_stub(stub, response)
|
55
|
+
def apply_stub(stub, response, async_mode = false)
|
53
56
|
http_resp = response.context.http_response
|
54
57
|
case
|
55
58
|
when stub[:error] then signal_error(stub[:error], http_resp)
|
56
|
-
when stub[:http] then signal_http(stub[:http], http_resp)
|
59
|
+
when stub[:http] then signal_http(stub[:http], http_resp, async_mode)
|
57
60
|
when stub[:data] then response.data = stub[:data]
|
58
61
|
end
|
59
62
|
end
|
@@ -67,9 +70,18 @@ requests are made, and retries are disabled.
|
|
67
70
|
end
|
68
71
|
|
69
72
|
# @param [Seahorse::Client::Http::Response] stub
|
70
|
-
# @param [Seahorse::Client::Http::Response] http_resp
|
71
|
-
|
72
|
-
|
73
|
+
# @param [Seahorse::Client::Http::Response | Seahorse::Client::Http::AsyncResponse] http_resp
|
74
|
+
# @param [Boolean] async_mode
|
75
|
+
def signal_http(stub, http_resp, async_mode = false)
|
76
|
+
if async_mode
|
77
|
+
h2_headers = stub.headers.to_h.inject([]) do |arr, (k, v)|
|
78
|
+
arr << [k, v]
|
79
|
+
end
|
80
|
+
h2_headers << [":status", stub.status_code]
|
81
|
+
http_resp.signal_headers(h2_headers)
|
82
|
+
else
|
83
|
+
http_resp.signal_headers(stub.status_code, stub.headers.to_h)
|
84
|
+
end
|
73
85
|
while chunk = stub.body.read(1024 * 1024)
|
74
86
|
http_resp.signal_data(chunk)
|
75
87
|
end
|
@@ -118,6 +118,25 @@ module Aws
|
|
118
118
|
|
119
119
|
def encode_event(opts, rules, event_data, builder)
|
120
120
|
event_ref = rules.shape.member(event_data.delete(:event_type))
|
121
|
+
explicit_payload = false
|
122
|
+
implicit_payload_members = {}
|
123
|
+
event_ref.shape.members.each do |name, ref|
|
124
|
+
if ref.eventpayload
|
125
|
+
explicit_payload = true
|
126
|
+
else
|
127
|
+
implicit_payload_members[name] = ref
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
if !explicit_payload && !implicit_payload_members.empty?
|
132
|
+
unless implicit_payload_members.size > 1
|
133
|
+
m_name, _ = implicit_payload_members.first
|
134
|
+
value = {}
|
135
|
+
value[m_name] = event_data[m_name]
|
136
|
+
opts[:payload] = StringIO.new(builder.new(event_ref).serialize(value))
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
121
140
|
event_data.each do |k, v|
|
122
141
|
member_ref = event_ref.shape.member(k)
|
123
142
|
if member_ref.eventheader
|
@@ -30,7 +30,7 @@ module Aws
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def apply_data(data, stub)
|
33
|
-
ParamValidator.new(@rules, validate_required:false).validate!(data)
|
33
|
+
ParamValidator.new(@rules, validate_required: false, input: false).validate!(data)
|
34
34
|
DataApplicator.new(@rules).apply_data(data, stub)
|
35
35
|
end
|
36
36
|
end
|
data/lib/aws-sdk-sts.rb
CHANGED
data/lib/aws-sdk-sts/client.rb
CHANGED
data/lib/seahorse.rb
CHANGED
@@ -15,12 +15,14 @@ require_relative 'seahorse/client/plugin_list'
|
|
15
15
|
require_relative 'seahorse/client/request'
|
16
16
|
require_relative 'seahorse/client/request_context'
|
17
17
|
require_relative 'seahorse/client/response'
|
18
|
+
require_relative 'seahorse/client/async_response'
|
18
19
|
|
19
20
|
# client http
|
20
21
|
|
21
22
|
require_relative 'seahorse/client/http/headers'
|
22
23
|
require_relative 'seahorse/client/http/request'
|
23
24
|
require_relative 'seahorse/client/http/response'
|
25
|
+
require_relative 'seahorse/client/http/async_response'
|
24
26
|
|
25
27
|
# client logging
|
26
28
|
|
@@ -32,12 +34,18 @@ require_relative 'seahorse/client/logging/formatter'
|
|
32
34
|
require_relative 'seahorse/client/net_http/connection_pool'
|
33
35
|
require_relative 'seahorse/client/net_http/handler'
|
34
36
|
|
37
|
+
# http2 handler
|
38
|
+
|
39
|
+
require_relative 'seahorse/client/h2/connection'
|
40
|
+
require_relative 'seahorse/client/h2/handler'
|
41
|
+
|
35
42
|
# plugins
|
36
43
|
|
37
44
|
require_relative 'seahorse/client/plugins/content_length'
|
38
45
|
require_relative 'seahorse/client/plugins/endpoint'
|
39
46
|
require_relative 'seahorse/client/plugins/logging'
|
40
47
|
require_relative 'seahorse/client/plugins/net_http'
|
48
|
+
require_relative 'seahorse/client/plugins/h2'
|
41
49
|
require_relative 'seahorse/client/plugins/raise_response_errors'
|
42
50
|
require_relative 'seahorse/client/plugins/response_target'
|
43
51
|
|
@@ -49,3 +57,4 @@ require_relative 'seahorse/model/authorizer'
|
|
49
57
|
require_relative 'seahorse/model/shapes'
|
50
58
|
|
51
59
|
require_relative 'seahorse/client/base'
|
60
|
+
require_relative 'seahorse/client/async_base'
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Seahorse
|
2
|
+
module Client
|
3
|
+
class AsyncBase < Seahorse::Client::Base
|
4
|
+
|
5
|
+
# default H2 plugins
|
6
|
+
@plugins = PluginList.new([
|
7
|
+
Plugins::Endpoint,
|
8
|
+
Plugins::H2,
|
9
|
+
Plugins::ResponseTarget
|
10
|
+
])
|
11
|
+
|
12
|
+
def initialize(plugins, options)
|
13
|
+
super
|
14
|
+
@connection = H2::Connection.new(options)
|
15
|
+
@options = options
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return [H2::Connection]
|
19
|
+
attr_reader :connection
|
20
|
+
|
21
|
+
# @return [Array<Symbol>] Returns a list of valid async request
|
22
|
+
# operation names.
|
23
|
+
def operation_names
|
24
|
+
self.class.api.async_operation_names
|
25
|
+
end
|
26
|
+
|
27
|
+
# Closes the underlying HTTP2 Connection for the client
|
28
|
+
# @return [Symbol] Returns the status of the connection (:closed)
|
29
|
+
def close_connection
|
30
|
+
@connection.close!
|
31
|
+
end
|
32
|
+
|
33
|
+
# Creates a new HTTP2 Connection for the client
|
34
|
+
# @return [Seahorse::Client::H2::Connection]
|
35
|
+
def new_connection
|
36
|
+
if @connection.closed?
|
37
|
+
@connection = H2::Connection.new(@options)
|
38
|
+
else
|
39
|
+
@connection
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def connection_errors
|
44
|
+
@connection.errors
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Seahorse
|
2
|
+
module Client
|
3
|
+
class AsyncResponse
|
4
|
+
|
5
|
+
def initialize(options = {})
|
6
|
+
@response = Response.new(context: options[:context])
|
7
|
+
@stream = options[:stream]
|
8
|
+
@stream_mutex = options[:stream_mutex]
|
9
|
+
@close_condition = options[:close_condition]
|
10
|
+
@sync_queue = options[:sync_queue]
|
11
|
+
end
|
12
|
+
|
13
|
+
def context
|
14
|
+
@response.context
|
15
|
+
end
|
16
|
+
|
17
|
+
def error
|
18
|
+
@response.error
|
19
|
+
end
|
20
|
+
|
21
|
+
def on(range, &block)
|
22
|
+
@response.on(range, &block)
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def on_complete(&block)
|
27
|
+
@response.on_complete(&block)
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def wait
|
32
|
+
if error && context.config.raise_response_errors
|
33
|
+
raise error
|
34
|
+
elsif @stream
|
35
|
+
# have a sync signal that #signal can be blocked on
|
36
|
+
# else, if #signal is called before #wait
|
37
|
+
# will be waiting for a signal never arrives
|
38
|
+
@sync_queue << "sync_signal"
|
39
|
+
# now #signal is unlocked for
|
40
|
+
# signaling close condition when ready
|
41
|
+
@stream_mutex.synchronize {
|
42
|
+
@close_condition.wait(@stream_mutex)
|
43
|
+
}
|
44
|
+
_kill_input_thread
|
45
|
+
@response
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def join!
|
50
|
+
if error && context.config.raise_response_errors
|
51
|
+
raise error
|
52
|
+
elsif @stream
|
53
|
+
# close callback is waiting
|
54
|
+
# for the "sync_signal"
|
55
|
+
@sync_queue << "sync_signal"
|
56
|
+
@stream.close
|
57
|
+
_kill_input_thread
|
58
|
+
@response
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def _kill_input_thread
|
65
|
+
if thread = context[:input_signal_thread]
|
66
|
+
Thread.kill(thread)
|
67
|
+
end
|
68
|
+
nil
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|