aws-sdk-core 3.189.0 → 3.199.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 (119) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +183 -0
  3. data/VERSION +1 -1
  4. data/lib/aws-sdk-core/binary/decode_handler.rb +3 -9
  5. data/lib/aws-sdk-core/binary/encode_handler.rb +1 -1
  6. data/lib/aws-sdk-core/binary/event_builder.rb +34 -37
  7. data/lib/aws-sdk-core/binary/event_stream_decoder.rb +1 -0
  8. data/lib/aws-sdk-core/binary/event_stream_encoder.rb +4 -3
  9. data/lib/aws-sdk-core/cbor/cbor_engine.rb +19 -0
  10. data/lib/aws-sdk-core/cbor/decoder.rb +310 -0
  11. data/lib/aws-sdk-core/cbor/encoder.rb +243 -0
  12. data/lib/aws-sdk-core/cbor.rb +106 -0
  13. data/lib/aws-sdk-core/client_stubs.rb +18 -14
  14. data/lib/aws-sdk-core/credential_provider.rb +1 -1
  15. data/lib/aws-sdk-core/ec2_metadata.rb +1 -1
  16. data/lib/aws-sdk-core/ecs_credentials.rb +2 -1
  17. data/lib/aws-sdk-core/endpoints/matchers.rb +5 -1
  18. data/lib/aws-sdk-core/error_handler.rb +41 -0
  19. data/lib/aws-sdk-core/errors.rb +2 -2
  20. data/lib/aws-sdk-core/event_emitter.rb +0 -16
  21. data/lib/aws-sdk-core/instance_profile_credentials.rb +3 -2
  22. data/lib/aws-sdk-core/json/builder.rb +8 -1
  23. data/lib/aws-sdk-core/json/error_handler.rb +15 -10
  24. data/lib/aws-sdk-core/json/handler.rb +5 -6
  25. data/lib/aws-sdk-core/json/json_engine.rb +3 -1
  26. data/lib/aws-sdk-core/json/oj_engine.rb +7 -1
  27. data/lib/aws-sdk-core/json/parser.rb +6 -1
  28. data/lib/aws-sdk-core/json.rb +43 -14
  29. data/lib/aws-sdk-core/lru_cache.rb +75 -0
  30. data/lib/aws-sdk-core/pageable_response.rb +1 -1
  31. data/lib/aws-sdk-core/param_validator.rb +7 -2
  32. data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +1 -0
  33. data/lib/aws-sdk-core/plugins/client_metrics_send_plugin.rb +14 -2
  34. data/lib/aws-sdk-core/plugins/credentials_configuration.rb +2 -0
  35. data/lib/aws-sdk-core/plugins/global_configuration.rb +8 -9
  36. data/lib/aws-sdk-core/plugins/invocation_id.rb +1 -11
  37. data/lib/aws-sdk-core/plugins/logging.rb +2 -0
  38. data/lib/aws-sdk-core/plugins/protocols/api_gateway.rb +3 -1
  39. data/lib/aws-sdk-core/plugins/protocols/ec2.rb +2 -24
  40. data/lib/aws-sdk-core/plugins/protocols/json_rpc.rb +6 -8
  41. data/lib/aws-sdk-core/plugins/protocols/query.rb +4 -2
  42. data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +3 -15
  43. data/lib/aws-sdk-core/plugins/protocols/rest_xml.rb +3 -0
  44. data/lib/aws-sdk-core/plugins/protocols/rpc_v2.rb +17 -0
  45. data/lib/aws-sdk-core/plugins/request_compression.rb +11 -2
  46. data/lib/aws-sdk-core/plugins/retry_errors.rb +12 -3
  47. data/lib/aws-sdk-core/plugins/sign.rb +8 -3
  48. data/lib/aws-sdk-core/plugins/stub_responses.rb +1 -0
  49. data/lib/aws-sdk-core/plugins/user_agent.rb +61 -26
  50. data/lib/aws-sdk-core/process_credentials.rb +45 -27
  51. data/lib/aws-sdk-core/query/ec2_handler.rb +27 -0
  52. data/lib/aws-sdk-core/query/ec2_param_builder.rb +5 -7
  53. data/lib/aws-sdk-core/query/handler.rb +4 -4
  54. data/lib/aws-sdk-core/query/param_builder.rb +2 -2
  55. data/lib/aws-sdk-core/query.rb +2 -1
  56. data/lib/aws-sdk-core/rest/content_type_handler.rb +60 -0
  57. data/lib/aws-sdk-core/rest/handler.rb +3 -4
  58. data/lib/aws-sdk-core/rest/request/body.rb +32 -5
  59. data/lib/aws-sdk-core/rest/request/endpoint.rb +24 -4
  60. data/lib/aws-sdk-core/rest/request/headers.rb +15 -7
  61. data/lib/aws-sdk-core/rest/request/querystring_builder.rb +23 -11
  62. data/lib/aws-sdk-core/rest/response/body.rb +15 -1
  63. data/lib/aws-sdk-core/rest/response/header_list_parser.rb +79 -0
  64. data/lib/aws-sdk-core/rest/response/headers.rb +8 -3
  65. data/lib/aws-sdk-core/rest.rb +1 -0
  66. data/lib/aws-sdk-core/rpc_v2/builder.rb +62 -0
  67. data/lib/aws-sdk-core/rpc_v2/content_type_handler.rb +45 -0
  68. data/lib/aws-sdk-core/rpc_v2/error_handler.rb +84 -0
  69. data/lib/aws-sdk-core/rpc_v2/handler.rb +74 -0
  70. data/lib/aws-sdk-core/rpc_v2/parser.rb +90 -0
  71. data/lib/aws-sdk-core/rpc_v2.rb +6 -0
  72. data/lib/aws-sdk-core/stubbing/protocols/rpc_v2.rb +41 -0
  73. data/lib/aws-sdk-core/util.rb +39 -0
  74. data/lib/aws-sdk-core/waiters/poller.rb +2 -2
  75. data/lib/aws-sdk-core/xml/builder.rb +17 -9
  76. data/lib/aws-sdk-core/xml/error_handler.rb +32 -42
  77. data/lib/aws-sdk-core/xml/parser/frame.rb +4 -20
  78. data/lib/aws-sdk-core/xml/parser/stack.rb +2 -0
  79. data/lib/aws-sdk-core/xml/parser.rb +2 -6
  80. data/lib/aws-sdk-core.rb +7 -2
  81. data/lib/aws-sdk-sso/client.rb +77 -49
  82. data/lib/aws-sdk-sso/plugins/endpoints.rb +1 -0
  83. data/lib/aws-sdk-sso.rb +1 -1
  84. data/lib/aws-sdk-ssooidc/client.rb +127 -51
  85. data/lib/aws-sdk-ssooidc/client_api.rb +22 -0
  86. data/lib/aws-sdk-ssooidc/errors.rb +21 -0
  87. data/lib/aws-sdk-ssooidc/plugins/endpoints.rb +1 -0
  88. data/lib/aws-sdk-ssooidc/types.rb +77 -9
  89. data/lib/aws-sdk-ssooidc.rb +1 -1
  90. data/lib/aws-sdk-sts/client.rb +78 -50
  91. data/lib/aws-sdk-sts/client_api.rb +8 -8
  92. data/lib/aws-sdk-sts/plugins/endpoints.rb +1 -0
  93. data/lib/aws-sdk-sts/types.rb +1 -1
  94. data/lib/aws-sdk-sts.rb +1 -1
  95. data/lib/seahorse/client/async_base.rb +1 -1
  96. data/lib/seahorse/client/async_response.rb +19 -0
  97. data/lib/seahorse/client/base.rb +18 -7
  98. data/lib/seahorse/client/h2/handler.rb +1 -0
  99. data/lib/seahorse/client/handler.rb +1 -1
  100. data/lib/seahorse/client/net_http/connection_pool.rb +3 -9
  101. data/lib/seahorse/client/plugin.rb +9 -0
  102. data/lib/seahorse/client/plugins/endpoint.rb +0 -1
  103. data/lib/seahorse/client/plugins/net_http.rb +48 -16
  104. data/lib/seahorse/model/shapes.rb +2 -2
  105. data/sig/aws-sdk-core/client_stubs.rbs +10 -0
  106. data/sig/aws-sdk-core/errors.rbs +22 -0
  107. data/sig/aws-sdk-core/resources/collection.rbs +21 -0
  108. data/sig/aws-sdk-core/structure.rbs +4 -0
  109. data/sig/aws-sdk-core/waiters/errors.rbs +20 -0
  110. data/sig/aws-sdk-core.rbs +7 -0
  111. data/sig/seahorse/client/base.rbs +25 -0
  112. data/sig/seahorse/client/handler_builder.rbs +16 -0
  113. data/sig/seahorse/client/response.rbs +61 -0
  114. metadata +38 -12
  115. /data/lib/aws-sdk-core/xml/parser/{engines/libxml.rb → libxml_engine.rb} +0 -0
  116. /data/lib/aws-sdk-core/xml/parser/{engines/nokogiri.rb → nokogiri_engine.rb} +0 -0
  117. /data/lib/aws-sdk-core/xml/parser/{engines/oga.rb → oga_engine.rb} +0 -0
  118. /data/lib/aws-sdk-core/xml/parser/{engines/ox.rb → ox_engine.rb} +0 -0
  119. /data/lib/aws-sdk-core/xml/parser/{engines/rexml.rb → rexml_engine.rb} +0 -0
