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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/aws-sdk-core.rb +1 -0
  4. data/lib/aws-sdk-core/async_client_stubs.rb +80 -0
  5. data/lib/aws-sdk-core/binary.rb +3 -0
  6. data/lib/aws-sdk-core/binary/decode_handler.rb +21 -1
  7. data/lib/aws-sdk-core/binary/encode_handler.rb +32 -0
  8. data/lib/aws-sdk-core/binary/event_builder.rb +122 -0
  9. data/lib/aws-sdk-core/binary/event_parser.rb +48 -18
  10. data/lib/aws-sdk-core/binary/event_stream_decoder.rb +5 -2
  11. data/lib/aws-sdk-core/binary/event_stream_encoder.rb +53 -0
  12. data/lib/aws-sdk-core/client_stubs.rb +1 -1
  13. data/lib/aws-sdk-core/errors.rb +4 -0
  14. data/lib/aws-sdk-core/event_emitter.rb +42 -0
  15. data/lib/aws-sdk-core/json/handler.rb +19 -1
  16. data/lib/aws-sdk-core/param_validator.rb +9 -1
  17. data/lib/aws-sdk-core/plugins/event_stream_configuration.rb +14 -0
  18. data/lib/aws-sdk-core/plugins/invocation_id.rb +33 -0
  19. data/lib/aws-sdk-core/plugins/stub_responses.rb +19 -7
  20. data/lib/aws-sdk-core/stubbing/protocols/rest.rb +19 -0
  21. data/lib/aws-sdk-core/stubbing/stub_data.rb +1 -1
  22. data/lib/aws-sdk-sts.rb +1 -1
  23. data/lib/aws-sdk-sts/client.rb +1 -1
  24. data/lib/seahorse.rb +9 -0
  25. data/lib/seahorse/client/async_base.rb +50 -0
  26. data/lib/seahorse/client/async_response.rb +73 -0
  27. data/lib/seahorse/client/base.rb +1 -1
  28. data/lib/seahorse/client/h2/connection.rb +242 -0
  29. data/lib/seahorse/client/h2/handler.rb +149 -0
  30. data/lib/seahorse/client/http/async_response.rb +42 -0
  31. data/lib/seahorse/client/http/response.rb +10 -5
  32. data/lib/seahorse/client/networking_error.rb +28 -0
  33. data/lib/seahorse/client/plugins/h2.rb +64 -0
  34. data/lib/seahorse/model/api.rb +4 -0
  35. data/lib/seahorse/model/operation.rb +4 -0
  36. metadata +35 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ea0675c1b3dd6a1df7b3d1633f52557acd31fe44
4
- data.tar.gz: b70038231fedd16ba86307a1ce71d962959dbc7b
3
+ metadata.gz: e240abd1c190c9f5b7b6dac9395342881be33c53
4
+ data.tar.gz: 6a08d6319fd1baef15af46a41edd756c8d23ed5a
5
5
  SHA512:
6
- metadata.gz: d806391d8741594c74e188e96bf511da0c9210e47e86ca8c8d386c1146dac14fafeed7fca216aa21a3ebe6ff029250ec024fd68776cb503e5f186576b1d3ac04
7
- data.tar.gz: c0a1a2a2c7f61c528cd68ed0fd0b29be6c5e13a0c054d76a5d072c76142afa4794ada5f0a3da71e09f0d4f92cbc37a7b8bc9faee35d37901438bba1165eac51a
6
+ metadata.gz: e8ed167ed3c41ae1e255235c7794abdb85cf60bc022c49c1dd30327d3ea1000a5a3c8f03e37dccd6a01778ae132ea365a4313e7f1e2e79e955b3e1c55f235a71
7
+ data.tar.gz: 421c2b9d17a58946a01a9181392af7da9e21158f9dc9b64d399ea13dfd299a1f74c5c16321098ed46f09241dd7a50019fbef89895e22f9ea9bca0b7764e11456
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.46.2
1
+ 3.47.0
@@ -19,6 +19,7 @@ require_relative 'aws-sdk-core/process_credentials'
19
19
  # client modules
20
20
 
21
21
  require_relative 'aws-sdk-core/client_stubs'
22
+ require_relative 'aws-sdk-core/async_client_stubs'
22
23
  require_relative 'aws-sdk-core/eager_loader'
23
24
  require_relative 'aws-sdk-core/errors'
