aws-sdk-code-generator 0.5.0.pre → 0.6.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/aws-sdk-code-generator/api.rb +2 -1
  3. data/lib/aws-sdk-code-generator/client_operation_documentation.rb +2 -1
  4. data/lib/aws-sdk-code-generator/client_operation_list.rb +4 -0
  5. data/lib/aws-sdk-code-generator/code_builder.rb +2 -2
  6. data/lib/aws-sdk-code-generator/endpoint_parameter.rb +190 -0
  7. data/lib/aws-sdk-code-generator/helper.rb +11 -1
  8. data/lib/aws-sdk-code-generator/plugin_list.rb +3 -1
  9. data/lib/aws-sdk-code-generator/resource_batch_action_code.rb +1 -1
  10. data/lib/aws-sdk-code-generator/resource_client_request.rb +1 -1
  11. data/lib/aws-sdk-code-generator/resource_waiter.rb +1 -1
  12. data/lib/aws-sdk-code-generator/service.rb +65 -17
  13. data/lib/aws-sdk-code-generator/views/client_api_module.rb +32 -15
  14. data/lib/aws-sdk-code-generator/views/endpoint_parameters_class.rb +6 -50
  15. data/lib/aws-sdk-code-generator/views/endpoint_provider_class.rb +9 -0
  16. data/lib/aws-sdk-code-generator/views/endpoints_module.rb +18 -124
  17. data/lib/aws-sdk-code-generator/views/endpoints_plugin.rb +46 -4
  18. data/lib/aws-sdk-code-generator/views/errors_module.rb +21 -0
  19. data/lib/aws-sdk-code-generator/views/features/smoke.rb +5 -4
  20. data/lib/aws-sdk-code-generator/views/rbs/client_class.rb +1 -1
  21. data/lib/aws-sdk-code-generator/views/rbs/types_module.rb +2 -2
  22. data/lib/aws-sdk-code-generator/views/resource_class.rb +22 -0
  23. data/lib/aws-sdk-code-generator/views/root_resource_class.rb +19 -0
  24. data/lib/aws-sdk-code-generator/views/service_module.rb +41 -27
  25. data/lib/aws-sdk-code-generator/views/spec/endpoint_provider_spec_class.rb +20 -11
  26. data/lib/aws-sdk-code-generator/views/types_module.rb +28 -4
  27. data/lib/aws-sdk-code-generator.rb +12 -0
  28. data/templates/async_client_class.mustache +6 -1
  29. data/templates/client_api_module.mustache +7 -0
  30. data/templates/client_class.mustache +11 -3
  31. data/templates/endpoint_parameters_class.mustache +16 -13
  32. data/templates/endpoints_module.mustache +18 -11
  33. data/templates/endpoints_plugin.mustache +34 -18
  34. data/templates/errors_module.mustache +5 -0
  35. data/templates/resource_class.mustache +6 -1
  36. data/templates/root_resource_class.mustache +5 -0
  37. data/templates/service_module.mustache +13 -3
  38. data/templates/spec/endpoint_provider_spec_class.mustache +1 -1
  39. data/templates/types_module.mustache +4 -0
  40. metadata +6 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3332820d3c044afc9813a785b511cc25fcce3581477a3f05f860bf49bb225ffe
4
- data.tar.gz: '09ed058cda2368a87496efc47772d019dfb3f1911732c344c9146af6a51f68fe'
3
+ metadata.gz: 7a56cc48e83d1c1b3f3c4abf956e29fdd7adb2aed45c2ff8d69b8489ad569518
4
+ data.tar.gz: 5ff9d87ff0f38a08370358ccccd6bf9e69f0e77da2bcba60b1042501fead60d7
5
5
  SHA512:
6
- metadata.gz: 4de3ecc3f1f0ff599143e79808c395aa82319da3af73f9c9b87c1d6526f438feb4471e52d68e8559a027223d523c21d89250e2e212c83a53a52c41726a8df7e3
7
- data.tar.gz: 9b6d2456bb9bd9fbff1e7beb50c0f93a8137e1eb249cf931107e0f1dca7dc0f92b57da5d011a199900c03a5cd6d6f53b7fd7387cafead162f7aa892dffaea76f
6
+ metadata.gz: be96b1aa147f0e2a8bdf45c383feaa21511d81c6129e648cc5fc488f1f19808aee62ec78916c2f9a9a5e3060dcc12bdb61a1e9a890af21c3ee610438997e3798
7
+ data.tar.gz: c4f0731f69dd91ddcd4498363cb149ee361cfe452c8cbe6c8e7e05d85586bf11b84494a4ececd41f0308ce1dfb612aa3e032575f9abca3566f6476f6857d1a67
@@ -131,7 +131,8 @@ module AwsSdkCodeGenerator
131
131
  # @return [Boolean]
132
132
  def streaming_input?(shape, operation)
133
133
  shape['streaming'] && operation &&
134
- operation['authtype'] == "v4-unsigned-body"
134
+ (operation['unsignedPayload'] ||
135
+ operation['authtype'] == 'v4-unsigned-body')
135
136
  end
136
137
 
137
138
  def plural?(resource)
@@ -16,6 +16,7 @@ module AwsSdkCodeGenerator
16
16
  @method_name = options.fetch(:method_name)
17
17
  @operation = options.fetch(:operation)
18
18
  @api = options.fetch(:api)
19
+ @protocol = options.fetch(:protocol)
19
20
  @client_examples = options.fetch(:client_examples, [])
20
21
  @examples = options.fetch(:examples)
21
22
  @module_name = options.fetch(:module_name)
@@ -279,7 +280,7 @@ module AwsSdkCodeGenerator
279
280
 
280
281
  def see_also_tag(operation, api)
281
282
  uid = api['metadata']['uid']
282
- if api['metadata']['protocol'] != 'api-gateway' && Crosslink.taggable?(uid)
283
+ if @protocol != 'api-gateway' && Crosslink.taggable?(uid)
283
284
  "# " + Crosslink.tag_string(uid, operation)
284
285
  end
285
286
  end
@@ -9,6 +9,7 @@ module AwsSdkCodeGenerator
9
9
  api = options.fetch(:api)
10
10
  examples = options.fetch(:examples, {})
11
11
  module_name = options.fetch(:module_name)
12
+ protocol = options.fetch(:protocol)
12
13
  protocol_settings = options.fetch(:protocol_settings, {})
13
14
  client_examples = options.fetch(:client_examples, {})
14
15
  paginators = options.fetch(:paginators, {})
@@ -41,6 +42,7 @@ module AwsSdkCodeGenerator
41
42
  method_name: method_name,
42
43
  operation: operation,
43
44
  api: api,
45
+ protocol: protocol,
44
46
  examples: examples,
45
47
  client_examples: client_examples[method_name] || [],
46
48
  async_client: true
@@ -60,6 +62,7 @@ module AwsSdkCodeGenerator
60
62
  method_name: method_name,
61
63
  operation: operation,
62
64
  api: api,
65
+ protocol: protocol,
63
66
  examples: examples,
64
67
  client_examples: client_examples[method_name] || [],
65
68
  async_client: false
@@ -80,6 +83,7 @@ module AwsSdkCodeGenerator
80
83
  method_name: method_name,
81
84
  operation: operation,
82
85
  api: api,
86
+ protocol: protocol,
83
87
  examples: examples,
84
88
  client_examples: client_examples[method_name] || [],
85
89
  async_client: false,