@@ -11,7 +11,7 @@ module Aws
11
11
 
12
12
  # @return [Boolean]
13
13
  def set?
14
- !!credentials && credentials.set?
14
+ !!@credentials && @credentials.set?
15
15
  end
16
16
 
17
17
  end
@@ -183,7 +183,7 @@ module Aws
183
183
 
184
184
  def open_connection
185
185
  uri = URI.parse(@endpoint)
186
- http = Net::HTTP.new(uri.hostname || @endpoint, @port || uri.port)
186
+ http = Net::HTTP.new(uri.hostname || @endpoint, uri.port || @port)
187
187
  http.open_timeout = @http_open_timeout
188
188
  http.read_timeout = @http_read_timeout
189
189
  http.set_debug_output(@http_debug_output) if @http_debug_output
@@ -207,7 +207,8 @@ module Aws
207
207
  end
208
208
  rescue TokenFileReadError, InvalidTokenError
209
209
  raise
210
- rescue StandardError
210
+ rescue StandardError => e
211
+ warn("Error retrieving ECS Credentials: #{e.message}")
211
212
  '{}'
212
213
  end
213
214
 
@@ -28,7 +28,11 @@ module Aws
28
28
 
29
29
  val = if (index = parts.first[BRACKET_REGEX, 1])