24
25
  require_relative 'aws-sdk-core/pageable_response'
@@ -0,0 +1,80 @@
1
+ module Aws
2
+ module AsyncClientStubs
3
+
4
+ include Aws::ClientStubs
5
+
6
+ # @api private
7
+ def setup_stubbing
8
+ @stubs = {}
9
+ @stub_mutex = Mutex.new
10
+ if Hash === @config.stub_responses
11
+ @config.stub_responses.each do |operation_name, stubs|
12
+ apply_stubs(operation_name, Array === stubs ? stubs : [stubs])
13
+ end
14
+ end
15
+
16
+ # When a client is stubbed allow the user to access the requests made
17
+ @api_requests = []
18
+
19
+ # allow to access signaled events when client is stubbed
20
+ @send_events = []
21
+
22
+ requests = @api_requests
23
+ send_events = @send_events
24
+
25
+ self.handle do |context|
26
+ if input_stream = context[:input_event_stream_handler]
27
+ stub_stream = StubStream.new
28
+ stub_stream.send_events = send_events
29
+ input_stream.event_emitter.stream = stub_stream
30
+ input_stream.event_emitter.validate_event = context.config.validate_params
31
+ end
32
+ requests << {
33
+ operation_name: context.operation_name,
34
+ params: context.params,
35
+ context: context
36
+ }
37
+ @handler.call(context)
38
+ end
39
+ end
40
+
41
+ def send_events
42
+ if config.stub_responses
43
+ @send_events
44
+ else
45
+ msg = 'This method is only implemented for stubbed clients, and is '
46
+ msg << 'available when you enable stubbing in the constructor with `stub_responses: true`'
47
+ raise NotImplementedError.new(msg)
48
+ end
49
+ end
50
+
51
+ class StubStream
52
+
53
+ def initialize
54
+ @state = :open
55
+ end
56
+
57
+ attr_accessor :send_events
58
+
59
+ attr_reader :state
60
+
61
+ def data(bytes, options = {})
62
+ if options[:end_stream]
63
+ @state = :closed
64
+ else
65
+ decoder = Aws::EventStream::Decoder.new
66
+ event = decoder.decode_chunk(bytes).first
67
+ @send_events << decoder.decode_chunk(event.payload.read).first
68
+ end
69
+ end
70
+
71
+ def closed?
72
+ @state == :closed
73
+ end
74
+
75
+ def close
76
+ @state = :closed
77
+ end
78
+ end
79
+ end
80
+ end
@@ -1,3 +1,6 @@
1
1
  require_relative 'binary/decode_handler'
2
+ require_relative 'binary/encode_handler'
2
3
  require_relative 'binary/event_stream_decoder'
4
+ require_relative 'binary/event_stream_encoder'
5
+ require_relative 'binary/event_builder'
3
6
  require_relative 'binary/event_parser'
@@ -23,11 +23,31 @@ module Aws
23
23
 
24
24
  context.http_response.on_headers(200) do
25
25
  protocol = context.config.api.metadata['protocol']
26
+ output_handler = context[:output_event_stream_handler] || context[:event_stream_handler]
26
27
  context.http_response.body = EventStreamDecoder.new(
27
28
  protocol,
28
29
  rules,
30
+ context.operation.output,
31
+ context.operation.errors,
29
32
  context.http_response.body,
30
- context[:event_stream_handler])
33
+ output_handler)
34
+ if input_emitter = context[:input_event_emitter]
35
+ # events need to be send in order
36
+ # every event signature requries prior signature
37
+ thread = Thread.new do
38
+ # polling for buffered emit events until stream not active
39
+ while input_emitter.stream.state == :open
40
+ while callback = input_emitter.buffer.shift
41
+ callback.call if input_emitter.stream.state == :open
42
+ end
43
+ end
44
+ end
45
+ thread.abort_on_exception = true
46
+ # attach thread to current stream context
47
+ # make sure when stream closes (#wait or #join! is called)
48
+ # input signal thread is also killed
49
+ context[:input_signal_thread] = thread
50
+ end
31
51
  end
32
52
 
33
53
  context.http_response.on_success(200) do