@@ -185,13 +185,13 @@ module AwsSdkCodeGenerator
185
185
  Views::ClientClass.new(
186
186
  service_identifier: @service.identifier,
187
187
  service_name: @service.name,
188
+ protocol: @service.protocol,
188
189
  protocol_settings: @service.protocol_settings,
189
190
  module_name: @service.module_name,
190
191
  gem_name: @service.gem_name,
191
192
  gem_version: @service.gem_version,
192
193
  aws_sdk_core_lib_path: @aws_sdk_core_lib_path,
193
194
  client_examples: @client_examples,
194
- protocol: @service.protocol,
195
195
  signature_version: @service.signature_version,
196
196
  require_endpoint_discovery: @service.require_endpoint_discovery,
197
197
  add_plugins: @service.add_plugins,
@@ -210,12 +210,12 @@ module AwsSdkCodeGenerator
210
210
  Views::AsyncClientClass.new(
211
211
  service_identifier: @service.identifier,
212
212
  service_name: @service.name,
213
+ protocol: @service.protocol,
213
214
  protocol_settings: @service.protocol_settings,
214
215
  module_name: @service.module_name,
215
216
  gem_name: @service.gem_name,
216
217
  gem_version: @service.gem_version,
217
218
  aws_sdk_core_lib_path: @aws_sdk_core_lib_path,
218
- protocol: @service.protocol,
219
219
  signature_version: @service.signature_version,
220
220
  add_plugins: @service.add_plugins,
221
221
  remove_plugins: @service.remove_plugins,
@@ -0,0 +1,190 @@
1
+ # frozen_string_literal: true
2
+
3
+ module AwsSdkCodeGenerator
4
+ class EndpointParameter
5
+ def initialize(name, definition, service, operation=nil)
6
+ @name = name
7
+
8
+ @value, @source = endpoint_parameter_value(name, definition, service, operation)
9
+
10
+ @type = definition['type']
11
+ @built_in = definition['builtIn']
12
+ @default = definition['default']
13
+ @required = definition['required']
14
+ @documentation = "# @!attribute #{key}\n"
15
+ if definition['documentation']
16
+ @documentation += " # #{definition['documentation']}\n"
17
+ end
18
+ if deprecated = definition['deprecated']
19
+ @documentation += " #\n # @deprecated\n"
20
+ if deprecated['message']
21
+ @documentation += " # #{deprecated['message']}\n"
22
+ end
23
+ if deprecated['since']
24
+ @documentation += " # Since: #{deprecated['since']}\n"
25
+ end
26
+ end
27
+ @documentation += " #\n # @return [#{@type}]\n #"
28
+ end
29
+
30
+ # @return [String]
31
+ attr_reader :name
32
+
33
+ # @return [String]
34
+ attr_reader :documentation
35
+
36
+ # @return [Boolean]
37
+ attr_reader :required
38
+
39
+ # @return [String]
40
+ attr_reader :source
41
+
42
+ # @return [String]
43
+ attr_reader :value
44
+
45
+ # @return [String,Boolean,Array]
46
+ def default
47
+ case @default
48
+ when String
49
+ "\"#{@default}\""
50
+ else
51
+ @default.to_s
52
+ end
53
+ end
54
+
55
+ def default?
56
+ !@default.nil?
57
+ end
58
+
59
+ def validate_required?
60
+ required && !default?
61
+ end
62
+
63
+ def key
64
+ Underscore.underscore(name)
65
+ end
66
+
67
+ private
68
+
69
+ # Most to least
70
+ # staticContextParams
71
+ # contextParam
72
+ # operationContextParams
73
+ # clientContextParams (always sourced from config)
74
+ # Built-In Bindings (sourced from config in most cases, context in some cases to allow operation level overrides)
75
+ # Built-in binding default values
76
+ # @retyrn [value, source]. source may be one of [operation, config, default]
77
+ def endpoint_parameter_value(param_name, param_data, service, operation)
78
+ unless operation.nil?
79
+ value, source = [
80
+ static_context_param(operation, param_name), 'operation'
81
+ ]
82
+ value, source = [
83
+ context_param_value(service, operation, param_name), 'operation'
84
+ ] unless value
85
+ value, source = [
86
+ operation_context_param_value(operation, param_name), 'operation'
87
+ ] unless value
88
+ end
89
+
90
+ value, source = [
91
+ client_context_param_value(service, param_name, param_data),
92
+ 'config'
93
+ ] unless value
94
+
95
+
96
+ # built-ins may be sourced from operation context in some cases
97
+ unless value
98
+ value, source = built_in_param_value(service, param_data)
99
+ end
100
+
101
+ [value || 'nil', source || 'default']
102
+ end
103
+
104
+ def client_context_param_value(service, param_name, param_data)
105
+ if service.api['clientContextParams']&.key?(param_name) &&
106
+ !param_data['builtIn']
107
+ "config.#{Underscore.underscore(param_name)}"
108
+ end
109
+ end
110
+
111
+ # built-ins may be sourced from operation context in some cases
112
+ def built_in_param_value(service, param_data)
113
+ source = 'config'
114
+ value =
115
+ case param_data['builtIn']
116
+ when 'AWS::Region'
117
+ 'config.region'
118
+ when 'AWS::UseFIPS'
119
+ 'config.use_fips_endpoint'
120
+ when 'AWS::UseDualStack'
121
+ if service.name == 'S3' || service.name == 'S3Control'
122
+ source = 'operation'
123
+ 'context[:use_dualstack_endpoint]'
124
+ else
125
+ 'config.use_dualstack_endpoint'
126
+ end
127
+ when 'AWS::Auth::AccountId'
128
+ 'config.credentials.credentials.account_id'
129
+ when 'AWS::Auth::AccountIdEndpointMode'
130
+ 'config.account_id_endpoint_mode'
131
+ when 'AWS::STS::UseGlobalEndpoint'
132
+ "config.sts_regional_endpoints == 'legacy'"
133
+ when 'AWS::S3::UseGlobalEndpoint'
134
+ "config.s3_us_east_1_regional_endpoint == 'legacy'"
135
+ when 'AWS::S3::Accelerate'
136
+ if service.name == 'S3' || service.name == 'S3Control'
137
+ source = 'operation'
138
+ 'context[:use_accelerate_endpoint]'
139
+ else
140
+ 'config.use_accelerate_endpoint'
141
+ end
142
+ when 'AWS::S3::ForcePathStyle'
143
+ 'config.force_path_style'
144
+ when 'AWS::S3::UseArnRegion', 'AWS::S3Control::UseArnRegion'
145
+ 'config.s3_use_arn_region'
146
+ when 'AWS::S3::DisableMultiRegionAccessPoints'
147
+ 'config.s3_disable_multiregion_access_points'
148
+ when 'SDK::Endpoint'
149
+ '(config.endpoint.to_s unless config.regional_endpoint)'
150
+ else
151
+ source = nil
152
+ nil # no value, not a default
153
+ end
154
+ [value, source]
155
+ end
156
+
157
+ def context_param_value(service, operation, param_name)
158
+ return nil unless operation['input']
159
+
160
+ input_shape = operation['input']['shape']
161
+ members = service.api['shapes'][input_shape].fetch('members', {})
162
+ members.detect do |(member_name, member)|
163
+ context_param = member.fetch('contextParam', {})
164
+ if context_param.fetch('name', nil) == param_name
165
+ break "context.params[:#{Underscore.underscore(member_name)}]"
166
+ end
167
+ end
168
+ end
169
+
170
+ def operation_context_param_value(operation, param_name)
171
+ return nil unless operation['input']
172
+
173
+ binding = operation.fetch('operationContextParams', {})[param_name]
174
+
175
+ return nil unless binding
176
+
177
+ "JMESPath.search(\"#{Underscore.underscore_jmespath(binding['path'])}\", context.params)"
178
+ end
179
+
180
+ def static_context_param(operation, param_name)
181
+ value = operation.fetch('staticContextParams', {})
182
+ .fetch(param_name, {}).fetch('value', nil)
183
+ if !value.nil? && value.is_a?(String)
184
+ "\"#{value}\""
185
+ else
186
+ value
187
+ end
188
+ end
189
+ end
190
+ end
@@ -175,8 +175,18 @@ module AwsSdkCodeGenerator
175
175
  str.gsub(/(.{1,#{width}})(\s+|\Z)/, "#{indent}\\1\n").chomp
176
176
  end
177
177
 
178
+ def gem_lib_path(gem_name)
179
+ File.expand_path(
180
+ File.join(
181
+ __dir__,
182
+ "../../../../gems/#{gem_name}/lib/"
183
+ )
184
+ )
185
+ end
186
+
178
187
  module_function :deep_copy, :operation_streaming?, :downcase_first, :wrap_string, :apig_prefix,
179
- :eventstream_output?, :eventstream_input?, :operation_eventstreaming?, :pascal_case
188
+ :eventstream_output?, :eventstream_input?, :operation_eventstreaming?, :pascal_case,
189
+ :gem_lib_path
180
190
 
181
191
  end
182
192
  end
@@ -63,7 +63,8 @@ module AwsSdkCodeGenerator
63
63
  'Aws::Plugins::ChecksumAlgorithm' => "#{core_plugins}/checksum_algorithm.rb",
64
64
  'Aws::Plugins::RequestCompression' => "#{core_plugins}/request_compression.rb",
65
65
  'Aws::Plugins::DefaultsMode' => "#{core_plugins}/defaults_mode.rb",
66
- 'Aws::Plugins::RecursionDetection' => "#{core_plugins}/recursion_detection.rb"
66
+ 'Aws::Plugins::RecursionDetection' => "#{core_plugins}/recursion_detection.rb",
67
+ 'Aws::Plugins::Telemetry' => "#{core_plugins}/telemetry.rb"
67
68
  }
68
69
  end
69
70
 
@@ -86,6 +87,7 @@ module AwsSdkCodeGenerator
86
87
  'rest-xml' => { 'Aws::Plugins::Protocols::RestXml' => "#{core_plugins}/protocols/rest_xml.rb" },
87
88
  'query' => { 'Aws::Plugins::Protocols::Query' => "#{core_plugins}/protocols/query.rb" },
88
89
  'ec2' => { 'Aws::Plugins::Protocols::EC2' => "#{core_plugins}/protocols/ec2.rb" },
90
+ 'smithy-rpc-v2-cbor' => { 'Aws::Plugins::Protocols::RpcV2' => "#{core_plugins}/protocols/rpc_v2.rb" },
89
91
  'api-gateway' => {
90
92
  'Aws::Plugins::Protocols::ApiGateway' => "#{core_plugins}/protocols/api_gateway.rb",
91
93
  'Aws::Plugins::ApiKey' => "#{core_plugins}/api_key.rb",
@@ -15,7 +15,7 @@ module AwsSdkCodeGenerator
15
15
  parts << 'batch_enum.each do |batch|'
16
16
  parts << initialize_params
17
17
  parts << apply_params_per_batch
18
- parts << " Aws::Plugins::UserAgent.feature('resource') do"
18
+ parts << " Aws::Plugins::UserAgent.metric('RESOURCE_MODEL') do"
19
19
  parts << " batch[0].client.#{client_method}(params)"
20
20
  parts << ' end'
21
21
  parts << 'end'
@@ -15,7 +15,7 @@ module AwsSdkCodeGenerator
15
15
  parts = []
16
16
  parts << request_options(params) if merge
17
17
  parts << assignment(options)
18
- parts << "Aws::Plugins::UserAgent.feature('resource') do\n"
18
+ parts << "Aws::Plugins::UserAgent.metric('RESOURCE_MODEL') do\n"
19
19
  parts << " @client."
20
20
  parts << operation_name(request)
21
21
  parts << arguments(merge, params, streaming)
@@ -54,7 +54,7 @@ module AwsSdkCodeGenerator
54
54
  ).to_s.strip
55
55
  parts = []
56
56
  parts << 'resp = ' if waiter['path']
57
- parts << "Aws::Plugins::UserAgent.feature('resource') do\n"
57
+ parts << "Aws::Plugins::UserAgent.metric('RESOURCE_MODEL') do\n"
58
58
  parts << " waiter.wait(params.merge(#{args}))"
59
59
  parts << "\nend"
60
60
  parts.join
@@ -2,12 +2,26 @@
2
2
 
3
3
  module AwsSdkCodeGenerator
4
4
  class Service
5
+ # Ordered priority list of supported protocols
6
+ # api-gateway is a special case and is always first.
7
+ SUPPORTED_PROTOCOLS = %w[
8
+ api-gateway
9
+ smithy-rpc-v2-cbor
10
+ json_1.0
11
+ json_1.1
12
+ rest-json
13
+ rest-xml
14
+ query
15
+ ec2
16
+ ]
5
17
 
6
18
  # @param [Hash] options
7
- # @option options [required, String] :gem_version Gem version, e.g. "1.0.0".
8
19
  # @option options [required, String] :name The service name, e.g. "S3"
9
20
  # @option options [String] :module_name The service module name, defaults
10
21
  # to "Aws::#{name}", e.g. "Aws::S3".
22
+ # @option options [String] :gem_name The gem name, defaults to
23
+ # "aws-sdk-#{name}", e.g. "aws-sdk-s3".
24
+ # @option options [required, String] :gem_version Gem version, e.g. "1.0.0".
11
25
  # @option options [required, Hash, String] :api
12
26
  # @option options [Hash, String] :docs
13
27
  # @option options [Hash, String] :paginators
@@ -21,44 +35,49 @@ module AwsSdkCodeGenerator
21
35
  # @option options [Hash] :add_plugins ({})
22
36
  # @option options [Hash] :remove_plugins ([])
23
37
  # @option options [Boolean] :deprecated (false)
38
+ # @option options [String] :default_endpoint (nil)
39
+ # @option options [String] :endpoints_key (nil)
24
40
  def initialize(options)
25
41
  @name = options.fetch(:name)
26
42
  @identifier = name.downcase
27
43
  @module_name = options[:module_name] || "Aws::#{name}"
28
44
  @gem_name = options[:gem_name] || "aws-sdk-#{identifier}"
29
45
  @gem_version = options.fetch(:gem_version)
46
+
30
47
  @api = load_json(options.fetch(:api))
31
- unless @api['metadata']['protocol'] == 'api-gateway'
32
- # Dont reply on API Gateway doc.json
48
+
49
+ # computed attributes
50
+ metadata = @api.fetch('metadata')
51
+ @protocol = select_protocol(metadata)
52
+ @protocol_settings = metadata['protocolSettings'] || {}
53
+ @api_version = metadata['apiVersion']
54
+ @signature_version = metadata['signatureVersion']
55
+ @auth = api.fetch('metadata')['auth']
56
+ @full_name = metadata['serviceFullName']
57
+ @short_name = metadata['serviceAbbreviation'] || @full_name
58
+
59
+ # Dont reply on API Gateway doc.json
60
+ unless @protocol == 'api-gateway'
33
61
  ApplyDocs.new(@api).apply(load_json(options[:docs]))
34
62
  end
35
63
  @paginators = load_json(options[:paginators])
36
64
  @waiters = load_json(options[:waiters])
37
65
  @resources = load_json(options[:resources])
38
66
  @examples = load_json(options[:examples])
39
- @smoke_tests = load_json(options[:smoke_tests])
40
67
  unless options[:legacy_endpoints]
41
68
  @endpoint_rules = load_json(options[:endpoint_rules])
42
69
  @endpoint_tests = load_json(options[:endpoint_tests])
43
70
  end
71
+ @smoke_tests = load_json(options[:smoke_tests])
72
+
44
73
  @gem_dependencies = options[:gem_dependencies] || {}
45
74
  @add_plugins = options[:add_plugins] || {}
46
75
  @remove_plugins = options[:remove_plugins] || []
76
+ @deprecated = options[:deprecated] || false
77
+ @default_endpoint = options[:default_endpoint] # APIG custom service only
47
78
  @endpoints_key = options.fetch(:endpoints_key, nil)
48
- # APIG custom service only
49
- @default_endpoint = options[:default_endpoint]
50
79
 
51
- # computed attributes
52
- @protocol = api.fetch('metadata').fetch('protocol')
53
- @protocol_settings = api.fetch('metadata')['protocolSettings'] || {}
54
- @api_version = api.fetch('metadata')['apiVersion']
55
- @signature_version = api.fetch('metadata')['signatureVersion']
56
- @full_name = api.fetch('metadata')['serviceFullName']
57
- @short_name = api.fetch('metadata')['serviceAbbreviation'] || @full_name
58
- @require_endpoint_discovery = api.fetch('operations', []).any? do |_, o|
59
- o['endpointdiscovery'] && o['endpointdiscovery']['required']
60
- end
61
- @deprecated = options[:deprecated] || false
80
+ @require_endpoint_discovery = endpoint_discovery_required?
62
81
  end
63
82
 
64
83
  # @return [String] The service name, e.g. "S3"
@@ -129,6 +148,9 @@ module AwsSdkCodeGenerator
129
148
  # @return [String] The service protocol, e.g. "json", "query", etc.
130
149
  attr_reader :protocol
131
150
 
151
+ # @return [Array<String>] The list of supported protocols
152
+ attr_reader :protocols
153
+
132
154
  # @return [Hash] The service protocol settings
133
155
  attr_reader :protocol_settings
134
156
 
@@ -138,6 +160,9 @@ module AwsSdkCodeGenerator
138
160
  # @return [String] The signature version, e.g. "v4"
139
161
  attr_reader :signature_version
140
162
 
163
+ # @return [Array<String>] A list of supported auth types
164
+ attr_reader :auth
165
+
141
166
  # @return [String] The full product name for the service,
142
167
  # e.g. "Amazon Simple Storage Service".
143
168
  attr_reader :full_name
@@ -174,6 +199,29 @@ module AwsSdkCodeGenerator
174
199
 
175
200
  private
176
201
 
202
+ def select_protocol(metadata)
203
+ protocols = metadata.fetch('protocols', [metadata['protocol']])
204
+ protocol = SUPPORTED_PROTOCOLS.find do |supported_protocol|
205
+ if %w[json_1.0 json_1.1].include?(supported_protocol)
206
+ supported_protocol, version = supported_protocol.split('_')
207
+ end
208
+
209
+ if protocols.include?(supported_protocol) &&
210
+ (version.nil? || version == metadata['jsonVersion'])
211
+ return supported_protocol
212
+ end
213
+ end
214
+ return protocol if protocol
215
+
216
+ raise "unsupported protocols `#{protocols.join(', ')}'"
217
+ end
218
+
219
+ def endpoint_discovery_required?
220
+ @api.fetch('operations', []).any? do |_, o|
221
+ o['endpointdiscovery'] && o['endpointdiscovery']['required']
222
+ end
223
+ end
224
+
177
225
  def load_json(value)
178
226
  case value
179
227
  when nil then nil
@@ -27,25 +27,26 @@ module AwsSdkCodeGenerator
27
27
  SHAPE_KEYS = {
28
28
  # keep
29
29
  'flattened' => true,
30
- 'timestampFormat' => true, # glacier api customization
30
+ 'timestampFormat' => true,
31
31
  'xmlNamespace' => true,
32
- 'streaming' => true, # transfer-encoding
33
- 'requiresLength' => true, # transfer-encoding
34
- 'union' => false, # should remain false
32
+ 'streaming' => true,
33
+ 'requiresLength' => true,
34
+ 'union' => false, # handled separately - should remain false
35
35
  'document' => true,
36
36
  'jsonvalue' => true,
37
- 'error' => true, # parsing customized error code in query protocol
38
- 'locationName' => true, # to recognize xmlName defined on shape
37
+ 'error' => true,
38
+ 'locationName' => true,
39
+ # ignore
39
40
  # event stream modeling
40
41
  'event' => false,
41
42
  'eventstream' => false,
42
43
  'eventheader' => false,
43
44
  'eventpayload' => false,
44
- # ignore
45
+ 'exceptionEvent' => false, # internal, exceptions cannot be events
46
+ # other
45
47
  'synthetic' => false,
46
48
  'box' => false,
47
49
  'fault' => false,
48
- 'exception_event' => false, # internal, exceptions cannot be events
49
50
  'deprecated' => false,
50
51
  'deprecatedMessage' => false,
51
52
  'type' => false,
@@ -68,7 +69,7 @@ module AwsSdkCodeGenerator
68
69
  }
69
70
 
70
71
  METADATA_KEYS = {
71
- # keep all
72
+ # keep
72
73
  'endpointPrefix' => true,
73
74
  'signatureVersion' => true,
74
75
  'auth' => true,
@@ -79,18 +80,18 @@ module AwsSdkCodeGenerator
79
80
  'targetPrefix' => true,
80
81
  'jsonVersion' => true,
81
82
  'errorPrefix' => true,
82
- 'timestampFormat' => true, # glacier api customization
83
+ 'timestampFormat' => true,
83
84
  'xmlNamespace' => true,
84
- 'protocolSettings' => {}, # current unused unless for h2 exclude
85
+ 'protocolSettings' => {},
85
86
  'serviceId' => true,
86
87
  'apiVersion' => true,
87
88
  'checksumFormat' => true,
88
89
  'globalEndpoint' => true,
89
90
  'serviceAbbreviation' => true,
90
91
  'uid' => true,
91
- 'awsQueryCompatible' => true, # AwsQuery migration
92
+ 'awsQueryCompatible' => true,
92
93
  # ignore
93
- 'ripServiceName' => true
94
+ 'ripServiceName' => false
94
95
  }
95
96
 
96
97
  # @option options [required, Service] :service
@@ -191,7 +192,11 @@ module AwsSdkCodeGenerator
191
192
  value: @service.api['metadata'][key].inspect
192
193
  }
193
194
  elsif METADATA_KEYS[key].nil?
194
- raise "unhandled metadata key #{key.inspect}"
195
+ AwsSdkCodeGenerator.warn(
196
+ @service.service_id,
197
+ :invalid_key,
198
+ "unhandled metadata key `#{key}`"
199
+ )
195
200
  end
196
201
  end
197
202
  metadata
@@ -250,6 +255,8 @@ module AwsSdkCodeGenerator
250
255
  end
251
256
  o.authorizer = operation['authorizer'] if operation.key?('authorizer')
252
257
  o.authtype = operation['authtype'] if operation.key?('authtype')
258
+ o.unsigned_payload = operation['unsignedPayload'] if operation.key?('unsignedPayload')
259
+ o.auth = operation['auth'] if operation.key?('auth')
253
260
  o.require_apikey = operation['requiresApiKey'] if operation.key?('requiresApiKey')
254
261
  o.pager = pager(operation_name)
255
262
  o.async = @service.protocol_settings['h2'] == 'eventstream' &&
@@ -314,7 +321,11 @@ module AwsSdkCodeGenerator
314
321
 
315
322
  args << "#{key}: #{value.inspect}"
316
323
  elsif SHAPE_KEYS[key].nil?
317
- raise "unhandled shape key #{key.inspect}"
324
+ AwsSdkCodeGenerator.warn(
325
+ @service.service_id,
326
+ :invalid_key,
327
+ "unhandled shape key `#{key}` on `#{shape_name}`"
328
+ )
318
329
  end
319
330
  end
320
331
  args.join(', ')
@@ -597,6 +608,12 @@ module AwsSdkCodeGenerator
597
608
  # @return [String,nil]
598
609
  attr_accessor :authtype
599
610
 
611
+ # @return [Boolean,nil]
612
+ attr_accessor :unsigned_payload
613
+
614
+ # @return [Array<String>]
615
+ attr_accessor :auth
616
+
600
617
  # @return [Boolean]
601
618
  attr_accessor :endpoint_trait
602
619