aws-sdk-code-generator 0.4.0.pre → 0.6.0.pre
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/lib/aws-sdk-code-generator/api.rb +2 -1
- data/lib/aws-sdk-code-generator/client_constructor.rb +2 -1
- data/lib/aws-sdk-code-generator/client_operation_documentation.rb +2 -1
- data/lib/aws-sdk-code-generator/client_operation_list.rb +4 -0
- data/lib/aws-sdk-code-generator/code_builder.rb +54 -2
- data/lib/aws-sdk-code-generator/endpoint_parameter.rb +190 -0
- data/lib/aws-sdk-code-generator/eventstream_example.rb +34 -34
- data/lib/aws-sdk-code-generator/gem_builder.rb +3 -5
- data/lib/aws-sdk-code-generator/helper.rb +11 -1
- data/lib/aws-sdk-code-generator/plugin_list.rb +5 -2
- data/lib/aws-sdk-code-generator/rbs/error_list.rb +38 -0
- data/lib/aws-sdk-code-generator/rbs/keyword_argument_builder.rb +159 -0
- data/lib/aws-sdk-code-generator/rbs/method_signature.rb +11 -0
- data/lib/aws-sdk-code-generator/rbs/resource_action.rb +39 -0
- data/lib/aws-sdk-code-generator/rbs/resource_association.rb +50 -0
- data/lib/aws-sdk-code-generator/rbs/resource_batch_action.rb +59 -0
- data/lib/aws-sdk-code-generator/rbs/resource_client_request.rb +40 -0
- data/lib/aws-sdk-code-generator/rbs/waiter.rb +53 -0
- data/lib/aws-sdk-code-generator/rbs.rb +40 -0
- data/lib/aws-sdk-code-generator/resource_batch_action_code.rb +3 -1
- data/lib/aws-sdk-code-generator/resource_client_request.rb +3 -1
- data/lib/aws-sdk-code-generator/resource_waiter.rb +6 -5
- data/lib/aws-sdk-code-generator/service.rb +85 -16
- data/lib/aws-sdk-code-generator/views/async_client_class.rb +5 -1
- data/lib/aws-sdk-code-generator/views/client_api_module.rb +58 -16
- data/lib/aws-sdk-code-generator/views/client_class.rb +5 -1
- data/lib/aws-sdk-code-generator/views/endpoint_parameters_class.rb +6 -50
- data/lib/aws-sdk-code-generator/views/endpoint_provider_class.rb +9 -0
- data/lib/aws-sdk-code-generator/views/endpoints_module.rb +18 -124
- data/lib/aws-sdk-code-generator/views/endpoints_plugin.rb +46 -4
- data/lib/aws-sdk-code-generator/views/errors_module.rb +21 -0
- data/lib/aws-sdk-code-generator/views/event_streams_module.rb +7 -1
- data/lib/aws-sdk-code-generator/views/features/smoke.rb +100 -23
- data/lib/aws-sdk-code-generator/views/features/step_definitions.rb +1 -4
- data/lib/aws-sdk-code-generator/views/gemspec.rb +13 -3
- data/lib/aws-sdk-code-generator/views/rbs/client_class.rb +172 -0
- data/lib/aws-sdk-code-generator/views/rbs/errors_module.rb +28 -0
- data/lib/aws-sdk-code-generator/views/rbs/resource_class.rb +95 -0
- data/lib/aws-sdk-code-generator/views/rbs/root_resource_class.rb +30 -0
- data/lib/aws-sdk-code-generator/views/rbs/types_module.rb +257 -0
- data/lib/aws-sdk-code-generator/views/rbs/waiters_module.rb +22 -0
- data/lib/aws-sdk-code-generator/views/resource_class.rb +22 -0
- data/lib/aws-sdk-code-generator/views/root_resource_class.rb +19 -0
- data/lib/aws-sdk-code-generator/views/service_module.rb +41 -27
- data/lib/aws-sdk-code-generator/views/spec/endpoint_provider_spec_class.rb +25 -12
- data/lib/aws-sdk-code-generator/views/types_module.rb +34 -11
- data/lib/aws-sdk-code-generator.rb +29 -1
- data/templates/async_client_class.mustache +6 -1
- data/templates/client_api_module.mustache +14 -0
- data/templates/client_class.mustache +10 -47
- data/templates/endpoint_parameters_class.mustache +16 -13
- data/templates/endpoints_module.mustache +19 -11
- data/templates/endpoints_plugin.mustache +38 -20
- data/templates/errors_module.mustache +5 -0
- data/templates/features/smoke.mustache +11 -15
- data/templates/features/step_definitions.mustache +0 -5
- data/templates/gemspec.mustache +5 -2
- data/templates/rbs/client_class.mustache +39 -0
- data/templates/rbs/errors_module.mustache +17 -0
- data/templates/rbs/resource_class.mustache +71 -0
- data/templates/rbs/root_resource_class.mustache +26 -0
- data/templates/rbs/types_module.mustache +37 -0
- data/templates/rbs/waiters_module.mustache +17 -0
- data/templates/resource_class.mustache +8 -1
- data/templates/root_resource_class.mustache +5 -0
- data/templates/service_module.mustache +13 -3
- data/templates/spec/endpoint_provider_spec_class.mustache +11 -1
- data/templates/types_module.mustache +4 -0
- metadata +27 -7
- data/lib/aws-sdk-code-generator/views/features/smoke_step_definitions.rb +0 -26
- data/templates/features/smoke_step_definitions.mustache +0 -31
@@ -0,0 +1,159 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
module RBS
|
5
|
+
# similar to SyntaxExampleHash
|
6
|
+
class KeywordArgumentBuilder
|
7
|
+
include Helper
|
8
|
+
|
9
|
+
attr_reader :newline
|
10
|
+
|
11
|
+
def initialize(api:, shape:, newline:)
|
12
|
+
@api = api
|
13
|
+
@shape = shape
|
14
|
+
@newline = newline
|
15
|
+
end
|
16
|
+
|
17
|
+
def format(indent: '')
|
18
|
+
members_str = struct_members(@shape, indent, [], keyword: true)
|
19
|
+
result = []
|
20
|
+
result << '' if newline
|
21
|
+
result << members_str if !members_str.empty?
|
22
|
+
result << indent if newline
|
23
|
+
result.join(joint)
|
24
|
+
end
|
25
|
+
|
26
|
+
def struct(struct_shape, i, visited)
|
27
|
+
members_str = struct_members(struct_shape, i, visited, keyword: false)
|
28
|
+
result = ["{"]
|
29
|
+
result << members_str if struct_shape['members']&.empty?&.!
|
30
|
+
result << "#{i}}"
|
31
|
+
result.join(joint)
|
32
|
+
end
|
33
|
+
|
34
|
+
def struct_members(struct_shape, i, visited, keyword:)
|
35
|
+
lines = []
|
36
|
+
unless struct_shape['members'].nil?
|
37
|
+
n = 0
|
38
|
+
struct_shape['members'].each do |member_name, member_ref|
|
39
|
+
next if member_ref['documented'] === false
|
40
|
+
more_indent = newline ? " " : ""
|
41
|
+
if @api['shapes'][member_ref['shape']]['eventstream'] === true
|
42
|
+
# FIXME: "input_event_stream_hander: EventStreams::#{member_ref['shape']}.new"
|
43
|
+
lines << "#{i}#{more_indent}input_event_stream_hander: untyped,"
|
44
|
+
else
|
45
|
+
lines << "#{i}#{more_indent}#{struct_member(struct_shape, member_name, member_ref, i, visited, keyword: keyword)}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
if lines.empty?
|
50
|
+
""
|
51
|
+
else
|
52
|
+
lines.join(joint).chomp(",")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def struct_member(struct, member_name, member_ref, i, visited, keyword:)
|
57
|
+
required = (struct['required'] || []).include?(member_name)
|
58
|
+
if keyword
|
59
|
+
"#{required ? '' : '?'}#{underscore(member_name)}: #{ref_value(member_ref, i + more_indent, visited)},"
|
60
|
+
else
|
61
|
+
"#{underscore(member_name)}: #{ref_value(member_ref, i + more_indent, visited)}#{required ? '' : '?'},"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def ref_value(ref, i, visited)
|
66
|
+
if visited.include?(ref['shape'])
|
67
|
+
return "untyped"
|
68
|
+
else
|
69
|
+
visited = visited + [ref['shape']]
|
70
|
+
end
|
71
|
+
|
72
|
+
s = shape(ref)
|
73
|
+
case s['type']
|
74
|
+
when 'structure'
|
75
|
+
if ref['shape'] == 'AttributeValue'
|
76
|
+
'untyped'
|
77
|
+
else
|
78
|
+
struct(s, i, visited)
|
79
|
+
end
|
80
|
+
when 'blob'
|
81
|
+
if ref['streaming']
|
82
|
+
"::String | ::StringIO | ::File" # input only
|
83
|
+
else
|
84
|
+
"::String"
|
85
|
+
end
|
86
|
+
when 'list' then list(s, i, visited)
|
87
|
+
when 'map' then map(s, i, visited)
|
88
|
+
when 'boolean' then "bool"
|
89
|
+
when 'integer', 'long' then '::Integer'
|
90
|
+
when 'float', 'double' then '::Float'
|
91
|
+
when 'byte' then '::Integer'
|
92
|
+
when 'character' then '::String'
|
93
|
+
when 'string' then string(ref)
|
94
|
+
when 'timestamp' then '::Time'
|
95
|
+
else raise "unsupported shape #{s['type'].inspect}"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def list(list_shape, i, visited)
|
100
|
+
member_ref = list_shape['member']
|
101
|
+
if complex?(member_ref)
|
102
|
+
complex_list(member_ref, i, visited)
|
103
|
+
else
|
104
|
+
scalar_list(member_ref, i, visited)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def scalar_list(member_ref, i, visited)
|
109
|
+
"Array[#{ref_value(member_ref, i, visited)}]"
|
110
|
+
end
|
111
|
+
|
112
|
+
def complex_list(member_ref, i, visited)
|
113
|
+
newline_indent = newline ? "\n#{i}" : ""
|
114
|
+
"Array[#{newline_indent}#{more_indent}#{ref_value(member_ref, i + more_indent, visited)},#{newline_indent}]"
|
115
|
+
end
|
116
|
+
|
117
|
+
def complex?(ref)
|
118
|
+
s = shape(ref)
|
119
|
+
if s['type'] == 'structure'
|
120
|
+
!ddb_av?(ref)
|
121
|
+
else
|
122
|
+
s['type'] == 'list' || s['type'] == 'map'
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def ddb_av?(ref)
|
127
|
+
s = shape(ref)
|
128
|
+
case s['type']
|
129
|
+
when 'list' then ddb_av?(s['member'])
|
130
|
+
when 'structure' then ref['shape'] == 'AttributeValue'
|
131
|
+
else false
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def map(map_shape, i, visited)
|
136
|
+
key = string(map_shape['key'])
|
137
|
+
value = ref_value(map_shape['value'], i + more_indent, visited)
|
138
|
+
"Hash[#{key}, #{value}]"
|
139
|
+
end
|
140
|
+
|
141
|
+
def string(ref)
|
142
|
+
string_shape = shape(ref)
|
143
|
+
if string_shape['enum']
|
144
|
+
"(#{string_shape['enum'].map { |s| "\"#{s}\"" }.join(" | ")})"
|
145
|
+
else ref['shape']
|
146
|
+
"::String"
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def more_indent
|
151
|
+
newline ? " " : ""
|
152
|
+
end
|
153
|
+
|
154
|
+
def joint
|
155
|
+
newline ? "\n" : " "
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
module RBS
|
5
|
+
class MethodSignature < Struct.new(:method_name, :overloads, keyword_init: true)
|
6
|
+
def signature
|
7
|
+
"def #{method_name}: #{overloads.join("\n #{" " * method_name.length}| ")}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
module RBS
|
5
|
+
class ResourceAction
|
6
|
+
class << self
|
7
|
+
def build_method_signature_list(resource:, api:)
|
8
|
+
(resource["actions"] || []).map do |action_name, action|
|
9
|
+
new(action_name: action_name, action: action, api: api).build_method_signature
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(action_name:, action:, api:)
|
15
|
+
request = action["request"]
|
16
|
+
operation = api["operations"][request["operation"]]
|
17
|
+
returns = if action["resource"]
|
18
|
+
resource = action["resource"]
|
19
|
+
AwsSdkCodeGenerator::Api.plural?(resource) ? "#{resource["type"]}::Collection" : resource["type"]
|
20
|
+
elsif operation["output"]
|
21
|
+
"Types::#{operation["output"]["shape"]}"
|
22
|
+
else
|
23
|
+
"::Aws::EmptyStructure"
|
24
|
+
end
|
25
|
+
|
26
|
+
@client_request = ResourceClientRequest.new(
|
27
|
+
method_name: Underscore.underscore(action_name),
|
28
|
+
api: api,
|
29
|
+
request: request,
|
30
|
+
returns: returns,
|
31
|
+
)
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_method_signature
|
35
|
+
@client_request.build_method_signature
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
module RBS
|
5
|
+
class ResourceAssociation
|
6
|
+
class << self
|
7
|
+
def build_method_signature_list(resource:, api:, paginators:)
|
8
|
+
associations = []
|
9
|
+
associations += has_associations(resource: resource)
|
10
|
+
associations += has_many_associations(resource: resource, api: api, paginators: paginators)
|
11
|
+
associations.sort_by(&:method_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def has_associations(resource:)
|
17
|
+
resource.fetch("has", {}).map do |name, assoc|
|
18
|
+
method_name = Underscore.underscore(name)
|
19
|
+
arguments = AwsSdkCodeGenerator::ResourceHasAssociation.send(:compute_params, assoc).map { |param|
|
20
|
+
"#{param[:type]} #{Underscore.underscore(param[:name])}"
|
21
|
+
}.join(', ')
|
22
|
+
returns = AwsSdkCodeGenerator::ResourceHasAssociation.send(:return_type, assoc).sub(/, nil$/, "?")
|
23
|
+
MethodSignature.new(
|
24
|
+
method_name: method_name,
|
25
|
+
overloads: ["(#{arguments}) -> #{returns}"]
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def has_many_associations(resource:, api:, paginators:)
|
31
|
+
resource.fetch("hasMany", {}).map do |name, assoc|
|
32
|
+
ResourceClientRequest.new(
|
33
|
+
method_name: Underscore.underscore(name),
|
34
|
+
api: api,
|
35
|
+
request: assoc["request"],
|
36
|
+
returns: "#{assoc["resource"]["type"]}::Collection",
|
37
|
+
skip: AwsSdkCodeGenerator::ResourceHasManyAssociation.send(
|
38
|
+
:paging_options,
|
39
|
+
{
|
40
|
+
assoc: assoc,
|
41
|
+
paginators: paginators
|
42
|
+
}
|
43
|
+
),
|
44
|
+
).build_method_signature
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
module RBS
|
5
|
+
class ResourceBatchAction
|
6
|
+
class << self
|
7
|
+
def build_method_signature_list(resource:, api:)
|
8
|
+
resource.fetch("batchActions", {}).map do |name, action|
|
9
|
+
new(api: api, name: name, action: action).build_method_signature
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(api:, name:, action:)
|
15
|
+
@api = api
|
16
|
+
@name = name
|
17
|
+
@action = action
|
18
|
+
@batch_action_documentation = AwsSdkCodeGenerator::ResourceBatchActionDocumentation.new(
|
19
|
+
var_name: nil,
|
20
|
+
method_name: method_name,
|
21
|
+
action: action,
|
22
|
+
api: api,
|
23
|
+
)
|
24
|
+
@skip_params = @batch_action_documentation.send(:skip_params)
|
25
|
+
@input_ref = @batch_action_documentation.send(:input_ref)
|
26
|
+
@input_shape = AwsSdkCodeGenerator::Api.shape(@input_ref, api)
|
27
|
+
end
|
28
|
+
|
29
|
+
def build_method_signature
|
30
|
+
arguments = nil
|
31
|
+
include_required = false
|
32
|
+
|
33
|
+
if @input_shape
|
34
|
+
shape = Helper.deep_copy(@input_shape)
|
35
|
+
shape.fetch("members").reject! { |member_name, _| @skip_params.include?(member_name) }
|
36
|
+
arguments = KeywordArgumentBuilder.new(
|
37
|
+
api: @api,
|
38
|
+
shape: shape,
|
39
|
+
newline: true
|
40
|
+
).format(indent: ' ' * (14 + method_name.length))
|
41
|
+
end
|
42
|
+
|
43
|
+
MethodSignature.new(
|
44
|
+
method_name: method_name,
|
45
|
+
overloads: [
|
46
|
+
"(#{arguments}) -> void",
|
47
|
+
"(#{include_required ? "" : "?"}Hash[Symbol, untyped]) -> void",
|
48
|
+
]
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def method_name
|
55
|
+
AwsSdkCodeGenerator::ResourceBatchAction.send(:build_method_name, @name, @action)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
module RBS
|
5
|
+
class ResourceClientRequest
|
6
|
+
include Helper
|
7
|
+
|
8
|
+
attr_reader :method_name
|
9
|
+
attr_reader :arguments
|
10
|
+
attr_reader :returns
|
11
|
+
attr_reader :include_required
|
12
|
+
|
13
|
+
def initialize(method_name:, api:, request:, returns:, skip: [])
|
14
|
+
@method_name = method_name
|
15
|
+
@returns = returns
|
16
|
+
@include_required = false
|
17
|
+
|
18
|
+
operation = api["operations"][request["operation"]]
|
19
|
+
shape_ref = operation["input"]
|
20
|
+
input_shape = AwsSdkCodeGenerator::Api.shape(shape_ref, api)
|
21
|
+
skip = Set.new(skip + AwsSdkCodeGenerator::ResourceSkipParams.compute(input_shape, request))
|
22
|
+
@arguments = if input_shape
|
23
|
+
shape = deep_copy(input_shape)
|
24
|
+
shape["members"].select! { |member_name, _| !skip.include?(member_name) }
|
25
|
+
KeywordArgumentBuilder.new(api: api, shape: shape, newline: true).format(indent: ' ' * (12 + method_name.length))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def build_method_signature
|
30
|
+
MethodSignature.new(
|
31
|
+
method_name: method_name,
|
32
|
+
overloads: [
|
33
|
+
"(#{arguments}) -> #{returns}",
|
34
|
+
"(#{@include_required ? "" : "?"}Hash[Symbol, untyped]) -> #{returns}"
|
35
|
+
]
|
36
|
+
)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
module RBS
|
5
|
+
class Waiter < Struct.new(
|
6
|
+
:name,
|
7
|
+
:class_name,
|
8
|
+
:client_overload_keyword_argument,
|
9
|
+
:client_overload_positional_argument,
|
10
|
+
:waiter_overload_keyword_argument,
|
11
|
+
:waiter_overload_positional_argument,
|
12
|
+
keyword_init: true
|
13
|
+
)
|
14
|
+
class << self
|
15
|
+
def build_list(api:, waiters:)
|
16
|
+
operations = api.fetch("operations")
|
17
|
+
waiters =
|
18
|
+
if waiters&.first
|
19
|
+
waiters["waiters"]
|
20
|
+
else
|
21
|
+
{}
|
22
|
+
end
|
23
|
+
waiters.map do |waiter_name, waiter|
|
24
|
+
operation = waiter.fetch("operation")
|
25
|
+
operation_ref = operations[operation]
|
26
|
+
input_shape = operation_ref.dig("input", "shape")
|
27
|
+
include_required = api["shapes"][input_shape]&.[]("required")&.empty?&.!
|
28
|
+
|
29
|
+
name = ":#{Underscore.underscore(waiter_name)}"
|
30
|
+
shapes = api.fetch("shapes")
|
31
|
+
input_shape_ref = shapes[input_shape]
|
32
|
+
params = AwsSdkCodeGenerator::RBS::KeywordArgumentBuilder.new(
|
33
|
+
api: api,
|
34
|
+
shape: input_shape_ref,
|
35
|
+
newline: true,
|
36
|
+
).format(indent: ' ' * 18)
|
37
|
+
returns = operation_ref.dig("output", "shape") ? "Client::_#{operation}ResponseSuccess" : "::Seahorse::Client::_ResponseSuccess[::Aws::EmptyStructure]"
|
38
|
+
prefix = include_required ? "" : "?"
|
39
|
+
|
40
|
+
new.tap do |w|
|
41
|
+
w.name = name
|
42
|
+
w.class_name = waiter_name
|
43
|
+
w.client_overload_keyword_argument = "(#{name} waiter_name, #{params}) -> #{returns}"
|
44
|
+
w.client_overload_positional_argument = "(#{name} waiter_name, #{prefix}Hash[Symbol, untyped] params, ?Hash[Symbol, untyped] options) -> #{returns}"
|
45
|
+
w.waiter_overload_keyword_argument = "(#{params}) -> #{returns}"
|
46
|
+
w.waiter_overload_positional_argument = "(#{prefix}Hash[Symbol, untyped]) -> #{returns}"
|
47
|
+
end
|
48
|
+
end.sort_by(&:name)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
module RBS
|
5
|
+
class << self
|
6
|
+
def to_type(shape_ref, api)
|
7
|
+
_, shape = Api.resolve(shape_ref, api)
|
8
|
+
case shape['type']
|
9
|
+
when 'blob' then Api.streaming?(shape_ref, api) ? '::IO' : '::String'
|
10
|
+
when 'boolean' then 'bool'
|
11
|
+
when 'byte' then '::Integer'
|
12
|
+
when 'character' then '::String'
|
13
|
+
when 'double' then '::Float'
|
14
|
+
when 'float' then '::Float'
|
15
|
+
when 'integer' then '::Integer'
|
16
|
+
when 'list' then "::Array[#{to_type(shape['member'], api)}]"
|
17
|
+
when 'long' then '::Integer'
|
18
|
+
when 'map' then "::Hash[#{to_type(shape['key'], api)}, #{to_type(shape['value'], api)}]"
|
19
|
+
when 'string'
|
20
|
+
if shape['enum']
|
21
|
+
"(#{shape['enum'].map { |e| "\"#{e}\"" }.join(" | ")})"
|
22
|
+
elsif Api.streaming?(shape_ref, api)
|
23
|
+
'::IO'
|
24
|
+
else
|
25
|
+
'::String'
|
26
|
+
end
|
27
|
+
when 'structure'
|
28
|
+
if shape['document']
|
29
|
+
'untyped'
|
30
|
+
else
|
31
|
+
"Types::#{shape_ref['shape']}"
|
32
|
+
end
|
33
|
+
when 'timestamp' then '::Time'
|
34
|
+
else
|
35
|
+
raise "unhandled type #{shape['type'].inspect}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -15,7 +15,9 @@ module AwsSdkCodeGenerator
|
|
15
15
|
parts << 'batch_enum.each do |batch|'
|
16
16
|
parts << initialize_params
|
17
17
|
parts << apply_params_per_batch
|
18
|
-
parts << "
|
18
|
+
parts << " Aws::Plugins::UserAgent.metric('RESOURCE_MODEL') do"
|
19
|
+
parts << " batch[0].client.#{client_method}(params)"
|
20
|
+
parts << ' end'
|
19
21
|
parts << 'end'
|
20
22
|
parts << 'nil'
|
21
23
|
parts.join("\n").rstrip
|
@@ -15,9 +15,11 @@ module AwsSdkCodeGenerator
|
|
15
15
|
parts = []
|
16
16
|
parts << request_options(params) if merge
|
17
17
|
parts << assignment(options)
|
18
|
-
parts << "
|
18
|
+
parts << "Aws::Plugins::UserAgent.metric('RESOURCE_MODEL') do\n"
|
19
|
+
parts << " @client."
|
19
20
|
parts << operation_name(request)
|
20
21
|
parts << arguments(merge, params, streaming)
|
22
|
+
parts << "\nend"
|
21
23
|
parts.join
|
22
24
|
end
|
23
25
|
|
@@ -52,11 +52,12 @@ module AwsSdkCodeGenerator
|
|
52
52
|
args = ResourceClientRequestParams.new(
|
53
53
|
params: waiter['params']
|
54
54
|
).to_s.strip
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
parts = []
|
56
|
+
parts << 'resp = ' if waiter['path']
|
57
|
+
parts << "Aws::Plugins::UserAgent.metric('RESOURCE_MODEL') do\n"
|
58
|
+
parts << " waiter.wait(params.merge(#{args}))"
|
59
|
+
parts << "\nend"
|
60
|
+
parts.join
|
60
61
|
end
|
61
62
|
|
62
63
|
def constructor_args(resource, waiter)
|
@@ -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
|
@@ -20,43 +34,50 @@ module AwsSdkCodeGenerator
|
|
20
34
|
# @option options [Hash<gem,version>] :gem_dependencies ({})
|
21
35
|
# @option options [Hash] :add_plugins ({})
|
22
36
|
# @option options [Hash] :remove_plugins ([])
|
37
|
+
# @option options [Boolean] :deprecated (false)
|
38
|
+
# @option options [String] :default_endpoint (nil)
|
39
|
+
# @option options [String] :endpoints_key (nil)
|
23
40
|
def initialize(options)
|
24
41
|
@name = options.fetch(:name)
|
25
42
|
@identifier = name.downcase
|
26
43
|
@module_name = options[:module_name] || "Aws::#{name}"
|
27
44
|
@gem_name = options[:gem_name] || "aws-sdk-#{identifier}"
|
28
45
|
@gem_version = options.fetch(:gem_version)
|
46
|
+
|
29
47
|
@api = load_json(options.fetch(:api))
|
30
|
-
|
31
|
-
|
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'
|
32
61
|
ApplyDocs.new(@api).apply(load_json(options[:docs]))
|
33
62
|
end
|
34
63
|
@paginators = load_json(options[:paginators])
|
35
64
|
@waiters = load_json(options[:waiters])
|
36
65
|
@resources = load_json(options[:resources])
|
37
66
|
@examples = load_json(options[:examples])
|
38
|
-
@smoke_tests = load_json(options[:smoke_tests])
|
39
67
|
unless options[:legacy_endpoints]
|
40
68
|
@endpoint_rules = load_json(options[:endpoint_rules])
|
41
69
|
@endpoint_tests = load_json(options[:endpoint_tests])
|
42
70
|
end
|
71
|
+
@smoke_tests = load_json(options[:smoke_tests])
|
72
|
+
|
43
73
|
@gem_dependencies = options[:gem_dependencies] || {}
|
44
74
|
@add_plugins = options[:add_plugins] || {}
|
45
75
|
@remove_plugins = options[:remove_plugins] || []
|
76
|
+
@deprecated = options[:deprecated] || false
|
77
|
+
@default_endpoint = options[:default_endpoint] # APIG custom service only
|
46
78
|
@endpoints_key = options.fetch(:endpoints_key, nil)
|
47
|
-
# APIG custom service only
|
48
|
-
@default_endpoint = options[:default_endpoint]
|
49
79
|
|
50
|
-
|
51
|
-
@protocol = api.fetch('metadata').fetch('protocol')
|
52
|
-
@protocol_settings = api.fetch('metadata')['protocolSettings'] || {}
|
53
|
-
@api_version = api.fetch('metadata')['apiVersion']
|
54
|
-
@signature_version = api.fetch('metadata')['signatureVersion']
|
55
|
-
@full_name = api.fetch('metadata')['serviceFullName']
|
56
|
-
@short_name = api.fetch('metadata')['serviceAbbreviation'] || @full_name
|
57
|
-
@require_endpoint_discovery = api.fetch('operations', []).any? do |_, o|
|
58
|
-
o['endpointdiscovery'] && o['endpointdiscovery']['required']
|
59
|
-
end
|
80
|
+
@require_endpoint_discovery = endpoint_discovery_required?
|
60
81
|
end
|
61
82
|
|
62
83
|
# @return [String] The service name, e.g. "S3"
|
@@ -127,6 +148,9 @@ module AwsSdkCodeGenerator
|
|
127
148
|
# @return [String] The service protocol, e.g. "json", "query", etc.
|
128
149
|
attr_reader :protocol
|
129
150
|
|
151
|
+
# @return [Array<String>] The list of supported protocols
|
152
|
+
attr_reader :protocols
|
153
|
+
|
130
154
|
# @return [Hash] The service protocol settings
|
131
155
|
attr_reader :protocol_settings
|
132
156
|
|
@@ -136,6 +160,9 @@ module AwsSdkCodeGenerator
|
|
136
160
|
# @return [String] The signature version, e.g. "v4"
|
137
161
|
attr_reader :signature_version
|
138
162
|
|
163
|
+
# @return [Array<String>] A list of supported auth types
|
164
|
+
attr_reader :auth
|
165
|
+
|
139
166
|
# @return [String] The full product name for the service,
|
140
167
|
# e.g. "Amazon Simple Storage Service".
|
141
168
|
attr_reader :full_name
|
@@ -146,6 +173,25 @@ module AwsSdkCodeGenerator
|
|
146
173
|
# @return [Boolean] true if any operation requires endpoint_discovery
|
147
174
|
attr_reader :require_endpoint_discovery
|
148
175
|
|
176
|
+
# @return [String] the service_id
|
177
|
+
def service_id
|
178
|
+
metadata = @api['metadata']
|
179
|
+
return metadata['serviceId'] if metadata['serviceId']
|
180
|
+
|
181
|
+
name = metadata['serviceAbbreviation'] || metadata['serviceFullName']
|
182
|
+
name = name.gsub(/AWS/, '').gsub(/Amazon/, '')
|
183
|
+
name = name.gsub(/[^a-zA-Z0-9 ]+/, '')
|
184
|
+
name = name.gsub(/^[0-9]+/, '')
|
185
|
+
name = name.strip
|
186
|
+
|
187
|
+
name
|
188
|
+
end
|
189
|
+
|
190
|
+
# @return [Boolean] true if the service is deprecated
|
191
|
+
def deprecated?
|
192
|
+
@deprecated
|
193
|
+
end
|
194
|
+
|
149
195
|
# @api private
|
150
196
|
def inspect
|
151
197
|
"#<#{self.class.name}>"
|
@@ -153,6 +199,29 @@ module AwsSdkCodeGenerator
|
|
153
199
|
|
154
200
|
private
|
155
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
|
+
|
156
225
|
def load_json(value)
|
157
226
|
case value
|
158
227
|
when nil then nil
|
@@ -24,10 +24,14 @@ module AwsSdkCodeGenerator
|
|
24
24
|
@gem_version = options.fetch(:gem_version)
|
25
25
|
@plugins = PluginList.new(options)
|
26
26
|
@codegenerated_plugins = options.fetch(:codegenerated_plugins, [])
|
27
|
+
@default_plugins = Seahorse::Client::AsyncBase.plugins.map do |plugin|
|
28
|
+
PluginList::Plugin.new(class_name: plugin.name, options: plugin.options, path: '')
|
29
|
+
end
|
27
30
|
@client_constructor = ClientConstructor.new(
|
28
31
|
options.merge(
|
29
32
|
plugins: @plugins,
|
30
|
-
codegenerated_plugins: @codegenerated_plugins
|
33
|
+
codegenerated_plugins: @codegenerated_plugins,
|
34
|
+
default_plugins: @default_plugins))
|
31
35
|
@operations = ClientOperationList.new(options).to_a
|
32
36
|
end
|
33
37
|
|