@@ -0,0 +1,32 @@
1
+ module Aws
2
+ module Binary
3
+
4
+ # @api private
5
+ class EncodeHandler < Seahorse::Client::Handler
6
+
7
+ def call(context)
8
+ if eventstream_member = eventstream_input?(context)
9
+ input_es_handler = context[:input_event_stream_handler]
10
+ input_es_handler.event_emitter.encoder = EventStreamEncoder.new(
11
+ context.config.api.metadata['protocol'],
12
+ eventstream_member,
13
+ context.operation.input,
14
+ context.config.sigv4_signer
15
+ )
16
+ context[:input_event_emitter] = input_es_handler.event_emitter
17
+ end
18
+ @handler.call(context)
19
+ end
20
+
21
+ private
22
+
23
+ def eventstream_input?(ctx)
24
+ ctx.operation.input.shape.members.each do |_, ref|
25
+ return ref if ref.eventstream
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,122 @@
1
+ module Aws
2
+ module Binary
3
+ # @api private
4
+ class EventBuilder
5
+
6
+ include Seahorse::Model::Shapes
7
+
8
+ # @param [Class] parser_class
9
+ # @param [Seahorse::Model::ShapeRef] rules (of eventstream member)
10
+ def initialize(serializer_class, rules)
11
+ @serializer_class = serializer_class
12
+ @rules = rules
13
+ end
14
+
15
+ def apply(event_type, params)
16
+ event_ref = @rules.shape.member(event_type)
17
+ _event_stream_message(event_ref, params)
18
+ end
19
+
20
+ private
21
+
22
+ def _event_stream_message(event_ref, params)
23
+ es_headers = {}
24
+ payload = ""
25
+
26
+ es_headers[":message-type"] = Aws::EventStream::HeaderValue.new(
27
+ type: "string", value: "event")
28
+ es_headers[":event-type"] = Aws::EventStream::HeaderValue.new(
29
+ type: "string", value: event_ref.shape.name)
30
+
31
+ explicit_payload = false
32
+ implicit_payload_members = {}
33
+ event_ref.shape.members.each do |member_name, member_ref|
34
+ unless member_ref.eventheader
35
+ if member_ref.eventpayload
36
+ explicit_payload = true
37
+ else
38
+ implicit_payload_members[member_name] = member_ref
39
+ end
40
+ end
41
+ end
42
+
43
+ # implict payload
44
+ if !explicit_payload && !implicit_payload_members.empty?
45
+ if implicit_payload_members.size > 1
46
+ payload_shape = Shapes::StructureShape.new
47
+ implicit_payload_members.each do |m_name, m_ref|
48
+ payload_shape.add_member(m_name, m_ref)
49
+ end
50
+ payload_ref = Shapes::ShapeRef.new(shape: payload_shape)
51
+
52
+ payload = build_payload_members(payload_ref, params)
53
+ else
54
+ m_name, m_ref = implicit_payload_members.first
55
+ streaming, content_type = _content_type(m_ref.shape)
56
+
57
+ es_headers[":content-type"] = Aws::EventStream::HeaderValue.new(
58
+ type: "string", value: content_type)
59
+ payload = _build_payload(streaming, m_ref, params[m_name])
60
+ end
61
+ end
62
+
63
+
64
+ event_ref.shape.members.each do |member_name, member_ref|
65
+ if member_ref.eventheader && params[member_name]
66
+ header_value = params[member_name]
67
+ es_headers[member_ref.shape.name] = Aws::EventStream::HeaderValue.new(
68
+ type: _header_value_type(member_ref.shape, header_value),
69
+ value: header_value
70
+ )
71
+ elsif member_ref.eventpayload && params[member_name]
72
+ # explicit payload
73
+ streaming, content_type = _content_type(member_ref.shape)
74
+
75
+ es_headers[":content-type"] = Aws::EventStream::HeaderValue.new(
76
+ type: "string", value: content_type)
77
+ payload = _build_payload(streaming, member_ref, params[member_name])
78
+ end
79
+ end
80
+
81
+ Aws::EventStream::Message.new(
82
+ headers: es_headers,
83
+ payload: StringIO.new(payload)
84
+ )
85
+ end
86
+
87
+ def _content_type(shape)
88
+ case shape
89
+ when BlobShape then [true, "application/octet-stream"]
90
+ when StringShape then [true, "text/plain"]
91
+ when StructureShape then
92
+ if @serializer_class.name.include?('Xml')
93
+ [false, "text/xml"]
94
+ elsif @serializer_class.name.include?('Json')
95
+ [false, "application/json"]
96
+ end
97
+ else
98
+ raise Aws::Errors::EventStreamBuilderError.new(
99
+ "Unsupport eventpayload shape: #{shape.name}")
100
+ end
101
+ end
102
+
103
+ def _header_value_type(shape, value)
104
+ case shape
105
+ when StringShape then "string"
106
+ when IntegerShape then "integer"
107
+ when TimestampShape then "timestamp"
108
+ when BlobShape then "bytes"
109
+ when BooleanShape then !!value ? "bool_true" : "bool_false"
110
+ else
111
+ raise Aws::Errors::EventStreamBuilderError.new(
112
+ "Unsupported eventheader shape: #{shape.name}")
113
+ end
114
+ end
115
+
116
+ def _build_payload(streaming, ref, value)
117
+ streaming ? value : @serializer_class.new(ref).serialize(value)
118
+ end
119
+
120
+ end
121
+ end
122
+ end
@@ -6,10 +6,14 @@ module Aws
6
6
  include Seahorse::Model::Shapes
