aws-sdk-core 3.46.0 → 3.94.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 +5 -5
- data/VERSION +1 -1
- data/lib/aws-sdk-core.rb +7 -0
- data/lib/aws-sdk-core/arn.rb +77 -0
- data/lib/aws-sdk-core/arn_parser.rb +38 -0
- data/lib/aws-sdk-core/assume_role_web_identity_credentials.rb +102 -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 +9 -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_side_monitoring/publisher.rb +9 -1
- data/lib/aws-sdk-core/client_stubs.rb +10 -9
- data/lib/aws-sdk-core/credential_provider.rb +0 -31
- data/lib/aws-sdk-core/credential_provider_chain.rb +79 -39
- data/lib/aws-sdk-core/deprecations.rb +16 -10
- data/lib/aws-sdk-core/ecs_credentials.rb +12 -8
- data/lib/aws-sdk-core/endpoint_cache.rb +14 -11
- data/lib/aws-sdk-core/errors.rb +94 -6
- data/lib/aws-sdk-core/event_emitter.rb +42 -0
- data/lib/aws-sdk-core/instance_profile_credentials.rb +120 -38
- data/lib/aws-sdk-core/json.rb +13 -14
- data/lib/aws-sdk-core/json/error_handler.rb +19 -2
- data/lib/aws-sdk-core/json/handler.rb +19 -1
- data/lib/aws-sdk-core/log/formatter.rb +7 -1
- data/lib/aws-sdk-core/log/param_filter.rb +3 -3
- data/lib/aws-sdk-core/pageable_response.rb +34 -20
- data/lib/aws-sdk-core/param_validator.rb +11 -5
- data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +26 -1
- data/lib/aws-sdk-core/plugins/endpoint_discovery.rb +1 -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/regional_endpoint.rb +8 -1
- data/lib/aws-sdk-core/plugins/retries/client_rate_limiter.rb +137 -0
- data/lib/aws-sdk-core/plugins/retries/clock_skew.rb +98 -0
- data/lib/aws-sdk-core/plugins/retries/error_inspector.rb +142 -0
- data/lib/aws-sdk-core/plugins/retries/retry_quota.rb +57 -0
- data/lib/aws-sdk-core/plugins/retry_errors.rb +290 -106
- data/lib/aws-sdk-core/plugins/signature_v4.rb +13 -2
- data/lib/aws-sdk-core/plugins/stub_responses.rb +20 -7
- data/lib/aws-sdk-core/plugins/transfer_encoding.rb +51 -0
- data/lib/aws-sdk-core/plugins/user_agent.rb +4 -8
- data/lib/aws-sdk-core/process_credentials.rb +9 -3
- data/lib/aws-sdk-core/shared_config.rb +95 -125
- data/lib/aws-sdk-core/structure.rb +1 -2
- data/lib/aws-sdk-core/stubbing/protocols/rest.rb +19 -0
- data/lib/aws-sdk-core/stubbing/stub_data.rb +13 -4
- data/lib/aws-sdk-core/util.rb +4 -0
- data/lib/aws-sdk-core/waiters/waiter.rb +2 -2
- data/lib/aws-sdk-core/xml/error_handler.rb +26 -3
- data/lib/aws-sdk-sts.rb +7 -4
- data/lib/aws-sdk-sts/client.rb +1109 -459
- data/lib/aws-sdk-sts/client_api.rb +67 -0
- data/lib/aws-sdk-sts/customizations.rb +2 -0
- data/lib/aws-sdk-sts/errors.rb +150 -0
- data/lib/aws-sdk-sts/plugins/sts_regional_endpoints.rb +32 -0
- data/lib/aws-sdk-sts/presigner.rb +67 -0
- data/lib/aws-sdk-sts/resource.rb +1 -0
- data/lib/aws-sdk-sts/types.rb +736 -176
- data/lib/seahorse.rb +9 -0
- data/lib/seahorse/client/async_base.rb +50 -0
- data/lib/seahorse/client/async_response.rb +62 -0
- data/lib/seahorse/client/base.rb +4 -2
- data/lib/seahorse/client/configuration.rb +4 -2
- data/lib/seahorse/client/events.rb +1 -1
- data/lib/seahorse/client/h2/connection.rb +246 -0
- data/lib/seahorse/client/h2/handler.rb +151 -0
- data/lib/seahorse/client/handler_list_entry.rb +2 -2
- data/lib/seahorse/client/http/async_response.rb +42 -0
- data/lib/seahorse/client/http/response.rb +13 -8
- data/lib/seahorse/client/logging/formatter.rb +4 -2
- data/lib/seahorse/client/net_http/connection_pool.rb +19 -20
- data/lib/seahorse/client/net_http/handler.rb +7 -1
- data/lib/seahorse/client/net_http/patches.rb +7 -1
- data/lib/seahorse/client/networking_error.rb +28 -0
- data/lib/seahorse/client/plugin.rb +5 -4
- data/lib/seahorse/client/plugins/content_length.rb +5 -2
- data/lib/seahorse/client/plugins/h2.rb +64 -0
- data/lib/seahorse/client/response.rb +3 -5
- data/lib/seahorse/model/api.rb +4 -0
- data/lib/seahorse/model/operation.rb +4 -0
- data/lib/seahorse/model/shapes.rb +2 -2
- metadata +43 -10
data/lib/aws-sdk-core/json.rb
CHANGED
@@ -7,28 +7,24 @@ require_relative 'json/parser'
|
|
7
7
|
module Aws
|
8
8
|
# @api private
|
9
9
|
module Json
|
10
|
-
|
11
10
|
class ParseError < StandardError
|
12
|
-
|
13
11
|
def initialize(error)
|
14
12
|
@error = error
|
15
13
|
super(error.message)
|
16
14
|
end
|
17
15
|
|
18
16
|
attr_reader :error
|
19
|
-
|
20
17
|
end
|
21
18
|
|
22
19
|
class << self
|
23
|
-
|
24
20
|
def load(json)
|
25
21
|
ENGINE.load(json, *ENGINE_LOAD_OPTIONS)
|
26
|
-
rescue
|
27
|
-
raise ParseError
|
22
|
+
rescue *ENGINE_ERRORS => e
|
23
|
+
raise ParseError, e
|
28
24
|
end
|
29
25
|
|
30
26
|
def load_file(path)
|
31
|
-
|
27
|
+
load(File.open(path, 'r', encoding: 'UTF-8', &:read))
|
32
28
|
end
|
33
29
|
|
34
30
|
def dump(value)
|
@@ -39,28 +35,31 @@ module Aws
|
|
39
35
|
|
40
36
|
def oj_engine
|
41
37
|
require 'oj'
|
42
|
-
[
|
38
|
+
[
|
39
|
+
Oj,
|
40
|
+
[{ mode: :compat, symbol_keys: false }],
|
41
|
+
[{ mode: :compat }],
|
42
|
+
oj_parse_error
|
43
|
+
]
|
43
44
|
rescue LoadError
|
44
45
|
false
|
45
46
|
end
|
46
47
|
|
47
48
|
def json_engine
|
48
|
-
[JSON, [], [], JSON::ParserError]
|
49
|
+
[JSON, [], [], [JSON::ParserError]]
|
49
50
|
end
|
50
51
|
|
51
52
|
def oj_parse_error
|
52
53
|
if Oj.const_defined?('ParseError')
|
53
|
-
Oj::ParseError
|
54
|
+
[Oj::ParseError, EncodingError, JSON::ParserError]
|
54
55
|
else
|
55
|
-
SyntaxError
|
56
|
+
[SyntaxError]
|
56
57
|
end
|
57
58
|
end
|
58
|
-
|
59
59
|
end
|
60
60
|
|
61
61
|
# @api private
|
62
|
-
ENGINE, ENGINE_LOAD_OPTIONS, ENGINE_DUMP_OPTIONS,
|
62
|
+
ENGINE, ENGINE_LOAD_OPTIONS, ENGINE_DUMP_OPTIONS, ENGINE_ERRORS =
|
63
63
|
oj_engine || json_engine
|
64
|
-
|
65
64
|
end
|
66
65
|
end
|
@@ -17,9 +17,10 @@ module Aws
|
|
17
17
|
json = Json.load(body)
|
18
18
|
code = error_code(json, context)
|
19
19
|
message = error_message(code, json)
|
20
|
-
|
20
|
+
data = parse_error_data(context, code)
|
21
|
+
[code, message, data]
|
21
22
|
rescue Json::ParseError
|
22
|
-
[http_status_error_code(context), '']
|
23
|
+
[http_status_error_code(context), '', EmptyStructure.new]
|
23
24
|
end
|
24
25
|
|
25
26
|
def error_code(json, context)
|
@@ -41,6 +42,22 @@ module Aws
|
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
45
|
+
def parse_error_data(context, code)
|
46
|
+
data = EmptyStructure.new
|
47
|
+
if error_rules = context.operation.errors
|
48
|
+
error_rules.each do |rule|
|
49
|
+
# match modeled shape name with the type(code) only
|
50
|
+
# some type(code) might contains invalid characters
|
51
|
+
# such as ':' (efs) etc
|
52
|
+
match = rule.shape.name == code.gsub(/[^^a-zA-Z0-9]/, '')
|
53
|
+
if match && rule.shape.members.any?
|
54
|
+
data = Parser.new(rule).parse(context.http_response.body_contents)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
data
|
59
|
+
end
|
60
|
+
|
44
61
|
end
|
45
62
|
end
|
46
63
|
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
|
@@ -171,7 +171,13 @@ module Aws
|
|
171
171
|
end
|
172
172
|
|
173
173
|
def _http_response_body(response)
|
174
|
-
|
174
|
+
if response.context.http_response.body.respond_to?(:rewind)
|
175
|
+
@param_formatter.summarize(
|
176
|
+
response.context.http_response.body_contents
|
177
|
+
)
|
178
|
+
else
|
179
|
+
''
|
180
|
+
end
|
175
181
|
end
|
176
182
|
|
177
183
|
def _error_class(response)
|
@@ -7,11 +7,11 @@ module Aws
|
|
7
7
|
|
8
8
|
# A managed list of sensitive parameters that should be filtered from
|
9
9
|
# logs. This is updated automatically as part of each release. See the
|
10
|
-
# `tasks/sensitive.rake` for more information.
|
10
|
+
# `tasks/update-sensitive-params.rake` for more information.
|
11
11
|
#
|
12
12
|
# @api private
|
13
13
|
# begin
|
14
|
-
SENSITIVE = [:access_token, :account_name, :account_password, :address, :admin_contact, :artifact_credentials, :auth_code, :authentication_token, :authorization_result, :backup_plan_tags, :backup_vault_tags, :base_32_string_seed, :body, :bot_configuration, :cause, :client_id, :client_secret, :configuration, :copy_source_sse_customer_key, :credentials, :custom_attributes, :db_password, :definition, :description, :display_name, :email, :email_address, :email_message, :embed_url, :error, :feedback_token, :file, :first_name, :id, :id_token, :input, :input_text, :key_id, :key_store_password, :kms_key_id, :kms_master_key_id, :last_name, :local_console_password, :master_account_email, :master_user_password, :message, :name, :new_password, :notes, :old_password, :output, :owner_information, :parameters, :passphrase, :password, :payload, :phone_number, :plaintext, :previous_password, :primary_email, :private_key, :proposed_password, :public_key, :qr_code_png, :query, :recovery_point_tags, :refresh_token, :registrant_contact, :request_attributes, :search_query, :secret_access_key, :secret_binary, :secret_code, :secret_hash, :secret_string, :service_password, :session_attributes, :share_notes, :shared_secret, :slots, :sse_customer_key, :ssekms_key_id, :status_message, :tag_key_list, :tags, :task_parameters, :tech_contact, :temporary_password, :text, :token, :trust_password, :upload_credentials, :upload_url, :user_email, :user_name, :username, :value, :values, :variables, :zip_file]
|
14
|
+
SENSITIVE = [:access_token, :account_name, :account_password, :address, :admin_contact, :admin_password, :alexa_for_business_room_arn, :artifact_credentials, :auth_code, :authentication_token, :authorization_result, :backup_plan_tags, :backup_vault_tags, :base_32_string_seed, :block, :block_address, :block_data, :blocks, :body, :bot_configuration, :bot_email, :calling_name, :cause, :client_id, :client_request_token, :client_secret, :comment, :configuration, :copy_source_sse_customer_key, :credentials, :current_password, :custom_attributes, :custom_private_key, :db_password, :default_phone_number, :definition, :description, :destination_access_token, :digest_tip_address, :display_name, :domain_signing_private_key, :e164_phone_number, :email, :email_address, :email_message, :embed_url, :error, :external_meeting_id, :external_model_endpoint_data_blobs, :external_user_id, :fall_back_phone_number, :feedback_token, :file, :first_name, :full_name, :host_key, :id, :id_token, :input, :input_text, :ion_text, :join_token, :key, :key_id, :key_material, :key_store_password, :kms_key_id, :kms_master_key_id, :lambda_function_arn, :last_name, :local_console_password, :master_account_email, :master_user_name, :master_user_password, :meeting_host_id, :message, :metadata, :name, :new_password, :next_password, :notes, :number, :old_password, :outbound_events_https_endpoint, :output, :owner_information, :parameters, :passphrase, :password, :payload, :phone_number, :plaintext, :previous_password, :primary_email, :primary_provisioned_number, :private_key, :private_key_plaintext, :proof, :proposed_password, :proxy_phone_number, :public_key, :qr_code_png, :query, :random_password, :recovery_point_tags, :refresh_token, :registrant_contact, :request_attributes, :resource_arn, :restore_metadata, :revision, :search_query, :secret_access_key, :secret_binary, :secret_code, :secret_hash, :secret_string, :secret_to_authenticate_initiator, :secret_to_authenticate_target, :security_token, :service_password, :session_attributes, :session_token, :share_notes, :shared_secret, :slots, :sns_topic_arn, :source_access_token, :sqs_queue_arn, :sse_customer_key, :ssekms_encryption_context, :ssekms_key_id, :status_message, :tag_key_list, :tags, :target_address, :task_parameters, :tech_contact, :temporary_password, :text, :token, :trust_password, :type, :upload_credentials, :upload_url, :uri, :user_data, :user_email, :user_name, :user_password, :username, :value, :values, :variables, :vpn_psk, :zip_file]
|
15
15
|
# end
|
16
16
|
|
17
17
|
def initialize(options = {})
|
@@ -31,7 +31,7 @@ module Aws
|
|
31
31
|
def filter_hash(values)
|
32
32
|
filtered = {}
|
33
33
|
values.each_pair do |key, value|
|
34
|
-
filtered[key] = @filters.
|
34
|
+
filtered[key] = @filters.any? { |f| f.to_s.casecmp(key.to_s).zero? } ? '[FILTERED]' : filter(value)
|
35
35
|
end
|
36
36
|
filtered
|
37
37
|
end
|
@@ -1,32 +1,46 @@
|
|
1
1
|
module Aws
|
2
2
|
|
3
|
-
# Decorates a {Seahorse::Client::Response} with paging methods
|
3
|
+
# Decorates a {Seahorse::Client::Response} with paging convenience methods.
|
4
|
+
# Some AWS calls provide paged responses to limit the amount of data returned
|
5
|
+
# with each response. To optimize for latency, some APIs may return an
|
6
|
+
# inconsistent number of responses per page. You should rely on the values of
|
7
|
+
# the `next_page?` method or using enumerable methods such as `each`
|
8
|
+
# rather than the number of items returned to iterate through results.
|
9
|
+
# See below for examples.
|
4
10
|
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
#
|
11
|
+
# # Paged Responses Are Enumerable
|
12
|
+
# The simplest way to handle paged response data is to use the built-in
|
13
|
+
# enumerator in the response object, as shown in the following example.
|
8
14
|
#
|
9
|
-
#
|
10
|
-
# resp = resp.next_page
|
11
|
-
# resp.last_page?
|
12
|
-
# #=> true
|
15
|
+
# s3 = Aws::S3::Client.new
|
13
16
|
#
|
14
|
-
#
|
15
|
-
#
|
17
|
+
# s3.list_objects(bucket:'aws-sdk').each do |response|
|
18
|
+
# puts response.contents.map(&:key)
|
19
|
+
# end
|
16
20
|
#
|
17
|
-
#
|
21
|
+
# This yields one response object per API call made, and enumerates objects
|
22
|
+
# in the named bucket. The SDK retrieves additional pages of data to
|
23
|
+
# complete the request.
|
18
24
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
+
# # Handling Paged Responses Manually
|
26
|
+
# To handle paging yourself, use the response’s `next_page?` method to verify
|
27
|
+
# there are more pages to retrieve, or use the last_page? method to verify
|
28
|
+
# there are no more pages to retrieve.
|
29
|
+
#
|
30
|
+
# If there are more pages, use the `next_page` method to retrieve the
|
31
|
+
# next page of results, as shown in the following example.
|
25
32
|
#
|
26
|
-
#
|
33
|
+
# s3 = Aws::S3::Client.new
|
27
34
|
#
|
28
|
-
#
|
29
|
-
#
|
35
|
+
# # Get the first page of data
|
36
|
+
# response = s3.list_objects(bucket:'aws-sdk')
|
37
|
+
#
|
38
|
+
# # Get additional pages
|
39
|
+
# while response.next_page? do
|
40
|
+
# response = response.next_page
|
41
|
+
# # Use the response data here...
|
42
|
+
# puts response.contents.map(&:key)
|
43
|
+
# end
|
30
44
|
#
|
31
45
|
module PageableResponse
|
32
46
|
|
@@ -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
|
@@ -138,7 +141,7 @@ module Aws
|
|
138
141
|
errors << expected_got(context, "true or false", value)
|
139
142
|
end
|
140
143
|
when BlobShape
|
141
|
-
unless
|
144
|
+
unless value.is_a?(String) || io_like?(value)
|
142
145
|
errors << expected_got(context, "a String or IO object", value)
|
143
146
|
end
|
144
147
|
else
|
@@ -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
|
@@ -158,9 +166,7 @@ module Aws
|
|
158
166
|
end
|
159
167
|
|
160
168
|
def io_like?(value)
|
161
|
-
value.respond_to?(:read) &&
|
162
|
-
value.respond_to?(:rewind) &&
|
163
|
-
value.respond_to?(:size)
|
169
|
+
value.respond_to?(:read) && value.respond_to?(:rewind)
|
164
170
|
end
|
165
171
|
|
166
172
|
def error_messages(errors)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'date'
|
2
|
+
require_relative 'retries/error_inspector'
|
2
3
|
|
3
4
|
module Aws
|
4
5
|
module Plugins
|
@@ -24,6 +25,16 @@ agent is running on, where client metrics will be published via UDP.
|
|
24
25
|
resolve_client_side_monitoring_port(cfg)
|
25
26
|
end
|
26
27
|
|
28
|
+
option(:client_side_monitoring_host,
|
29
|
+
default: "127.0.0.1",
|
30
|
+
doc_type: String,
|
31
|
+
docstring: <<-DOCS) do |cfg|
|
32
|
+
Allows you to specify the DNS hostname or IPv4 or IPv6 address that the client
|
33
|
+
side monitoring agent is running on, where client metrics will be published via UDP.
|
34
|
+
DOCS
|
35
|
+
resolve_client_side_monitoring_host(cfg)
|
36
|
+
end
|
37
|
+
|
27
38
|
option(:client_side_monitoring_publisher,
|
28
39
|
default: ClientSideMonitoring::Publisher,
|
29
40
|
doc_type: Aws::ClientSideMonitoring::Publisher,
|
@@ -49,6 +60,7 @@ all generated client side metrics. Defaults to an empty string.
|
|
49
60
|
handlers.add(Handler, step: :initialize)
|
50
61
|
publisher = config.client_side_monitoring_publisher
|
51
62
|
publisher.agent_port = config.client_side_monitoring_port
|
63
|
+
publisher.agent_host = config.client_side_monitoring_host
|
52
64
|
end
|
53
65
|
end
|
54
66
|
|
@@ -70,6 +82,19 @@ all generated client side metrics. Defaults to an empty string.
|
|
70
82
|
end
|
71
83
|
end
|
72
84
|
|
85
|
+
def self.resolve_client_side_monitoring_host(cfg)
|
86
|
+
env_source = ENV["AWS_CSM_HOST"]
|
87
|
+
env_source = nil if env_source == ""
|
88
|
+
cfg_source = Aws.shared_config.csm_host(profile: cfg.profile)
|
89
|
+
if env_source
|
90
|
+
env_source
|
91
|
+
elsif cfg_source
|
92
|
+
cfg_source
|
93
|
+
else
|
94
|
+
"127.0.0.1"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
73
98
|
def self.resolve_client_side_monitoring(cfg)
|
74
99
|
env_source = ENV["AWS_CSM_ENABLED"]
|
75
100
|
env_source = nil if env_source == ""
|
@@ -117,7 +142,7 @@ all generated client side metrics. Defaults to an empty string.
|
|
117
142
|
@handler.call(context)
|
118
143
|
rescue StandardError => e
|
119
144
|
# Handle SDK Exceptions
|
120
|
-
inspector =
|
145
|
+
inspector = Retries::ErrorInspector.new(
|
121
146
|
e,
|
122
147
|
context.http_response.status_code
|
123
148
|
)
|
@@ -151,7 +151,7 @@ the background every 60 secs (default). Defaults to `false`.
|
|
151
151
|
|
152
152
|
def self.resolve_endpoint_discovery(cfg)
|
153
153
|
env = ENV['AWS_ENABLE_ENDPOINT_DISCOVERY']
|
154
|
-
shared_cfg = Aws.shared_config.
|
154
|
+
shared_cfg = Aws.shared_config.endpoint_discovery_enabled(profile: cfg.profile)
|
155
155
|
Aws::Util.str_2_bool(env) || Aws::Util.str_2_bool(shared_cfg)
|
156
156
|
end
|
157
157
|
|
@@ -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
|
@@ -35,7 +35,14 @@ to test endpoints. This should be avalid HTTP(S) URI.
|
|
35
35
|
DOCS
|
36
36
|
endpoint_prefix = cfg.api.metadata['endpointPrefix']
|
37
37
|
if cfg.region && endpoint_prefix
|
38
|
-
|
38
|
+
if cfg.respond_to?(:sts_regional_endpoints)
|
39
|
+
sts_regional = cfg.sts_regional_endpoints
|
40
|
+
end
|
41
|
+
Aws::Partitions::EndpointProvider.resolve(
|
42
|
+
cfg.region,
|
43
|
+
endpoint_prefix,
|
44
|
+
sts_regional
|
45
|
+
)
|
39
46
|
end
|
40
47
|
end
|
41
48
|
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module Aws
|
2
|
+
module Plugins
|
3
|
+
module Retries
|
4
|
+
# @api private
|
5
|
+
# Used only in 'adaptive' retry mode
|
6
|
+
class ClientRateLimiter
|
7
|
+
MIN_CAPACITY = 1
|
8
|
+
MIN_FILL_RATE = 0.5
|
9
|
+
SMOOTH = 0.8
|
10
|
+
# How much to scale back after a throttling response
|
11
|
+
BETA = 0.7
|
12
|
+
# Controls how aggressively we scale up after being throttled
|
13
|
+
SCALE_CONSTANT = 0.4
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@mutex = Mutex.new
|
17
|
+
@fill_rate = nil
|
18
|
+
@max_capacity = nil
|
19
|
+
@current_capacity = 0
|
20
|
+
@last_timestamp = nil
|
21
|
+
@enabled = false
|
22
|
+
@measured_tx_rate = 0
|
23
|
+
@last_tx_rate_bucket = Aws::Util.monotonic_seconds
|
24
|
+
@request_count = 0
|
25
|
+
@last_max_rate = 0
|
26
|
+
@last_throttle_time = Aws::Util.monotonic_seconds
|
27
|
+
@calculated_rate = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
def token_bucket_acquire(amount, wait_to_fill = true)
|
31
|
+
# Client side throttling is not enabled until we see a
|
32
|
+
# throttling error
|
33
|
+
return unless @enabled
|
34
|
+
|
35
|
+
@mutex.synchronize do
|
36
|
+
token_bucket_refill
|
37
|
+
|
38
|
+
# Next see if we have enough capacity for the requested amount
|
39
|
+
while @current_capacity < amount
|
40
|
+
raise Aws::Errors::RetryCapacityNotAvailableError unless wait_to_fill
|
41
|
+
@mutex.sleep((amount - @current_capacity) / @fill_rate)
|
42
|
+
token_bucket_refill
|
43
|
+
end
|
44
|
+
@current_capacity -= amount
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def update_sending_rate(is_throttling_error)
|
49
|
+
@mutex.synchronize do
|
50
|
+
update_measured_rate
|
51
|
+
|
52
|
+
if is_throttling_error
|
53
|
+
rate_to_use = if @enabled
|
54
|
+
[@measured_tx_rate, @fill_rate].min
|
55
|
+
else
|
56
|
+
@measured_tx_rate
|
57
|
+
end
|
58
|
+
|
59
|
+
# The fill_rate is from the token bucket
|
60
|
+
@last_max_rate = rate_to_use
|
61
|
+
calculate_time_window
|
62
|
+
@last_throttle_time = Aws::Util.monotonic_seconds
|
63
|
+
@calculated_rate = cubic_throttle(rate_to_use)
|
64
|
+
enable_token_bucket
|
65
|
+
else
|
66
|
+
calculate_time_window
|
67
|
+
@calculated_rate = cubic_success(Aws::Util.monotonic_seconds)
|
68
|
+
end
|
69
|
+
|
70
|
+
new_rate = [@calculated_rate, 2 * @measured_tx_rate].min
|
71
|
+
token_bucket_update_rate(new_rate)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
def token_bucket_refill
|
78
|
+
timestamp = Aws::Util.monotonic_seconds
|
79
|
+
unless @last_timestamp
|
80
|
+
@last_timestamp = timestamp
|
81
|
+
return
|
82
|
+
end
|
83
|
+
|
84
|
+
fill_amount = (timestamp - @last_timestamp) * @fill_rate
|
85
|
+
@current_capacity = [
|
86
|
+
@max_capacity, @current_capacity + fill_amount
|
87
|
+
].min
|
88
|
+
|
89
|
+
@last_timestamp = timestamp
|
90
|
+
end
|
91
|
+
|
92
|
+
def token_bucket_update_rate(new_rps)
|
93
|
+
# Refill based on our current rate before we update to the
|
94
|
+
# new fill rate
|
95
|
+
token_bucket_refill
|
96
|
+
@fill_rate = [new_rps, MIN_FILL_RATE].max
|
97
|
+
@max_capacity = [new_rps, MIN_CAPACITY].max
|
98
|
+
# When we scale down we can't have a current capacity that exceeds our
|
99
|
+
# max_capacity.
|
100
|
+
@current_capacity = [@current_capacity, @max_capacity].min
|
101
|
+
end
|
102
|
+
|
103
|
+
def enable_token_bucket
|
104
|
+
@enabled = true
|
105
|
+
end
|
106
|
+
|
107
|
+
def update_measured_rate
|
108
|
+
t = Aws::Util.monotonic_seconds
|
109
|
+
time_bucket = (t * 2).floor / 2.0
|
110
|
+
@request_count += 1
|
111
|
+
if time_bucket > @last_tx_rate_bucket
|
112
|
+
current_rate = @request_count / (time_bucket - @last_tx_rate_bucket)
|
113
|
+
@measured_tx_rate = (current_rate * SMOOTH) +
|
114
|
+
(@measured_tx_rate * (1 - SMOOTH))
|
115
|
+
@request_count = 0
|
116
|
+
@last_tx_rate_bucket = time_bucket
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def calculate_time_window
|
121
|
+
# This is broken out into a separate calculation because it only
|
122
|
+
# gets updated when @last_max_rate changes so it can be cached.
|
123
|
+
@time_window = ((@last_max_rate * (1 - BETA)) / SCALE_CONSTANT)**(1.0 / 3)
|
124
|
+
end
|
125
|
+
|
126
|
+
def cubic_success(timestamp)
|
127
|
+
dt = timestamp - @last_throttle_time
|
128
|
+
(SCALE_CONSTANT * ((dt - @time_window)**3)) + @last_max_rate
|
129
|
+
end
|
130
|
+
|
131
|
+
def cubic_throttle(rate_to_use)
|
132
|
+
rate_to_use * BETA
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|