30
30
  # remove brackets and index from part before indexing
31
- value[parts.first.gsub(BRACKET_REGEX, '')][index.to_i]
31
+ if (base = parts.first.gsub(BRACKET_REGEX, '')) && !base.empty?
32
+ value[base][index.to_i]
33
+ else
34
+ value[index.to_i]
35
+ end
32
36
  else
33
37
  value[parts.first]
34
38
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ class ErrorHandler < Seahorse::Client::Handler
5
+
6
+ private
7
+
8
+ def error(context)
9
+ body = context.http_response.body_contents
10
+ if body.empty?
11
+ code, message, data = http_status_error(context)
12
+ else
13
+ code, message, data = extract_error(body, context)
14
+ end
15
+ build_error(context, code, message, data)
16
+ end
17
+
18
+ def build_error(context, code, message, data)
19
+ errors_module = context.client.class.errors_module
20
+ errors_module.error_class(code).new(context, message, data)
21
+ end
22
+
23
+ def http_status_error(context)
24
+ [http_status_error_code(context), '', EmptyStructure.new]
25
+ end
26
+
27
+ def http_status_error_code(context)
28
+ status_code = context.http_response.status_code
29
+ {
30
+ 302 => 'MovedTemporarily',
31
+ 304 => 'NotModified',
32
+ 400 => 'BadRequest',
33
+ 403 => 'Forbidden',
34
+ 404 => 'NotFound',
35
+ 412 => 'PreconditionFailed',
36
+ 413 => 'RequestEntityTooLarge',
37
+ }[status_code] || "Http#{status_code}Error"
38
+ end
39
+
40
+ end
41
+ end
@@ -12,7 +12,7 @@ module Aws
12
12
  class ServiceError < RuntimeError