7
7
 
8
8
  # @param [Class] parser_class
9
- # @param [Seahorse::Model::ShapeRef] rules
10
- def initialize(parser_class, rules)
9
+ # @param [Seahorse::Model::ShapeRef] rules (of eventstream member)
10
+ # @param [Array] error_refs array of errors ShapeRef
11
+ # @param [Seahorse::Model::ShapeRef] output_ref
12
+ def initialize(parser_class, rules, error_refs, output_ref)
11
13
  @parser_class = parser_class
12
14
  @rules = rules
15
+ @error_refs = error_refs
16
+ @output_ref = output_ref
13
17
  end
14
18
 
15
19
  # Parse raw event message into event struct
@@ -31,9 +35,7 @@ module Aws
31
35
  when 'event'
32
36
  parse_event(raw_event)
33
37
  when 'exception'
34
- # Pending
35
- raise Aws::Errors::EventStreamParserError.new(
36
- ':exception event parsing is not supported')
38
+ parse_exception(raw_event)
37
39
  else
38
40
  raise Aws::Errors::EventStreamParserError.new(
39
41
  'Unrecognized :message-type value for the event')
@@ -44,6 +46,15 @@ module Aws
44
46
  end
45
47
  end
46
48
 
49
+ def parse_exception(raw_event)
50
+ exception_type = raw_event.headers.delete(":exception-type").value
51
+ name, ref = @rules.shape.member_by_location_name(exception_type)
52
+ # exception lives in payload implictly
53
+ exception = parse_payload(raw_event.payload.read, ref)
54
+ exception.event_type = name
55
+ exception
56
+ end
57
+
47
58
  def parse_error_event(raw_event)
48
59
  error_code = raw_event.headers.delete(":error-code")
49
60
  error_message = raw_event.headers.delete(":error-message")
@@ -58,35 +69,54 @@ module Aws
58
69
  event_type = raw_event.headers.delete(":event-type").value
59
70
  # content_type = raw_event.headers.delete(":content-type").value
60
71
 
61
- # Pending
62
72
  if event_type == 'initial-response'
63
- raise Aws::Errors::EventStreamParserError.new(
64
- 'non eventstream member at response is not supported yet'
65
- )
73
+ event = Struct.new(:event_type, :response).new
74
+ event.event_type = :initial_response
75
+ event.response = parse_payload(raw_event.payload.read, @output_ref)
76
+ return event
66
77
  end
67
78
 
68
79
  # locate event from eventstream
69
80
  name, ref = @rules.shape.member_by_location_name(event_type)
70
- raise "Non event member found at eventstream" unless ref.event
81
+ unless ref.event
82
+ raise Aws::Errors::EventStreamParserError.new(
83
+ "Failed to locate event shape for the event")
84
+ end
71
85
 
72
86
  event = ref.shape.struct_class.new
87
+
88
+ explicit_payload = false
89
+ implicit_payload_members = {}
90
+ ref.shape.members.each do |member_name, member_ref|
91
+ unless member_ref.eventheader
92
+ if member_ref.eventpayload
93
+ explicit_payload = true
94
+ else
95
+ implicit_payload_members[member_name] = member_ref
96
+ end
97
+ end
98
+ end
99
+
100
+ # implicit payload
101
+ if !explicit_payload && !implicit_payload_members.empty?
102
+ event = parse_payload(raw_event.payload.read, ref)
103
+ end
73
104
  event.event_type = name
