aws-sdk-core 2.11.175 → 2.11.176
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/apis/rekognition/2016-06-27/api-2.json +6 -1
- data/lib/aws-sdk-core.rb +7 -4
- data/lib/aws-sdk-core/api/builder.rb +24 -1
- data/lib/aws-sdk-core/api/customizations.rb +3 -1
- data/lib/aws-sdk-core/api/shape_map.rb +4 -0
- data/lib/aws-sdk-core/client.rb +3 -1
- data/lib/aws-sdk-core/client_stubs.rb +34 -0
- data/lib/aws-sdk-core/endpoint_cache.rb +188 -0
- data/lib/aws-sdk-core/errors.rb +24 -0
- data/lib/aws-sdk-core/plugins/endpoint_discovery.rb +167 -0
- data/lib/aws-sdk-core/plugins/endpoint_pattern.rb +62 -0
- data/lib/aws-sdk-core/plugins/regional_endpoint.rb +2 -0
- data/lib/aws-sdk-core/plugins/retry_errors.rb +21 -1
- data/lib/aws-sdk-core/plugins/s3_control_dns.rb +3 -1
- data/lib/aws-sdk-core/shared_config.rb +7 -0
- data/lib/aws-sdk-core/version.rb +1 -1
- data/lib/seahorse/client/configuration.rb +7 -1
- data/lib/seahorse/model/api.rb +4 -0
- data/lib/seahorse/model/operation.rb +9 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0071e4fe3106f7b8a5536ba25a6460aa2b87dbee
|
4
|
+
data.tar.gz: 7cb903f9379b80c8864c6a5e71ed7f46af7f8138
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2c4f2bf73e0cae8cea8d73d69eee330177c1f78b869fe58f4722ebeb667ef5da961c3847f948f84c5db534eddc63fa5602922d0ba61076b56ffba13062289fa
|
7
|
+
data.tar.gz: 93cef4a5cf1992ed98b4174775b9efd0761abfefb212e24d7d284eabe06c6f43a5f9661a9951df438f2796b2712746ffc37d75f1dc7d594a44306452bfd7e515
|
@@ -1511,7 +1511,12 @@
|
|
1511
1511
|
"mouthUp",
|
1512
1512
|
"mouthDown",
|
1513
1513
|
"leftPupil",
|
1514
|
-
"rightPupil"
|
1514
|
+
"rightPupil",
|
1515
|
+
"upperJawlineLeft",
|
1516
|
+
"midJawlineLeft",
|
1517
|
+
"chinBottom",
|
1518
|
+
"midJawlineRight",
|
1519
|
+
"upperJawlineRight"
|
1515
1520
|
]
|
1516
1521
|
},
|
1517
1522
|
"Landmarks":{
|
data/lib/aws-sdk-core.rb
CHANGED
@@ -200,6 +200,7 @@ module Aws
|
|
200
200
|
autoload :EagerLoader, 'aws-sdk-core/eager_loader'
|
201
201
|
autoload :ECSCredentials, 'aws-sdk-core/ecs_credentials'
|
202
202
|
autoload :EndpointProvider, 'aws-sdk-core/endpoint_provider'
|
203
|
+
autoload :EndpointCache, 'aws-sdk-core/endpoint_cache'
|
203
204
|
autoload :Errors, 'aws-sdk-core/errors'
|
204
205
|
autoload :IniParser, 'aws-sdk-core/ini_parser'
|
205
206
|
autoload :InstanceProfileCredentials, 'aws-sdk-core/instance_profile_credentials'
|
@@ -259,6 +260,8 @@ module Aws
|
|
259
260
|
autoload :HelpfulSocketErrors, 'aws-sdk-core/plugins/helpful_socket_errors'
|
260
261
|
autoload :IdempotencyToken, 'aws-sdk-core/plugins/idempotency_token'
|
261
262
|
autoload :JsonvalueConverter, 'aws-sdk-core/plugins/jsonvalue_converter'
|
263
|
+
autoload :EndpointDiscovery, 'aws-sdk-core/plugins/endpoint_discovery'
|
264
|
+
autoload :EndpointPattern, 'aws-sdk-core/plugins/endpoint_pattern'
|
262
265
|
autoload :Logging, 'aws-sdk-core/plugins/logging'
|
263
266
|
autoload :MachineLearningPredictEndpoint, 'aws-sdk-core/plugins/machine_learning_predict_endpoint'
|
264
267
|
autoload :ParamConverter, 'aws-sdk-core/plugins/param_converter'
|
@@ -575,10 +578,10 @@ module Aws
|
|
575
578
|
service_added do |name, svc_module, options|
|
576
579
|
if paginators = options[:paginators]
|
577
580
|
paginators = Json.load_file(paginators) unless Hash === paginators
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
581
|
+
paginators['pagination'].each do |n, rules|
|
582
|
+
op_name = Seahorse::Util.underscore(n)
|
583
|
+
operation = svc_module::Client.api.operation(op_name)
|
584
|
+
operation[:pager] = Pager.new(rules)
|
582
585
|
end
|
583
586
|
end
|
584
587
|
end
|
@@ -58,9 +58,20 @@ module Aws
|
|
58
58
|
api = Seahorse::Model::Api.new
|
59
59
|
api.metadata = definition['metadata'] || {}
|
60
60
|
api.version = api.metadata['apiVersion']
|
61
|
+
if op = has_endpoint_operation?(definition['operations'])
|
62
|
+
api.endpoint_operation = op
|
63
|
+
end
|
61
64
|
api
|
62
65
|
end
|
63
66
|
|
67
|
+
def has_endpoint_operation?(ops)
|
68
|
+
return nil if ops.nil?
|
69
|
+
ops.each do |name, op|
|
70
|
+
return underscore(name) if op['endpointoperation']
|
71
|
+
end
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
|
64
75
|
def build_shape_map(definition, api, docs)
|
65
76
|
shapes = definition['shapes'] || {}
|
66
77
|
api.metadata['shapes'] = ShapeMap.new(shapes, docs: docs)
|
@@ -76,17 +87,29 @@ module Aws
|
|
76
87
|
def build_operation(name, definition, shapes, docs)
|
77
88
|
http = definition['http'] || {}
|
78
89
|
op = Seahorse::Model::Operation.new
|
79
|
-
op.name = name
|
90
|
+
op.name = definition['name'] || name
|
80
91
|
op.http_method = http['method']
|
81
92
|
op.http_request_uri = http['requestUri'] || '/'
|
82
93
|
op.documentation = docs.operation_docs(name)
|
83
94
|
op.deprecated = !!definition['deprecated']
|
95
|
+
op.endpoint_operation = !!definition['endpointoperation']
|
84
96
|
op.input = shapes.shape_ref(definition['input'])
|
85
97
|
op.output = shapes.shape_ref(definition['output'])
|
86
98
|
op['authtype'] = definition['authtype'] unless definition['authtype'].nil?
|
87
99
|
(definition['errors'] || []).each do |error|
|
88
100
|
op.errors << shapes.shape_ref(error)
|
89
101
|
end
|
102
|
+
if definition['endpointdiscovery']
|
103
|
+
op.endpoint_discovery = {}
|
104
|
+
definition['endpointdiscovery'].each do |k, v|
|
105
|
+
op.endpoint_discovery[k] = v
|
106
|
+
end
|
107
|
+
elsif definition['endpoint']
|
108
|
+
op.endpoint_pattern = {}
|
109
|
+
definition['endpoint'].each do |k, v|
|
110
|
+
op.endpoint_pattern[k] = v
|
111
|
+
end
|
112
|
+
end
|
90
113
|
op
|
91
114
|
end
|
92
115
|
|
@@ -94,7 +94,9 @@ module Aws
|
|
94
94
|
plugins('Amazon CloudSearch Domain',
|
95
95
|
add: %w(Aws::Plugins::CSDConditionalSigning
|
96
96
|
Aws::Plugins::CSDSwitchToPost),
|
97
|
-
remove: %w(Aws::Plugins::RegionalEndpoint
|
97
|
+
remove: %w(Aws::Plugins::RegionalEndpoint
|
98
|
+
Aws::Plugins::EndpointPattern
|
99
|
+
Aws::Plugins::EndpointDiscovery),
|
98
100
|
)
|
99
101
|
|
100
102
|
plugins('Amazon DynamoDB', add: %w(
|
@@ -54,6 +54,10 @@ module Aws
|
|
54
54
|
location_name = meta.delete('locationName')
|
55
55
|
location_name ||= options[:member_name] unless location == 'headers'
|
56
56
|
documentation = @docs.shape_ref_docs(shape.name, options[:target])
|
57
|
+
if meta['hostLabel']
|
58
|
+
# used for endpoint pattern
|
59
|
+
meta['hostLabelName'] = options[:member_name]
|
60
|
+
end
|
57
61
|
|
58
62
|
ShapeRef.new(
|
59
63
|
shape: shape,
|
data/lib/aws-sdk-core/client.rb
CHANGED
@@ -17,7 +17,9 @@ module Aws
|
|
17
17
|
'Aws::Plugins::ResponsePaging',
|
18
18
|
'Aws::Plugins::StubResponses',
|
19
19
|
'Aws::Plugins::IdempotencyToken',
|
20
|
-
'Aws::Plugins::JsonvalueConverter'
|
20
|
+
'Aws::Plugins::JsonvalueConverter',
|
21
|
+
'Aws::Plugins::EndpointDiscovery',
|
22
|
+
'Aws::Plugins::EndpointPattern'
|
21
23
|
]
|
22
24
|
|
23
25
|
# @api private
|
@@ -18,6 +18,19 @@ module Aws
|
|
18
18
|
end
|
19
19
|
@config.stub_responses = true
|
20
20
|
end
|
21
|
+
|
22
|
+
# When a client is stubbed allow the user to access the requests made
|
23
|
+
@api_requests = []
|
24
|
+
|
25
|
+
requests = @api_requests
|
26
|
+
self.handle do |context|
|
27
|
+
requests << {
|
28
|
+
operation_name: context.operation_name,
|
29
|
+
params: context.params,
|
30
|
+
context: context
|
31
|
+
}
|
32
|
+
@handler.call(context)
|
33
|
+
end
|
21
34
|
end
|
22
35
|
|
23
36
|
# Configures what data / errors should be returned from the named operation
|
@@ -167,6 +180,27 @@ module Aws
|
|
167
180
|
end
|
168
181
|
end
|
169
182
|
|
183
|
+
# Allows you to access all of the requests that the stubbed client has made
|
184
|
+
#
|
185
|
+
# @params [Boolean] exclude_presign Setting to true for filtering out not sent requests from
|
186
|
+
# generating presigned urls. Default to false.
|
187
|
+
# @return [Array] Returns an array of the api requests made, each request object contains the
|
188
|
+
# :operation_name, :params, and :context of the request.
|
189
|
+
# @raise [NotImplementedError] Raises `NotImplementedError` when the client is not stubbed
|
190
|
+
def api_requests(options = {})
|
191
|
+
if config.stub_responses
|
192
|
+
if options[:exclude_presign]
|
193
|
+
@api_requests.reject {|req| req[:context][:presigned_url] }
|
194
|
+
else
|
195
|
+
@api_requests
|
196
|
+
end
|
197
|
+
else
|
198
|
+
msg = 'This method is only implemented for stubbed clients, and is '
|
199
|
+
msg << 'available when you enable stubbing in the constructor with `stub_responses: true`'
|
200
|
+
raise NotImplementedError.new(msg)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
170
204
|
# Generates and returns stubbed response data from the named operation.
|
171
205
|
#
|
172
206
|
# s3 = Aws::S3::Client.new
|
@@ -0,0 +1,188 @@
|
|
1
|
+
module Aws
|
2
|
+
# @api private
|
3
|
+
# a LRU cache caching endpoints data
|
4
|
+
class EndpointCache
|
5
|
+
|
6
|
+
# default cache entries limit
|
7
|
+
MAX_ENTRIES = 1000
|
8
|
+
|
9
|
+
# default max threads pool size
|
10
|
+
MAX_THREADS = 10
|
11
|
+
|
12
|
+
def initialize(options = {})
|
13
|
+
@max_entries = options[:max_entries] || MAX_ENTRIES
|
14
|
+
@entries = {} # store endpoints
|
15
|
+
@max_threads = options[:max_threads] || MAX_THREADS
|
16
|
+
@pool = {} # store polling threads
|
17
|
+
@mutex = Mutex.new
|
18
|
+
@require_identifier = nil # whether endpoint operation support identifier
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Integer] Max size limit of cache
|
22
|
+
attr_reader :max_entries
|
23
|
+
|
24
|
+
# @return [Integer] Max count of polling threads
|
25
|
+
attr_reader :max_threads
|
26
|
+
|
27
|
+
# return [Hash] Polling threads pool
|
28
|
+
attr_reader :pool
|
29
|
+
|
30
|
+
# @param [String] key
|
31
|
+
# @return [Endpoint]
|
32
|
+
def [](key)
|
33
|
+
@mutex.synchronize do
|
34
|
+
# fetching an existing endpoint delete it and then append it
|
35
|
+
endpoint = @entries[key]
|
36
|
+
if endpoint
|
37
|
+
@entries.delete(key)
|
38
|
+
@entries[key] = endpoint
|
39
|
+
end
|
40
|
+
endpoint
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# @param [String] key
|
45
|
+
# @param [Hash] value
|
46
|
+
def []=(key, value)
|
47
|
+
@mutex.synchronize do
|
48
|
+
# delete the least recent used endpoint when cache is full
|
49
|
+
unless @entries.size < @max_entries
|
50
|
+
old_key, _ = @entries.shift
|
51
|
+
self.delete_polling_thread(old_key)
|
52
|
+
end
|
53
|
+
# delete old value if exists
|
54
|
+
@entries.delete(key)
|
55
|
+
@entries[key] = Endpoint.new(value.to_hash)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# checking whether an unexpired endpoint key exists in cache
|
60
|
+
# @param [String] key
|
61
|
+
# @return [Boolean]
|
62
|
+
def key?(key)
|
63
|
+
if @entries.key?(key) && (@entries[key].nil? || @entries[key].expired?)
|
64
|
+
self.delete(key)
|
65
|
+
end
|
66
|
+
@entries.key?(key)
|
67
|
+
end
|
68
|
+
|
69
|
+
# checking whether an polling thread exist for the key
|
70
|
+
# @param [String] key
|
71
|
+
# @return [Boolean]
|
72
|
+
def threads_key?(key)
|
73
|
+
@pool.key?(key)
|
74
|
+
end
|
75
|
+
|
76
|
+
# remove entry only
|
77
|
+
# @param [String] key
|
78
|
+
def delete(key)
|
79
|
+
@mutex.synchronize do
|
80
|
+
@entries.delete(key)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# kill the old polling thread and remove it from pool
|
85
|
+
# @param [String] key
|
86
|
+
def delete_polling_thread(key)
|
87
|
+
Thread.kill(@pool[key]) if self.threads_key?(key)
|
88
|
+
@pool.delete(key)
|
89
|
+
end
|
90
|
+
|
91
|
+
# update cache with requests (using service endpoint operation)
|
92
|
+
# to fetch endpoint list (with identifiers when available)
|
93
|
+
# @param [String] key
|
94
|
+
# @param [RequestContext] ctx
|
95
|
+
def update(key, ctx)
|
96
|
+
resp = _request_endpoint(ctx)
|
97
|
+
if resp && resp.endpoints
|
98
|
+
resp.endpoints.each { |e| self[key] = e }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# extract the key to be used in the cache from request context
|
103
|
+
# @param [RequestContext] ctx
|
104
|
+
# @return [String]
|
105
|
+
def extract_key(ctx)
|
106
|
+
parts = []
|
107
|
+
# fetching from cred provider directly gives warnings
|
108
|
+
parts << ctx.config.credentials.credentials.access_key_id
|
109
|
+
if _endpoint_operation_identifier(ctx)
|
110
|
+
parts << ctx.operation_name
|
111
|
+
ctx.operation.input.shape.members.inject(parts) do |p, (name, ref)|
|
112
|
+
p << ctx.params[name] if ref["endpointdiscoveryid"]
|
113
|
+
p
|
114
|
+
end
|
115
|
+
end
|
116
|
+
parts.join('_')
|
117
|
+
end
|
118
|
+
|
119
|
+
# update polling threads pool
|
120
|
+
# param [String] key
|
121
|
+
# param [Thread] thread
|
122
|
+
def update_polling_pool(key, thread)
|
123
|
+
unless @pool.size < @max_threads
|
124
|
+
_, thread = @pool.shift
|
125
|
+
Thread.kill(thread)
|
126
|
+
end
|
127
|
+
@pool[key] = thread
|
128
|
+
end
|
129
|
+
|
130
|
+
# kill all polling threads
|
131
|
+
def stop_polling!
|
132
|
+
@pool.each { |_, t| Thread.kill(t) }
|
133
|
+
@pool = {}
|
134
|
+
end
|
135
|
+
|
136
|
+
private
|
137
|
+
|
138
|
+
def _request_endpoint(ctx)
|
139
|
+
params = {}
|
140
|
+
if _endpoint_operation_identifier(ctx)
|
141
|
+
# build identifier params when available
|
142
|
+
params[:operation] = ctx.operation.name
|
143
|
+
ctx.operation.input.shape.members.inject(params) do |p, (name, ref)|
|
144
|
+
if ref["endpointdiscoveryid"]
|
145
|
+
p[:identifiers] ||= {}
|
146
|
+
p[:identifiers][ref.location_name] = ctx.params[name]
|
147
|
+
end
|
148
|
+
p
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
begin
|
153
|
+
endpoint_operation_name = ctx.config.api.endpoint_operation
|
154
|
+
ctx.client.send(endpoint_operation_name, params)
|
155
|
+
rescue Aws::Errors::ServiceError
|
156
|
+
nil
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def _endpoint_operation_identifier(ctx)
|
161
|
+
return @require_identifier unless @require_identifier.nil?
|
162
|
+
operation_name = ctx.config.api.endpoint_operation
|
163
|
+
operation = ctx.config.api.operation(operation_name)
|
164
|
+
@require_identifier = operation.input.shape.members.any?
|
165
|
+
end
|
166
|
+
|
167
|
+
class Endpoint
|
168
|
+
|
169
|
+
# default endpoint cache time, 1 minute
|
170
|
+
CACHE_PERIOD = 1
|
171
|
+
|
172
|
+
def initialize(options)
|
173
|
+
@address = options.fetch(:address)
|
174
|
+
@cache_period = options[:cache_period_in_minutes] || CACHE_PERIOD
|
175
|
+
@created_time = Time.now
|
176
|
+
end
|
177
|
+
|
178
|
+
# [String] valid URI address (with path)
|
179
|
+
attr_reader :address
|
180
|
+
|
181
|
+
def expired?
|
182
|
+
Time.now - @created_time > @cache_period * 60
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
186
|
+
|
187
|
+
end
|
188
|
+
end
|
data/lib/aws-sdk-core/errors.rb
CHANGED
@@ -53,6 +53,30 @@ module Aws
|
|
53
53
|
# Raised when a {Service} is constructed and region is not specified.
|
54
54
|
class MissingRegionError < ArgumentError; end
|
55
55
|
|
56
|
+
# Rasied when endpoint discovery failed for operations
|
57
|
+
# that requires endpoints from endpoint discovery
|
58
|
+
class EndpointDiscoveryError < RuntimeError
|
59
|
+
def initialize(*args)
|
60
|
+
msg = 'Endpoint discovery failed for the operation or discovered endpoint is not working, '\
|
61
|
+
'request will keep failing until endpoint discovery succeeds or :endpoint option is provided.'
|
62
|
+
super(msg)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# raised when hostLabel member is not provided
|
67
|
+
# at operation input when endpoint trait is available
|
68
|
+
# with 'hostPrefix' requirement
|
69
|
+
class MissingEndpointHostLabelValue < RuntimeError
|
70
|
+
|
71
|
+
def initialize(name)
|
72
|
+
msg = "Missing required parameter #{name} to construct"\
|
73
|
+
" endpoint host prefix. You can disable host prefix by"\
|
74
|
+
" setting :disable_host_prefix_injection to `true`."
|
75
|
+
super(msg)
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
56
80
|
# Raised when attempting to connect to an endpoint and a `SocketError`
|
57
81
|
# is received from the HTTP client. This error is typically the result
|
58
82
|
# of configuring an invalid `:region`.
|
@@ -0,0 +1,167 @@
|
|
1
|
+
module Aws
|
2
|
+
module Plugins
|
3
|
+
|
4
|
+
# Enables Endpoint Discovery per service when supported
|
5
|
+
#
|
6
|
+
# @seahorse.client.option [Boolean] :endpoint_discovery When
|
7
|
+
# set to `true`, endpoint discovery will be enabled for
|
8
|
+
# operations when available. Defaults to `false`.
|
9
|
+
#
|
10
|
+
# @seahorse.client.option [Integer] :endpoint_cache_max_entries
|
11
|
+
# Used for the maximum size limit of the LRU cache storing endpoints data
|
12
|
+
# for endpoint discovery enabled operations. Defaults to 1000.
|
13
|
+
#
|
14
|
+
# @seahorse.client.option [Integer] :endpoint_cache_max_threads
|
15
|
+
# Used for the maximum threads in use for polling endpoints to be cached,
|
16
|
+
# defaults to 10.
|
17
|
+
#
|
18
|
+
# @seahorse.client.option [Integer] :endpoint_cache_poll_interval
|
19
|
+
# When :endpoint_discovery and :active_endpoint_cache is enabled,
|
20
|
+
# Use this option to config the time interval in seconds for making
|
21
|
+
# requests fetching endpoints information. Defaults to 60 sec.
|
22
|
+
#
|
23
|
+
# @seahorse.client.option [Boolean] :active_endpoint_cache
|
24
|
+
# When set to `true`, a thread polling for endpoints will be running in
|
25
|
+
# the background every 60 secs (default). Defaults to `false`.
|
26
|
+
class EndpointDiscovery < Seahorse::Client::Plugin
|
27
|
+
|
28
|
+
option(:endpoint_discovery, false) do |cfg|
|
29
|
+
resolve_endpoint_discovery(cfg)
|
30
|
+
end
|
31
|
+
|
32
|
+
option(:endpoint_cache_max_entries, 1000)
|
33
|
+
|
34
|
+
option(:endpoint_cache_max_threads, 10)
|
35
|
+
|
36
|
+
option(:endpoint_cache_poll_interval, 60)
|
37
|
+
|
38
|
+
option(:endpoint_cache) do |cfg|
|
39
|
+
Aws::EndpointCache.new(
|
40
|
+
max_entries: cfg.endpoint_cache_max_entries,
|
41
|
+
max_threads: cfg.endpoint_cache_max_threads
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
option(:active_endpoint_cache, false)
|
46
|
+
|
47
|
+
def add_handlers(handlers, config)
|
48
|
+
handlers.add(Handler, priority: 90) if config.regional_endpoint
|
49
|
+
end
|
50
|
+
|
51
|
+
class Handler < Seahorse::Client::Handler
|
52
|
+
|
53
|
+
def call(context)
|
54
|
+
if context.operation.endpoint_operation
|
55
|
+
context.http_request.headers['x-amz-api-version'] = context.config.api.version
|
56
|
+
_apply_endpoint_discovery_user_agent(context)
|
57
|
+
elsif discovery_cfg = context.operation.endpoint_discovery
|
58
|
+
endpoint = _discover_endpoint(
|
59
|
+
context,
|
60
|
+
str_2_bool(discovery_cfg["required"])
|
61
|
+
)
|
62
|
+
context.http_request.endpoint = _valid_uri(endpoint.address) if endpoint
|
63
|
+
if endpoint || context.config.endpoint_discovery
|
64
|
+
_apply_endpoint_discovery_user_agent(context)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
@handler.call(context)
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def _valid_uri(address)
|
73
|
+
# returned address can be missing scheme
|
74
|
+
if address.start_with?('http')
|
75
|
+
URI.parse(address)
|
76
|
+
else
|
77
|
+
URI.parse("https://" + address)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def _apply_endpoint_discovery_user_agent(ctx)
|
82
|
+
if ctx.config.user_agent_suffix.nil?
|
83
|
+
ctx.config.user_agent_suffix = "endpoint-discovery"
|
84
|
+
elsif !ctx.config.user_agent_suffix.include? "endpoint-discovery"
|
85
|
+
ctx.config.user_agent_suffix += "endpoint-discovery"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def _discover_endpoint(ctx, required)
|
90
|
+
cache = ctx.config.endpoint_cache
|
91
|
+
key = cache.extract_key(ctx)
|
92
|
+
|
93
|
+
if required
|
94
|
+
# required for the operation
|
95
|
+
unless cache.key?(key)
|
96
|
+
cache.update(key, ctx)
|
97
|
+
end
|
98
|
+
endpoint = cache[key]
|
99
|
+
# hard fail if endpoint is not discovered
|
100
|
+
raise Aws::Errors::EndpointDiscoveryError.new unless endpoint
|
101
|
+
endpoint
|
102
|
+
elsif ctx.config.endpoint_discovery
|
103
|
+
# not required for the operation
|
104
|
+
# but enabled
|
105
|
+
if cache.key?(key)
|
106
|
+
cache[key]
|
107
|
+
elsif ctx.config.active_endpoint_cache
|
108
|
+
# enabled active cache pull
|
109
|
+
interval = ctx.config.endpoint_cache_poll_interval
|
110
|
+
if key.include?('_')
|
111
|
+
# identifier related, kill the previous polling thread by key
|
112
|
+
# because endpoint req params might be changed
|
113
|
+
cache.delete_polling_thread(key)
|
114
|
+
end
|
115
|
+
|
116
|
+
# start a thread for polling endpoints when non-exist
|
117
|
+
unless cache.threads_key?(key)
|
118
|
+
thread = Thread.new do
|
119
|
+
while !cache.key?(key) do
|
120
|
+
cache.update(key, ctx)
|
121
|
+
sleep(interval)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
cache.update_polling_pool(key, thread)
|
125
|
+
end
|
126
|
+
|
127
|
+
cache[key]
|
128
|
+
else
|
129
|
+
# disabled active cache pull
|
130
|
+
# attempt, buit fail soft
|
131
|
+
cache.update(key, ctx)
|
132
|
+
cache[key]
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def str_2_bool(str)
|
138
|
+
case str.to_s
|
139
|
+
when "true" then true
|
140
|
+
when "false" then false
|
141
|
+
else
|
142
|
+
nil
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
def self.resolve_endpoint_discovery(cfg)
|
151
|
+
env = ENV['AWS_ENABLE_ENDPOINT_DISCOVERY']
|
152
|
+
shared_cfg = Aws.shared_config.endpoint_discovery(profile: cfg.profile)
|
153
|
+
self.str_2_bool(env) || self.str_2_bool(shared_cfg)
|
154
|
+
end
|
155
|
+
|
156
|
+
def self.str_2_bool(str)
|
157
|
+
case str.to_s
|
158
|
+
when "true" then true
|
159
|
+
when "false" then false
|
160
|
+
else
|
161
|
+
nil
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Aws
|
2
|
+
module Plugins
|
3
|
+
|
4
|
+
# Disable host prefix per operation when available
|
5
|
+
#
|
6
|
+
# @seahorse.client.option [Boolean] :disable_host_prefix_injection
|
7
|
+
# Set to true to disable SDK automatically adding host prefix
|
8
|
+
# to default service endpoint when available.
|
9
|
+
#
|
10
|
+
class EndpointPattern < Seahorse::Client::Plugin
|
11
|
+
|
12
|
+
option(:disable_host_prefix_injection, false)
|
13
|
+
|
14
|
+
def add_handlers(handlers, config)
|
15
|
+
if config.regional_endpoint && !config.disable_host_prefix_injection
|
16
|
+
handlers.add(Handler, priority: 90)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Handler < Seahorse::Client::Handler
|
21
|
+
|
22
|
+
def call(context)
|
23
|
+
endpoint_trait = context.operation.endpoint_pattern
|
24
|
+
if endpoint_trait && !endpoint_trait.empty?
|
25
|
+
_apply_endpoint_trait(context, endpoint_trait)
|
26
|
+
end
|
27
|
+
@handler.call(context)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def _apply_endpoint_trait(context, trait)
|
33
|
+
# currently only support host pattern
|
34
|
+
ori_host = context.http_request.endpoint.host
|
35
|
+
if pattern = trait['hostPrefix']
|
36
|
+
host_prefix = pattern.gsub(/\{.+?\}/) do |label|
|
37
|
+
label = label.delete("{}")
|
38
|
+
_replace_label_value(
|
39
|
+
ori_host, label, context.operation.input, context.params)
|
40
|
+
end
|
41
|
+
context.http_request.endpoint.host = host_prefix + context.http_request.endpoint.host
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def _replace_label_value(ori, label, input_ref, params)
|
46
|
+
name = nil
|
47
|
+
input_ref.shape.members.each do |m_name, ref|
|
48
|
+
if ref['hostLabel'] && ref['hostLabelName'] == label
|
49
|
+
name = m_name
|
50
|
+
end
|
51
|
+
end
|
52
|
+
if name.nil? || params[name].nil?
|
53
|
+
raise Errors::MissingEndpointHostLabelValue.new(name)
|
54
|
+
end
|
55
|
+
params[name]
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -71,6 +71,25 @@ module Aws
|
|
71
71
|
(500..599).include?(@http_status_code)
|
72
72
|
end
|
73
73
|
|
74
|
+
def endpoint_discovery?(context)
|
75
|
+
return false unless context.operation.endpoint_discovery
|
76
|
+
|
77
|
+
if @http_status_code == 421 ||
|
78
|
+
extract_name(@error) == 'InvalidEndpointException'
|
79
|
+
@error = Errors::EndpointDiscoveryError.new
|
80
|
+
end
|
81
|
+
|
82
|
+
# When endpoint discovery error occurs
|
83
|
+
# evict the endpoint from cache
|
84
|
+
if @error.is_a?(Errors::EndpointDiscoveryError)
|
85
|
+
key = context.config.endpoint_cache.extract_key(context)
|
86
|
+
context.config.endpoint_cache.delete(key)
|
87
|
+
true
|
88
|
+
else
|
89
|
+
false
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
74
93
|
private
|
75
94
|
|
76
95
|
def extract_name(error)
|
@@ -135,7 +154,8 @@ module Aws
|
|
135
154
|
error.throttling_error? or
|
136
155
|
error.checksum? or
|
137
156
|
error.networking? or
|
138
|
-
error.server?
|
157
|
+
error.server? or
|
158
|
+
error.endpoint_discovery?(context)
|
139
159
|
end
|
140
160
|
|
141
161
|
def refreshable_credentials?(context)
|
@@ -128,6 +128,13 @@ module Aws
|
|
128
128
|
end
|
129
129
|
end
|
130
130
|
|
131
|
+
def endpoint_discovery(opts = {})
|
132
|
+
p = opts[:profile] || @profile_name
|
133
|
+
if @config_enabled && @parsed_config
|
134
|
+
@parsed_config.fetch(p, {})["endpoint_discovery_enabled"]
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
131
138
|
private
|
132
139
|
def credentials_present?
|
133
140
|
(@parsed_credentials && !@parsed_credentials.empty?) ||
|
data/lib/aws-sdk-core/version.rb
CHANGED
@@ -197,7 +197,13 @@ module Seahorse
|
|
197
197
|
|
198
198
|
def value_at(opt_name)
|
199
199
|
value = @struct[opt_name]
|
200
|
-
value.is_a?(Defaults)
|
200
|
+
if value.is_a?(Defaults)
|
201
|
+
# this config value is used by endpoint discovery etc
|
202
|
+
@struct[:regional_endpoint] = true if opt_name == :endpoint
|
203
|
+
resolve_defaults(opt_name, value)
|
204
|
+
else
|
205
|
+
value
|
206
|
+
end
|
201
207
|
end
|
202
208
|
|
203
209
|
def resolve_defaults(opt_name, defaults)
|
data/lib/seahorse/model/api.rb
CHANGED
@@ -5,6 +5,7 @@ module Seahorse
|
|
5
5
|
def initialize
|
6
6
|
@metadata = {}
|
7
7
|
@operations = {}
|
8
|
+
@endpoint_operation = nil
|
8
9
|
end
|
9
10
|
|
10
11
|
# @return [String, nil]
|
@@ -13,6 +14,9 @@ module Seahorse
|
|
13
14
|
# @return [Hash]
|
14
15
|
attr_accessor :metadata
|
15
16
|
|
17
|
+
# @return [Symbol|nil]
|
18
|
+
attr_accessor :endpoint_operation
|
19
|
+
|
16
20
|
def operations(&block)
|
17
21
|
if block_given?
|
18
22
|
@operations.each(&block)
|
@@ -22,9 +22,18 @@ module Seahorse
|
|
22
22
|
# @return [Boolean]
|
23
23
|
attr_accessor :deprecated
|
24
24
|
|
25
|
+
# @return [Boolean]
|
26
|
+
attr_accessor :endpoint_operation
|
27
|
+
|
28
|
+
# @return [Hash]
|
29
|
+
attr_accessor :endpoint_discovery
|
30
|
+
|
25
31
|
# @return [String, nil]
|
26
32
|
attr_accessor :documentation
|
27
33
|
|
34
|
+
# @return [Hash, nil]
|
35
|
+
attr_accessor :endpoint_pattern
|
36
|
+
|
28
37
|
# @return [ShapeRef, nil]
|
29
38
|
attr_accessor :input
|
30
39
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aws-sdk-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.11.
|
4
|
+
version: 2.11.176
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Amazon Web Services
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-11-
|
11
|
+
date: 2018-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jmespath
|
@@ -765,6 +765,7 @@ files:
|
|
765
765
|
- lib/aws-sdk-core/elastictranscoder.rb
|
766
766
|
- lib/aws-sdk-core/empty_structure.rb
|
767
767
|
- lib/aws-sdk-core/emr.rb
|
768
|
+
- lib/aws-sdk-core/endpoint_cache.rb
|
768
769
|
- lib/aws-sdk-core/endpoint_provider.rb
|
769
770
|
- lib/aws-sdk-core/errors.rb
|
770
771
|
- lib/aws-sdk-core/firehose.rb
|
@@ -848,6 +849,8 @@ files:
|
|
848
849
|
- lib/aws-sdk-core/plugins/dynamodb_simple_attributes.rb
|
849
850
|
- lib/aws-sdk-core/plugins/ec2_copy_encrypted_snapshot.rb
|
850
851
|
- lib/aws-sdk-core/plugins/ec2_region_validation.rb
|
852
|
+
- lib/aws-sdk-core/plugins/endpoint_discovery.rb
|
853
|
+
- lib/aws-sdk-core/plugins/endpoint_pattern.rb
|
851
854
|
- lib/aws-sdk-core/plugins/glacier_account_id.rb
|
852
855
|
- lib/aws-sdk-core/plugins/glacier_api_version.rb
|
853
856
|
- lib/aws-sdk-core/plugins/glacier_checksums.rb
|