13
13
 
14
14
  # @param [Seahorse::Client::RequestContext] context
15
- # @param [String] message
15
+ # @param [String, nil] message
16
16
  # @param [Aws::Structure] data
17
17
  def initialize(context, message, data = Aws::EmptyStructure.new)
18
18
  @code = self.class.code
@@ -34,7 +34,7 @@ module Aws
34
34
 
35
35
  class << self
36
36
 
37
- # @return [String]
37
+ # @return [String, nil]
38
38
  attr_accessor :code
39
39
 
40
40
  end
@@ -6,7 +6,6 @@ module Aws
6
6
  def initialize
7
7
  @listeners = {}
8
8
  @validate_event = true
9
- @status = :sleep
10
9
  @signal_queue = Queue.new
11
10
  end
12
11
 
@@ -40,25 +39,10 @@ module Aws
40
39
  Aws::ParamValidator.validate!(
41
40
  @encoder.rules.shape.member(type), params)
42
41
  end
43
- _ready_for_events?
44
42
  @stream.data(
45
43
  @encoder.encode(type, params),
46
44
  end_stream: type == :end_stream
47
45
  )
48
46
  end
49
-
50
- private
51
-
52
- def _ready_for_events?
53
- return true if @status == :ready
54
-
55
- # blocked until once initial 200 response is received
56
- # signal will be available in @signal_queue
57
- # and this check will no longer be blocked
58
- @signal_queue.pop
59
- @status = :ready
60
- true
61
- end
62
-
63
47
  end
64
48
  end
@@ -215,7 +215,8 @@ module Aws
215
215
  _get_credentials(conn, token)
216
216
  end
217
217
  end
218
- rescue
218
+ rescue => e
219
+ warn("Error retrieving instance profile credentials: #{e}")
219
220
  '{}'
220
221
  end
221
222
  end
@@ -261,7 +262,7 @@ module Aws
261
262
 
262
263
  def open_connection
263
264
  uri = URI.parse(@endpoint)
264
- http = Net::HTTP.new(uri.hostname || @endpoint, @port || uri.port)
265
+ http = Net::HTTP.new(uri.hostname || @endpoint, uri.port || @port)
265
266
  http.open_timeout = @http_open_timeout
266
267
  http.read_timeout = @http_read_timeout
267
268
  http.set_debug_output(@http_debug_output) if @http_debug_output
@@ -8,7 +8,7 @@ module Aws
8
8
 
9
9
  include Seahorse::Model::Shapes
10
10
 
11
- def initialize(rules)
11
+ def initialize(rules, _options = {})
12
12
  @rules = rules
13
13
  end
14
14
 
@@ -20,6 +20,8 @@ module Aws
20
20
  private
21
21
 
22
22
  def structure(ref, values)
23
+ return nil if values.nil?
24
+
23
25
  shape = ref.shape
24
26
  values.each_pair.with_object({}) do |(key, value), data|
25
27
  if shape.member?(key) && !value.nil?
@@ -31,11 +33,15 @@ module Aws
31
33
  end
32
34
 
33
35
  def list(ref, values)
36
+ return nil if values.nil?
37
+
34
38
  member_ref = ref.shape.member
35
39
  values.collect { |value| format(member_ref, value) }
36
40
  end
37
41
 
38
42
  def map(ref, values)
43
+ return nil if values.nil?
44
+
39
45
  value_ref = ref.shape.value
40
46
  values.each.with_object({}) do |(key, value), data|
41
47
  data[key] = format(value_ref, value)
@@ -49,6 +55,7 @@ module Aws
49
55
  when MapShape then map(ref, value)
50
56
  when TimestampShape then timestamp(ref, value)
51
57
  when BlobShape then encode(value)
58
+ when FloatShape then Util.serialize_number(value)
52
59
  else value
53
60
  end
54
61
  end
@@ -2,10 +2,8 @@
2
2
 
3
3
  module Aws
4
4
  module Json
