aws-sdk-core 3.46.2 → 3.47.0

Sign up to get free protection for your applications and to get access to all the features.
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