105
+
74
106
  # locate payload and headers in the event
75
107
  ref.shape.members.each do |member_name, member_ref|
76
- if member_ref.eventpayload
77
- eventpayload_streaming?(member_ref) ?
78
- event.send("#{member_name}=", raw_event.payload) :
79
- event.send("#{member_name}=", parse_payload(raw_event.payload.read, member_ref))
80
- elsif member_ref.eventheader
108
+ if member_ref.eventheader
81
109
  # allow incomplete event members in response
82
110
  if raw_event.headers.key?(member_ref.location_name)
83
111
  event.send("#{member_name}=", raw_event.headers[member_ref.location_name].value)
84
112
  end
85
- else
86
- raise "Non eventpayload or eventheader member found at event"
113
+ elsif member_ref.eventpayload
114
+ # explicit payload
115
+ eventpayload_streaming?(member_ref) ?
116
+ event.send("#{member_name}=", raw_event.payload) :
117
+ event.send("#{member_name}=", parse_payload(raw_event.payload.read, member_ref))
87
118
  end
88
119
  end
89
-
90
120
  event
91
121
  end
92
122
 
@@ -7,11 +7,13 @@ module Aws
7
7
 
8
8
  # @param [String] protocol
9
9
  # @param [ShapeRef] rules ShapeRef of the eventstream member
10
+ # @param [ShapeRef] output_ref ShapeRef of output shape
11
+ # @param [Array] error_refs array of ShapeRefs for errors
10
12
  # @param [EventStream|nil] event_stream_handler A Service EventStream object
11
13
  # that registered with callbacks for processing events when they arrive
12
- def initialize(protocol, rules, io, event_stream_handler = nil)
14
+ def initialize(protocol, rules, output_ref, error_refs, io, event_stream_handler = nil)
13
15
  @decoder = Aws::EventStream::Decoder.new
14
- @event_parser = EventParser.new(parser_class(protocol), rules)
16
+ @event_parser = EventParser.new(parser_class(protocol), rules, error_refs, output_ref)
15
17
  @stream_class = extract_stream_class(rules.shape.struct_class)
16
18
  @emitter = event_stream_handler.event_emitter
17
19
  @events = []
@@ -42,6 +44,7 @@ module Aws
42
44
  case protocol
43
45
  when 'rest-xml' then Aws::Xml::Parser
44
46
  when 'rest-json' then Aws::Json::Parser
47
+ when 'json' then Aws::Json::Parser
45
48
  else raise "unsupported protocol #{protocol} for event stream"
46
49
  end
47
50
  end
@@ -0,0 +1,53 @@
1
+ require 'aws-eventstream'
2
+
3
+ module Aws
4
+ module Binary
5
+ # @api private
6
+ class EventStreamEncoder
7
+
8
+ # @param [String] protocol
9
+ # @param [ShapeRef] rules ShapeRef of the eventstream member
10
+ # @param [ShapeRef] input_ref ShapeRef of the input shape
11
+ # @param [Aws::Sigv4::Signer] signer
12
+ def initialize(protocol, rules, input_ref, signer)
13
+ @encoder = Aws::EventStream::Encoder.new
14
+ @event_builder = EventBuilder.new(serializer_class(protocol), rules)
15
+ @input_ref = input_ref
16
+ @rules = rules
17
+ @signer = signer
18
+ @prior_signature = nil
19
+ end
20
+
21
+ attr_reader :rules
22
+
23
+ attr_accessor :prior_signature
24
+
25
+ def encode(event_type, params)
26
+ if event_type == :end_stream
27
+ payload = ''
28
+ else
29
+ payload = @encoder.encode(@event_builder.apply(event_type, params))
30
+ end
31
+ headers, signature = @signer.sign_event(@prior_signature, payload, @encoder)
32
+ @prior_signature = signature
33
+ message = Aws::EventStream::Message.new(
34
+ headers: headers,
35
+ payload: StringIO.new(payload)
36
+ )
37
+ @encoder.encode(message)
38
+ end
39
+
40
+ private
41
+
42
+ def serializer_class(protocol)
43
+ case protocol
44
+ when 'rest-xml' then Xml::Builder
45
+ when 'rest-json' then Json::Builder
46
+ when 'json' then Json::Builder
47
+ else raise "unsupported protocol #{protocol} for event stream"
48
+ end
49
+ end
50
+
51
+ end
52
+ end
53
+ end