5
- class ErrorHandler < Xml::ErrorHandler
5
+ class ErrorHandler < Aws::ErrorHandler
6
6
 
7
- # @param [Seahorse::Client::RequestContext] context
8
- # @return [Seahorse::Client::Response]
9
7
  def call(context)
10
8
  @handler.call(context).on(300..599) do |response|
11
9
  response.error = error(context)
@@ -19,7 +17,7 @@ module Aws
19
17
  json = Json.load(body)
20
18
  code = error_code(json, context)
21
19
  message = error_message(code, json)
22
- data = parse_error_data(context, code)
20
+ data = parse_error_data(context, body, code)
23
21
  [code, message, data]
24
22
  rescue Json::ParseError
25
23
  [http_status_error_code(context), '', EmptyStructure.new]
@@ -48,7 +46,7 @@ module Aws
48
46
  end
49
47
 
50
48
  def remove_prefix(error_code, context)
51
- if prefix = context.config.api.metadata['errorPrefix']
49
+ if (prefix = context.config.api.metadata['errorPrefix'])
52
50
  error_code.sub(/^#{prefix}/, '')
53
51
  else
54
52
  error_code
@@ -63,22 +61,29 @@ module Aws
63
61
  end
64
62
  end
65
63
 
66
- def parse_error_data(context, code)
64
+ def parse_error_data(context, body, code)
67
65
  data = EmptyStructure.new
68
- if error_rules = context.operation.errors
66
+ if (error_rules = context.operation.errors)
69
67
  error_rules.each do |rule|
70
68
  # match modeled shape name with the type(code) only
71
69
  # some type(code) might contains invalid characters
72
70
  # such as ':' (efs) etc
73
71
  match = rule.shape.name == code.gsub(/[^^a-zA-Z0-9]/, '')
74
- if match && rule.shape.members.any?
75
- data = Parser.new(rule).parse(context.http_response.body_contents)
76
- end
72
+ next unless match && rule.shape.members.any?
73
+
74
+ data = Parser.new(rule).parse(body)
75
+ # errors support HTTP bindings
76
+ apply_error_headers(rule, context, data)
77
77
  end
78
78
  end
79
79
  data
80
80
  end
81
81
 
82
+ def apply_error_headers(rule, context, data)
83
+ headers = Aws::Rest::Response::Headers.new(rule)
84
+ headers.apply(context.http_response, data)
85
+ end
86
+
82
87
  end
83
88
  end
84
89
  end
@@ -12,8 +12,7 @@ module Aws
12
12
  build_request(context)
13
13
  response = @handler.call(context)
14
14
  response.on(200..299) { |resp| parse_response(resp) }
15
- response.on(200..599) { |resp| apply_request_id(context) }
16
- response
15
+ response.on(200..599) { |_resp| apply_request_id(context) }
17
16
  end
18
17
 
19
18
  private
@@ -38,10 +37,10 @@ module Aws
38
37
  end
39
38
 
40
39
  def parse_body(context)
40
+ json = context.http_response.body_contents
41
41
  if simple_json?(context)
42
- Json.load(context.http_response.body_contents)
43
- elsif rules = context.operation.output
44
- json = context.http_response.body_contents
42
+ Json.load(json)
43
+ elsif (rules = context.operation.output)
45
44
  if json.is_a?(Array)
46
45
  # an array of emitted events
47
46
  if json[0].respond_to?(:response)
@@ -62,7 +61,7 @@ module Aws
62
61
  Parser.new(
63
62
  rules,
64
63
  query_compatible: query_compatible?(context)
65
- ).parse(json == '' ? '{}' : json)
64
+ ).parse(json)
66
65
  end
67
66
  else
68
67
  EmptyStructure.new
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'json'
4
+
3
5
  module Aws
4
6
  module Json
5
- module JSONEngine
7
+ module JsonEngine
6
8
  class << self
7
9
  def load(json)
8
10
  JSON.parse(json)
@@ -1,10 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'oj'
4
+
3
5
  module Aws
4
6
  module Json
5
7
  module OjEngine
6
8
  # @api private
7
- LOAD_OPTIONS = { mode: :compat, symbol_keys: false, empty_string: false }.freeze
9
+ LOAD_OPTIONS = {
10
+ mode: :compat,
11
+ symbol_keys: false,
12
+ empty_string: false
13
+ }.freeze
8
14
 
9
15
  # @api private
10
16
  DUMP_OPTIONS = { mode: :compat }.freeze
@@ -17,6 +17,8 @@ module Aws
17
17
 
18
18
  # @param [String<JSON>] json
19
19
  def parse(json, target = nil)
20
+ json = '{}' if json.empty?
21
+
20
22
  parse_ref(@rules, Json.load(json), target)
21
23
  end
22
24
 
@@ -69,6 +71,8 @@ module Aws
69
71
  def map(ref, values, target = nil)
70
72
  target = {} if target.nil?
71
73
  values.each do |key, value|
74
+ next if value.nil?
75
+
72
76
  target[key] = parse_ref(ref.shape.value, value)
73
77
  end
74
78
  target
@@ -85,6 +89,7 @@ module Aws
85
89
  when TimestampShape then time(value)
86
90
  when BlobShape then Base64.decode64(value)
87
91
  when BooleanShape then value.to_s == 'true'
92
+ when FloatShape then Util.deserialize_number(value)
88
93
  else value
89
94
  end
90
95
  end
@@ -93,7 +98,7 @@ module Aws
93
98
  # @param [String, Integer] value
94
99
  # @return [Time]
95
100
  def time(value)
96
- value.is_a?(Numeric) ? Time.at(value) : Time.parse(value)
101
+ value.is_a?(Numeric) ? Time.at(value) : Aws::Util.deserialize_time(value)
97
102
  end
98
103
 
99
104
  def flattened_list?(shape)
@@ -1,12 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
3
  require_relative 'json/builder'
5
4
  require_relative 'json/error_handler'
6
5
  require_relative 'json/handler'
7
6
  require_relative 'json/parser'
8
- require_relative 'json/json_engine'
9
- require_relative 'json/oj_engine'
10
7
 
11
8
  module Aws
12
9
  # @api private
@@ -21,29 +18,61 @@ module Aws
21
18
  end
22
19
 
23
20
  class << self
24
- def load(json)
25
- ENGINE.load(json)
21
+ # @param [Symbol,Class] engine
22
+ # Must be one of the following values:
23
+ #
24
+ # * :oj
25
+ # * :json
26
+ #
27
+ def engine=(engine)
28
+ @engine = Class === engine ? engine : load_engine(engine)
29
+ end
30
+
31
+ # @return [Class] Returns the default engine.
32
+ # One of:
33
+ #
34
+ # * {OjEngine}
35
+ # * {JsonEngine}
36
+ #
37
+ def engine
38
+ set_default_engine unless @engine
39
+ @engine
26
40
  end
27
41
 
28
- def load_file(path)
29
- load(File.open(path, 'r', encoding: 'UTF-8', &:read))
42
+ def load(json)
43
+ @engine.load(json)
30
44
  end
31
45
 
32
46
  def dump(value)
33
- ENGINE.dump(value)
47
+ @engine.dump(value)
48
+ end
49
+
50
+ def set_default_engine
51
+ [:oj, :json].each do |name|
52
+ @engine ||= try_load_engine(name)
53
+ end
54
+ unless @engine
55
+ raise 'Unable to find a compatible json library. ' \
56
+ 'Ensure that you have installed or added to your Gemfile one of ' \
57
+ 'oj or json'
58
+ end
34
59
  end
35
60
 
36
61
  private
37
62
 
38
- def select_engine
39
- require 'oj'
40
- OjEngine
63
+ def load_engine(name)
64
+ require "aws-sdk-core/json/#{name}_engine"
65
+ const_name = name[0].upcase + name[1..-1] + 'Engine'
66
+ const_get(const_name)
67
+ end
68
+
69
+ def try_load_engine(name)
70
+ load_engine(name)
41
71
  rescue LoadError
42
- JSONEngine
72
+ false
43
73
  end
44
74
  end
45
75
 
46
- # @api private
47
- ENGINE = select_engine
76
+ set_default_engine
48
77
  end
49
78
  end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ # @api private
5
+ # A simple thread safe LRU cache
6
+ class LRUCache
7
+ # @param [Hash] options
8
+ # @option options [Integer] :max_entries (100) Maximum number of entries
9
+ # @option options [Integer] :expiration (nil) Expiration time in seconds
10
+ def initialize(options = {})
11
+ @max_entries = options[:max_entries] || 100
12
+ @expiration = options[:expiration]
13
+ @entries = {}
14
+ @mutex = Mutex.new
15
+ end
16
+
17
+ # @param [String] key
18
+ # @return [Object]
19
+ def [](key)
20
+ @mutex.synchronize do
21
+ value = @entries[key]
22
+ if value
23
+ @entries.delete(key)
24
+ @entries[key] = value unless value.expired?
25
+ end
26
+ @entries[key]&.value
27
+ end
28
+ end
29
+
30
+ # @param [String] key
31
+ # @param [Object] value
32
+ def []=(key, value)
33
+ @mutex.synchronize do
34
+ @entries.shift unless @entries.size < @max_entries
35
+ # delete old value if exists
36
+ @entries.delete(key)
37
+ @entries[key] = Entry.new(value: value, expiration: @expiration)
38
+ @entries[key].value
39
+ end
40
+ end
41
+
42
+ # @param [String] key
43
+ # @return [Boolean]
44
+ def key?(key)
45
+ @mutex.synchronize do
46
+ @entries.delete(key) if @entries.key?(key) && @entries[key].expired?
47
+ @entries.key?(key)
48
+ end
49
+ end
50
+
51
+ def clear
52
+ @mutex.synchronize do
53
+ @entries.clear
54
+ end
55
+ end
56
+
57
+ # @api private
58
+ class Entry
59
+ def initialize(options = {})
60
+ @value = options[:value]
61
+ @expiration = options[:expiration]
62
+ @created_time = Time.now
63
+ end
64
+
65
+ # @return [Object]
66
+ attr_reader :value
67
+
68
+ def expired?
69
+ return false unless @expiration
70
+
71
+ Time.now - @created_time > @expiration
72
+ end
73
+ end
74
+ end
75
+ end
@@ -201,7 +201,7 @@ module Aws
201
201
  def next_response(params)
202
202
  params = next_page_params(params)
203
203
  request = context.client.build_request(context.operation_name, params)
204
- Aws::Plugins::UserAgent.feature('paginator') do
204
+ Aws::Plugins::UserAgent.metric('PAGINATOR') do
205
205
  request.send_request
206
206
  end
207
207
  end
@@ -71,9 +71,10 @@ module Aws
71
71
  end
72
72
 
73
73
  if @validate_required && shape.union
74
- if values.length > 1
74
+ set_values = @input ? values.length : values.to_h.length
75
+ if set_values > 1
75
76
  errors << "multiple values provided to union at #{context} - must contain exactly one of the supported types: #{shape.member_names.join(', ')}"
76
- elsif values.length == 0
77
+ elsif set_values == 0
77
78
  errors << "No values provided to union at #{context} - must contain exactly one of the supported types: #{shape.member_names.join(', ')}"
78
79
  end
79
80
  end
@@ -106,6 +107,8 @@ module Aws
106
107
  # validate members
107
108
  member_ref = ref.shape.member
108
109
  values.each.with_index do |value, index|
110
+ next unless value
111
+
109
112
  shape(member_ref, value, errors, context + "[#{index}]")
110
113
  end
111
114
  end
@@ -121,6 +124,8 @@ module Aws
121
124
 
122
125
  values.each do |key, value|
123
126
  shape(key_ref, key, errors, "#{context} #{key.inspect} key")
127
+ next unless value
128
+
124
129
  shape(value_ref, value, errors, context + "[#{key.inspect}]")
125
130
  end
126
131
  end
@@ -40,6 +40,7 @@ side monitoring agent is running on, where client metrics will be published via
40
40
  option(:client_side_monitoring_publisher,
41
41
  default: ClientSideMonitoring::Publisher,
42
42
  doc_type: Aws::ClientSideMonitoring::Publisher,
43
+ rbs_type: 'untyped',
43
44
  docstring: <<-DOCS) do |cfg|
44
45
  Allows you to provide a custom client-side monitoring publisher class. By default,
45
46
  will use the Client Side Monitoring Agent Publisher.
@@ -11,6 +11,8 @@ module Aws
11
11
  # AttemptHandler comes just before we would retry an error.
12
12
  # Or before we would follow redirects.
13
13
  handlers.add(AttemptHandler, step: :sign, priority: 39)
14
+ # ErrorHandler comes after we have parsed an error.
15
+ handlers.add(ErrorHandler, step: :sign, priority: 95)
14
16
  # LatencyHandler is as close to sending as possible.
15
17
  handlers.add(LatencyHandler, step: :sign, priority: 0)
16
18
  end
@@ -62,17 +64,27 @@ module Aws
62
64
  call_attempt.x_amzn_request_id = headers["x-amzn-request-id"]
63
65
  end
64
66
  call_attempt.http_status_code = context.http_response.status_code
65
- if e = resp.error
67
+ context.metadata[:current_call_attempt] = call_attempt
68
+ request_metrics.add_call_attempt(call_attempt)
69
+ resp
70
+ end
71
+ end
72
+
73
+ class ErrorHandler < Seahorse::Client::Handler
74
+ def call(context)
75
+ resp = @handler.call(context)
76
+ call_attempt = context.metadata[:current_call_attempt]
77
+ if (e = resp.error)
66
78
  e_name = _extract_error_name(e)
67
79
  e_msg = e.message
68
80
  call_attempt.aws_exception = "#{e_name}"
69
81
  call_attempt.aws_exception_msg = "#{e_msg}"
70
82
  end
71
- request_metrics.add_call_attempt(call_attempt)
72
83
  resp
73
84
  end
74
85
 
75
86
  private
87
+
76
88
  def _extract_error_name(error)
77
89
  if error.is_a?(Aws::Errors::ServiceError)
78
90
  error.class.code
@@ -23,6 +23,7 @@ at HOME/.aws/credentials. When not specified, 'default' is used.
23
23
  option(:credentials,
24
24
  required: true,
25
25
  doc_type: 'Aws::CredentialProvider',
26
+ rbs_type: 'untyped',
26
27
  docstring: <<-DOCS
27
28
  Your AWS credentials. This can be an instance of any one of the
28
29
  following classes:
@@ -79,6 +80,7 @@ locations will be searched for credentials:
79
80
  option(:token_provider,
80
81
  required: false,
81
82
  doc_type: 'Aws::TokenProvider',
83
+ rbs_type: 'untyped',
82
84
  docstring: <<-DOCS
83
85
  A Bearer Token Provider. This can be an instance of any one of the
84
86
  following classes:
@@ -43,7 +43,7 @@ module Aws
43
43
  # @api private
44
44
  class GlobalConfiguration < Seahorse::Client::Plugin
45
45
 
46
- @identifiers = Set.new()
46
+ @identifiers = Set.new
47
47
 
48
48
  # @api private
49
49
  def before_initialize(client_class, options)
@@ -55,17 +55,18 @@ module Aws
55
55
  private
56
56
 
57
57
  def apply_service_defaults(client_class, options)
58
- if defaults = Aws.config[client_class.identifier]
59
- defaults.each do |option_name, default|
60
- options[option_name] = default unless options.key?(option_name)
61
- end
58
+ return unless (defaults = Aws.config[client_class.identifier])
59
+
60
+ defaults.each do |option_name, default|
61
+ options[option_name] = default unless options.key?(option_name)
62
62
  end
63
63
  end
64
64
 
65
- def apply_aws_defaults(client_class, options)
65
+ def apply_aws_defaults(_client_class, options)
66
66
  Aws.config.each do |option_name, default|
67
67
  next if self.class.identifiers.include?(option_name)
68
68
  next if options.key?(option_name)
69
+
69
70
  options[option_name] = default
70
71
  end
71
72
  end
@@ -80,9 +81,7 @@ module Aws
80
81
 
81
82
  # @return [Set<String>]
82
83
  # @api private
83
- def identifiers
84
- @identifiers
85
- end
84
+ attr_reader :identifiers
86
85
 
87
86
  end
88
87
  end