aws-sdk-code-generator 0.1.0.pre → 0.2.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 +5 -5
- data/lib/aws-sdk-code-generator.rb +68 -75
- data/lib/aws-sdk-code-generator/api.rb +130 -0
- data/lib/aws-sdk-code-generator/apply_docs.rb +15 -2
- data/lib/aws-sdk-code-generator/client_constructor.rb +39 -0
- data/lib/aws-sdk-code-generator/client_operation_documentation.rb +268 -0
- data/lib/aws-sdk-code-generator/client_operation_list.rb +148 -0
- data/lib/aws-sdk-code-generator/client_response_structure_example.rb +108 -0
- data/lib/aws-sdk-code-generator/code_builder.rb +146 -133
- data/lib/aws-sdk-code-generator/crosslink.rb +42 -0
- data/lib/aws-sdk-code-generator/docstring.rb +199 -0
- data/lib/aws-sdk-code-generator/error_list.rb +77 -0
- data/lib/aws-sdk-code-generator/errors.rb +2 -0
- data/lib/aws-sdk-code-generator/eventstream_example.rb +220 -0
- data/lib/aws-sdk-code-generator/gem_builder.rb +19 -25
- data/lib/aws-sdk-code-generator/hash_formatter.rb +5 -2
- data/lib/aws-sdk-code-generator/helper.rb +77 -61
- data/lib/aws-sdk-code-generator/plugin_list.rb +146 -0
- data/lib/aws-sdk-code-generator/resource_action.rb +69 -0
- data/lib/aws-sdk-code-generator/resource_action_code.rb +57 -0
- data/lib/aws-sdk-code-generator/resource_association.rb +37 -0
- data/lib/aws-sdk-code-generator/resource_attribute.rb +76 -0
- data/lib/aws-sdk-code-generator/resource_batch_action.rb +56 -0
- data/lib/aws-sdk-code-generator/resource_batch_action_code.rb +136 -0
- data/lib/aws-sdk-code-generator/resource_batch_action_documentation.rb +108 -0
- data/lib/aws-sdk-code-generator/resource_batch_builder.rb +212 -0
- data/lib/aws-sdk-code-generator/resource_builder.rb +48 -0
- data/lib/aws-sdk-code-generator/resource_client_request.rb +62 -0
- data/lib/aws-sdk-code-generator/resource_client_request_documentation.rb +81 -0
- data/lib/aws-sdk-code-generator/resource_client_request_params.rb +86 -0
- data/lib/aws-sdk-code-generator/resource_data_method.rb +60 -0
- data/lib/aws-sdk-code-generator/resource_has_association.rb +117 -0
- data/lib/aws-sdk-code-generator/resource_has_many_association.rb +52 -0
- data/lib/aws-sdk-code-generator/resource_has_many_association_code.rb +76 -0
- data/lib/aws-sdk-code-generator/resource_identifier.rb +44 -0
- data/lib/aws-sdk-code-generator/resource_identifiers_method.rb +29 -0
- data/lib/aws-sdk-code-generator/resource_load_method.rb +68 -0
- data/lib/aws-sdk-code-generator/resource_method.rb +22 -0
- data/lib/aws-sdk-code-generator/resource_skip_params.rb +36 -0
- data/lib/aws-sdk-code-generator/resource_value_source.rb +68 -0
- data/lib/aws-sdk-code-generator/resource_waiter.rb +80 -0
- data/lib/aws-sdk-code-generator/service.rb +30 -7
- data/lib/aws-sdk-code-generator/shared_example.rb +131 -0
- data/lib/aws-sdk-code-generator/syntax_example.rb +60 -0
- data/lib/aws-sdk-code-generator/syntax_example_hash.rb +174 -0
- data/lib/aws-sdk-code-generator/underscore.rb +10 -5
- data/lib/aws-sdk-code-generator/view.rb +33 -0
- data/lib/aws-sdk-code-generator/views.rb +2 -0
- data/lib/aws-sdk-code-generator/views/apig_endpoint_class.rb +25 -0
- data/lib/aws-sdk-code-generator/views/apig_readme.rb +32 -0
- data/lib/aws-sdk-code-generator/views/async_client_class.rb +68 -0
- data/lib/aws-sdk-code-generator/views/authorizer_class.rb +17 -0
- data/lib/aws-sdk-code-generator/views/client_api_module.rb +583 -0
- data/lib/aws-sdk-code-generator/views/client_class.rb +93 -0
- data/lib/aws-sdk-code-generator/views/docstring.rb +27 -0
- data/lib/aws-sdk-code-generator/views/errors_module.rb +32 -0
- data/lib/aws-sdk-code-generator/views/event_streams_module.rb +149 -0
- data/lib/aws-sdk-code-generator/views/features/env.rb +9 -0
- data/lib/aws-sdk-code-generator/views/features/smoke.rb +51 -0
- data/lib/aws-sdk-code-generator/views/features/smoke_step_definitions.rb +26 -0
- data/lib/aws-sdk-code-generator/views/features/step_definitions.rb +2 -0
- data/lib/aws-sdk-code-generator/views/gemspec.rb +39 -5
- data/lib/aws-sdk-code-generator/views/resource_class.rb +122 -0
- data/lib/aws-sdk-code-generator/views/root_resource_class.rb +58 -0
- data/lib/aws-sdk-code-generator/views/service_module.rb +30 -14
- data/lib/aws-sdk-code-generator/views/spec/spec_helper.rb +9 -0
- data/lib/aws-sdk-code-generator/views/types_module.rb +294 -0
- data/lib/aws-sdk-code-generator/views/version.rb +2 -0
- data/lib/aws-sdk-code-generator/views/waiters_module.rb +37 -0
- data/lib/aws-sdk-code-generator/waiter.rb +95 -0
- data/lib/aws-sdk-code-generator/yard_option_tag.rb +43 -0
- metadata +61 -68
- data/lib/aws-sdk-code-generator/dsl/access_control_statement.rb +0 -23
- data/lib/aws-sdk-code-generator/dsl/attribute_accessor.rb +0 -43
- data/lib/aws-sdk-code-generator/dsl/attribute_reader.rb +0 -11
- data/lib/aws-sdk-code-generator/dsl/attribute_writer.rb +0 -11
- data/lib/aws-sdk-code-generator/dsl/autoload_statement.rb +0 -15
- data/lib/aws-sdk-code-generator/dsl/block_param.rb +0 -11
- data/lib/aws-sdk-code-generator/dsl/class.rb +0 -27
- data/lib/aws-sdk-code-generator/dsl/code_literal.rb +0 -66
- data/lib/aws-sdk-code-generator/dsl/code_object.rb +0 -33
- data/lib/aws-sdk-code-generator/dsl/docstring.rb +0 -36
- data/lib/aws-sdk-code-generator/dsl/eigenclass.rb +0 -15
- data/lib/aws-sdk-code-generator/dsl/extend_statement.rb +0 -12
- data/lib/aws-sdk-code-generator/dsl/formatter.rb +0 -25
- data/lib/aws-sdk-code-generator/dsl/include_statement.rb +0 -17
- data/lib/aws-sdk-code-generator/dsl/main.rb +0 -105
- data/lib/aws-sdk-code-generator/dsl/method.rb +0 -108
- data/lib/aws-sdk-code-generator/dsl/module.rb +0 -167
- data/lib/aws-sdk-code-generator/dsl/option_tag.rb +0 -36
- data/lib/aws-sdk-code-generator/dsl/param.rb +0 -43
- data/lib/aws-sdk-code-generator/dsl/param_list.rb +0 -38
- data/lib/aws-sdk-code-generator/dsl/return_tag.rb +0 -19
- data/lib/aws-sdk-code-generator/dsl/tag_default.rb +0 -20
- data/lib/aws-sdk-code-generator/dsl/tag_docstring.rb +0 -27
- data/lib/aws-sdk-code-generator/dsl/tag_type.rb +0 -18
- data/lib/aws-sdk-code-generator/generators/client_api_module.rb +0 -334
- data/lib/aws-sdk-code-generator/generators/client_class.rb +0 -389
- data/lib/aws-sdk-code-generator/generators/client_operation_documentation.rb +0 -166
- data/lib/aws-sdk-code-generator/generators/errors_module.rb +0 -25
- data/lib/aws-sdk-code-generator/generators/resource/action.rb +0 -88
- data/lib/aws-sdk-code-generator/generators/resource/batch_builder.rb +0 -211
- data/lib/aws-sdk-code-generator/generators/resource/builder.rb +0 -50
- data/lib/aws-sdk-code-generator/generators/resource/client_getter.rb +0 -15
- data/lib/aws-sdk-code-generator/generators/resource/client_request.rb +0 -49
- data/lib/aws-sdk-code-generator/generators/resource/client_request_docs.rb +0 -97
- data/lib/aws-sdk-code-generator/generators/resource/client_request_params.rb +0 -88
- data/lib/aws-sdk-code-generator/generators/resource/collection_class.rb +0 -180
- data/lib/aws-sdk-code-generator/generators/resource/data_attribute_getter.rb +0 -24
- data/lib/aws-sdk-code-generator/generators/resource/data_loaded_method.rb +0 -18
- data/lib/aws-sdk-code-generator/generators/resource/data_method.rb +0 -49
- data/lib/aws-sdk-code-generator/generators/resource/exists_method.rb +0 -29
- data/lib/aws-sdk-code-generator/generators/resource/extract_identifier_method.rb +0 -32
- data/lib/aws-sdk-code-generator/generators/resource/has_association.rb +0 -101
- data/lib/aws-sdk-code-generator/generators/resource/has_many_association.rb +0 -108
- data/lib/aws-sdk-code-generator/generators/resource/identifier_getter.rb +0 -26
- data/lib/aws-sdk-code-generator/generators/resource/identifiers_method.rb +0 -28
- data/lib/aws-sdk-code-generator/generators/resource/initialize_method.rb +0 -67
- data/lib/aws-sdk-code-generator/generators/resource/load_method.rb +0 -65
- data/lib/aws-sdk-code-generator/generators/resource/value_source.rb +0 -68
- data/lib/aws-sdk-code-generator/generators/resource/waiter_method.rb +0 -61
- data/lib/aws-sdk-code-generator/generators/resource_class.rb +0 -325
- data/lib/aws-sdk-code-generator/generators/response_structure_example.rb +0 -83
- data/lib/aws-sdk-code-generator/generators/root_resource_class.rb +0 -42
- data/lib/aws-sdk-code-generator/generators/service_documentation.rb +0 -64
- data/lib/aws-sdk-code-generator/generators/shared_example.rb +0 -132
- data/lib/aws-sdk-code-generator/generators/structure_type_class.rb +0 -95
- data/lib/aws-sdk-code-generator/generators/syntax_example.rb +0 -169
- data/lib/aws-sdk-code-generator/generators/types_module.rb +0 -52
- data/lib/aws-sdk-code-generator/generators/waiter_class.rb +0 -62
- data/lib/aws-sdk-code-generator/generators/waiters_module.rb +0 -20
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
module Crosslink
|
5
|
+
|
6
|
+
BASEURL = 'http://docs.aws.amazon.com/'
|
7
|
+
EXCLUDE_UIDS = [
|
8
|
+
"apigateway",
|
9
|
+
"budgets",
|
10
|
+
"cloudsearch",
|
11
|
+
"cloudsearchdomain",
|
12
|
+
"discovery",
|
13
|
+
"elastictranscoder",
|
14
|
+
"es",
|
15
|
+
"glacier",
|
16
|
+
"importexport",
|
17
|
+
"iot",
|
18
|
+
"iot-data",
|
19
|
+
"machinelearning",
|
20
|
+
"rekognition",
|
21
|
+
"sdb",
|
22
|
+
"swf"
|
23
|
+
]
|
24
|
+
|
25
|
+
def self.tag_string(uid, name)
|
26
|
+
path = "#{BASEURL}goto/WebAPI/#{uid}/#{name}"
|
27
|
+
"@see #{path} AWS API Documentation"
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.taggable?(uid)
|
31
|
+
uid && !exclude?(uid)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
def self.exclude?(uid)
|
36
|
+
EXCLUDE_UIDS.any? do |service|
|
37
|
+
uid.match(/^#{service}/)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,199 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# kramdown
|
4
|
+
require 'kramdown'
|
5
|
+
# end kramdown
|
6
|
+
|
7
|
+
module AwsSdkCodeGenerator
|
8
|
+
module Docstring
|
9
|
+
class << self
|
10
|
+
|
11
|
+
# Prefixes each line of `text` with a pound sign. Given the string
|
12
|
+
#
|
13
|
+
# Hello
|
14
|
+
# World
|
15
|
+
#
|
16
|
+
# The following string would be returned:
|
17
|
+
#
|
18
|
+
# # Hello
|
19
|
+
# # World
|
20
|
+
#
|
21
|
+
# @param [String, nil] text
|
22
|
+
# @option options [String] :gap (' ')
|
23
|
+
# @return [String, nil]
|
24
|
+
def block_comment(text, options = {})
|
25
|
+
if text
|
26
|
+
gap = options.fetch(:gap, ' ')
|
27
|
+
text.lines.map do |line|
|
28
|
+
line = line.rstrip
|
29
|
+
if line == ''
|
30
|
+
"#"
|
31
|
+
else
|
32
|
+
"##{gap}#{line}"
|
33
|
+
end
|
34
|
+
end.join("\n")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Joins multiple doc strings into a single doc block. Each entry
|
39
|
+
# in the given `docstrings` array can be a string, nil, or an another array.
|
40
|
+
# Arrays are flattened, and nils are compacted out.
|
41
|
+
#
|
42
|
+
# Given the following `docstrings`:
|
43
|
+
#
|
44
|
+
# [
|
45
|
+
# "First doc block",
|
46
|
+
# nil,
|
47
|
+
# "Second doc block\nthat contains\nmultiple lines\n",
|
48
|
+
# [
|
49
|
+
# "Third doc block\n",
|
50
|
+
# "Last doc block\n",
|
51
|
+
# ],
|
52
|
+
# ]
|
53
|
+
#
|
54
|
+
# The following joined doc block would be returned:
|
55
|
+
#
|
56
|
+
# # First doc block
|
57
|
+
# #
|
58
|
+
# # Second doc block
|
59
|
+
# # that contains
|
60
|
+
# # multiple lines
|
61
|
+
# #
|
62
|
+
# # Third doc block
|
63
|
+
# #
|
64
|
+
# # Last doc block
|
65
|
+
#
|
66
|
+
# @param [Array<String>] docstrings
|
67
|
+
#
|
68
|
+
# @option options [Boolean] :block_comment (true)
|
69
|
+
# By default, each docstring is commented by passing
|
70
|
+
# it to {Docstring.block_comment}. Setting `:block_comment` to
|
71
|
+
# false disables this behavior.
|
72
|
+
#
|
73
|
+
# @option options [String] :gap (' ')
|
74
|
+
# This option is given to {Docstring.block_comment} when
|
75
|
+
# `:block_comment` is `true`.
|
76
|
+
#
|
77
|
+
# @option options [String] :separator (true)
|
78
|
+
# When `true`, a blank line is inserted between
|
79
|
+
# each documentation section.
|
80
|
+
#
|
81
|
+
# @return [String, nil] If the given `docstrings` is empty,
|
82
|
+
# then a `nil` is returned.
|
83
|
+
#
|
84
|
+
def join_docstrings(docstrings, options = {})
|
85
|
+
docs = docstrings.flatten.inject([]) do |sections, section|
|
86
|
+
if section.nil? || section.size == 0
|
87
|
+
sections
|
88
|
+
else
|
89
|
+
sections << (options.fetch(:block_comment, true) ?
|
90
|
+
block_comment(section, options) :
|
91
|
+
section)
|
92
|
+
sections << (options.fetch(:separator, true) ? "\n#\n" : "\n")
|
93
|
+
sections
|
94
|
+
end
|
95
|
+
end
|
96
|
+
if docs.empty?
|
97
|
+
nil
|
98
|
+
else
|
99
|
+
docs[-1] = docs[-1].rstrip
|
100
|
+
docs.join
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# @param [String]
|
105
|
+
# @return [String]
|
106
|
+
def escape_html(string)
|
107
|
+
string.to_s.encode(:xml => :text)
|
108
|
+
end
|
109
|
+
|
110
|
+
# kramdown html
|
111
|
+
# @param [String<HTML>, nil] html
|
112
|
+
# @option options [Integer] :line_width (70)
|
113
|
+
# @return [String<Markdown>, nil]
|
114
|
+
def html_to_markdown(html, options = {})
|
115
|
+
line_width = options.fetch(:line_width, 70)
|
116
|
+
# TODO : this section of code is **very slow** and runs many times
|
117
|
+
# while building a service.
|
118
|
+
if html
|
119
|
+
html = "<p>#{html}</p>" unless html.match(/<\w+>/)
|
120
|
+
|
121
|
+
# unescaped curly braces cause YARD errors, they are interpreted
|
122
|
+
# as code links.
|
123
|
+
html = html.gsub('{', "\\{").gsub('}', "\\}")
|
124
|
+
|
125
|
+
# Kramdown generates invalid markup when there are attributes
|
126
|
+
# on the code tag, have to reduce these down to get the proper markdown.
|
127
|
+
html = html.gsub(/<code.*?>(.+?)<\/code>/) { "<code>#{$1}</code>" }
|
128
|
+
|
129
|
+
# Kramdown creates invalid markup with target="_blank" attributes.
|
130
|
+
html = html.gsub(' target="_blank"', '')
|
131
|
+
|
132
|
+
# There are quite a few empty <a> tags. These appear to be code names,
|
133
|
+
# such as structure member names, or structure type names. We should
|
134
|
+
# investigate if it is possible to inflect these properly and then
|
135
|
+
# turn them into YARD links.
|
136
|
+
html = html.gsub(/<a>(.+?)<\/a>/) { $1 }
|
137
|
+
|
138
|
+
# For span tags, it can contain customized attributes, e.g. data-target
|
139
|
+
# keeping text context only for now
|
140
|
+
html = html.gsub(/<span.*?>(.+?)<\/span>/) { $1 }
|
141
|
+
|
142
|
+
# <important> tag doesn't render well
|
143
|
+
html = html.gsub(/<important>(.+?)<\/important>/){ "<p>#{$1}</p>" }
|
144
|
+
|
145
|
+
# <replaceable> doesn't render anything, so sub it out for italic
|
146
|
+
html = html.gsub(/<replaceable>(.+?)<\/replaceable>/) { "<i>#{$1}</i>" }
|
147
|
+
|
148
|
+
markdown = Kramdown::Document.new(
|
149
|
+
html,
|
150
|
+
input: 'html',
|
151
|
+
line_width: line_width,
|
152
|
+
auto_ids: false
|
153
|
+
).to_kramdown.strip
|
154
|
+
|
155
|
+
# remove extra escape
|
156
|
+
markdown.gsub(/\\(\*|`|'|")/, '\1')
|
157
|
+
end
|
158
|
+
end
|
159
|
+
# end kramdown html
|
160
|
+
|
161
|
+
# @param [Array<Array<String>>]
|
162
|
+
def markdown_table(table)
|
163
|
+
# compute the width of each column by scanning for longest values
|
164
|
+
column_width = lambda do |col|
|
165
|
+
table.map { |row| row[col].size }.max
|
166
|
+
end
|
167
|
+
widths = [
|
168
|
+
column_width.call(0),
|
169
|
+
column_width.call(1),
|
170
|
+
column_width.call(2),
|
171
|
+
column_width.call(3),
|
172
|
+
]
|
173
|
+
|
174
|
+
# insert a dashed line after the header row
|
175
|
+
table = [
|
176
|
+
table[0],
|
177
|
+
['-' * widths[0], '-' * widths[1], '-' * widths[2], '-' * widths[3]]
|
178
|
+
] + table[1..-1]
|
179
|
+
|
180
|
+
# build the final table
|
181
|
+
line = "| #{widths.map{|n| "%-#{n}s" }.join(' | ')} |"
|
182
|
+
table.map { |row| line % row }.join("\n")
|
183
|
+
end
|
184
|
+
|
185
|
+
def ucfirst(string)
|
186
|
+
if string
|
187
|
+
string[0].upcase + string[1..-1]
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
def indent(string, space = ' ')
|
192
|
+
string.lines.map do |line|
|
193
|
+
"#{space}#{line}"
|
194
|
+
end.join.lstrip
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
class ErrorList
|
5
|
+
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize(options)
|
9
|
+
@api = options[:api]
|
10
|
+
@module_name = options[:module_name]
|
11
|
+
@errors = @api['shapes'].inject([]) do |es, (name, shape)|
|
12
|
+
# only generate error shape with non empty members
|
13
|
+
# excluding event shapes marked as error
|
14
|
+
if error_struct?(shape)
|
15
|
+
members = shape['members'].inject([]) do |arr, (k, v)|
|
16
|
+
arr << {
|
17
|
+
name: Underscore.underscore(k),
|
18
|
+
type: Docstring.ucfirst(v['type'] ||'String'),
|
19
|
+
shared: k.downcase == 'message' || k.downcase == 'code'
|
20
|
+
}
|
21
|
+
arr
|
22
|
+
end
|
23
|
+
es << Error.new(
|
24
|
+
name: name,
|
25
|
+
members: members,
|
26
|
+
data_type: "#{@module_name}::Types::#{name}",
|
27
|
+
retryable: !!shape['retryable'],
|
28
|
+
throttling: throttling?(shape)
|
29
|
+
)
|
30
|
+
end
|
31
|
+
es
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def error_struct?(shape)
|
36
|
+
shape['type'] == 'structure' && !!!shape['event'] &&
|
37
|
+
(shape['error'] || shape['exception'])
|
38
|
+
end
|
39
|
+
|
40
|
+
def each(&block)
|
41
|
+
@errors.each(&block)
|
42
|
+
end
|
43
|
+
|
44
|
+
def throttling?(shape)
|
45
|
+
shape['retryable'] && shape['retryable'].kind_of?(Hash) && shape['retryable']['throttling']
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
class Error
|
50
|
+
|
51
|
+
def initialize(options)
|
52
|
+
@name = options.fetch(:name)
|
53
|
+
@data_type = options[:data_type]
|
54
|
+
@members = options[:members]
|
55
|
+
@retryable = options[:retryable]
|
56
|
+
@throttling = options[:throttling]
|
57
|
+
end
|
58
|
+
|
59
|
+
# @return [String]
|
60
|
+
attr_reader :name
|
61
|
+
|
62
|
+
# @return [String]
|
63
|
+
attr_reader :data_type
|
64
|
+
|
65
|
+
# @return [Array<Hash>]
|
66
|
+
attr_reader :members
|
67
|
+
|
68
|
+
# @return [Boolean]
|
69
|
+
attr_reader :retryable
|
70
|
+
|
71
|
+
# @return [Boolean]
|
72
|
+
attr_reader :throttling
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AwsSdkCodeGenerator
|
4
|
+
class EventStreamExample
|
5
|
+
|
6
|
+
def initialize(options = {})
|
7
|
+
@api = options.fetch(:api)
|
8
|
+
@method_name = options.fetch(:method_name)
|
9
|
+
@module_name = options.fetch(:module_name)
|
10
|
+
@receiver = options.fetch(:receiver)
|
11
|
+
@resp_var = options.fetch(:resp_var)
|
12
|
+
@operation = options.fetch(:operation)
|
13
|
+
@input_eventstream_member, @input_eventstream_shape = input_eventstream_shape
|
14
|
+
@output_eventstream_member, @output_eventstream_shape = output_eventstream_shape
|
15
|
+
if @input_eventstream_shape && @output_eventstream_shape &&
|
16
|
+
@input_eventstream_shape == @output_eventstream_shape
|
17
|
+
# input and output sharing same eventstream
|
18
|
+
# renaming, see EventStreamModules
|
19
|
+
@input_eventstream = "#{@module_name}::EventStreams::Input#{@input_eventstream_shape}"
|
20
|
+
@output_eventstream = "#{@module_name}::EventStreams::Output#{@output_eventstream_shape}"
|
21
|
+
else
|
22
|
+
@input_eventstream = "#{@module_name}::EventStreams::#{@input_eventstream_shape}" if @input_eventstream_shape
|
23
|
+
@output_eventstream = "#{@module_name}::EventStreams::#{@output_eventstream_shape}" if @output_eventstream_shape
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def format
|
28
|
+
if @input_eventstream_member && @output_eventstream_member
|
29
|
+
bi_directional_format
|
30
|
+
elsif @output_eventstream_member
|
31
|
+
output_format
|
32
|
+
# elsif @input_eventstream_member
|
33
|
+
# input stream only is supported naturally, but
|
34
|
+
# unclear usage when just input streaming, so pending for now
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def bi_directional_format
|
39
|
+
<<-EXAMPLE.strip
|
40
|
+
# @example Bi-directional EventStream Operation Example
|
41
|
+
#
|
42
|
+
# You can signal input events after initial request is
|
43
|
+
# established, events will be sent to stream
|
44
|
+
# immediately (once stream connection is established successfully).
|
45
|
+
#
|
46
|
+
# To signal events, you can call #signal methods from an #{@input_eventstream} object.
|
47
|
+
# Make sure signal events before calling #wait or #join! at async response.
|
48
|
+
#
|
49
|
+
# input_stream = #{@input_eventstream}.new
|
50
|
+
#
|
51
|
+
# async_resp = #{@receiver}.#{@method_name}( # params input,
|
52
|
+
# input_event_stream_handler: input_stream) do |out_stream|
|
53
|
+
#
|
54
|
+
# # register callbacks for events arrival
|
55
|
+
#{event_entry(:output, 'out_stream', 2)}
|
56
|
+
#
|
57
|
+
# end
|
58
|
+
# # => returns Aws::Seahorse::Client::AsyncResponse
|
59
|
+
#
|
60
|
+
# # signal events
|
61
|
+
#{event_entry(:input, 'input_stream')}
|
62
|
+
#
|
63
|
+
# # make sure signaling :end_stream in the end
|
64
|
+
# input_stream.signal_end_stream
|
65
|
+
#
|
66
|
+
# # wait until stream is closed before finalizing sync response
|
67
|
+
# resp = async_resp.wait
|
68
|
+
# # Or close stream and finalizing sync response immediately
|
69
|
+
# # resp = async_resp.join!
|
70
|
+
#
|
71
|
+
# Inorder to streamingly processing events received, you can also provide an #{@output_eventstream}
|
72
|
+
# object to register callbacks before initializing request instead of processing from request block
|
73
|
+
#
|
74
|
+
# output_stream = #{@output_eventstream}.new
|
75
|
+
# # register callbacks for events arrival
|
76
|
+
#{event_entry(:output, 'output_stream')}
|
77
|
+
#{error_event_entry('output_stream')}
|
78
|
+
#
|
79
|
+
# async_resp = #{@receiver}.#{@method_name} ( #params input,
|
80
|
+
# input_event_stream_handler: input_stream
|
81
|
+
# output_event_stream_handler: output_stream
|
82
|
+
# )
|
83
|
+
#
|
84
|
+
# resp = async_resp.wait!
|
85
|
+
#
|
86
|
+
# Besides above usage patterns for process events when they arrive immediately, you can also
|
87
|
+
# iterate through events after response complete.
|
88
|
+
#
|
89
|
+
# Events are available at #{@resp_var}.#{@output_eventstream_member} # => Enumerator
|
90
|
+
EXAMPLE
|
91
|
+
end
|
92
|
+
|
93
|
+
def output_format
|
94
|
+
<<-EXAMPLE.strip
|
95
|
+
# @example EventStream Operation Example
|
96
|
+
#
|
97
|
+
# You can process event once it arrives immediately, or wait until
|
98
|
+
# full response complete and iterate through eventstream enumerator.
|
99
|
+
#
|
100
|
+
# To interact with event immediately, you need to register ##{@method_name}
|
101
|
+
# with callbacks, callbacks can be register for specifc events or for all events,
|
102
|
+
# callback for errors in the event stream is also available for register.
|
103
|
+
#
|
104
|
+
# Callbacks can be passed in by `:event_stream_handler` option or within block
|
105
|
+
# statement attached to ##{@method_name} call directly. Hybrid pattern of both
|
106
|
+
# is also supported.
|
107
|
+
#
|
108
|
+
# `:event_stream_handler` option takes in either Proc object or
|
109
|
+
# #{@output_eventstream} object.
|
110
|
+
#
|
111
|
+
# Usage pattern a): callbacks with a block attached to ##{@method_name}
|
112
|
+
# Example for registering callbacks for all event types and error event
|
113
|
+
#
|
114
|
+
# #{@receiver}.#{@method_name}( # params input# ) do |stream|
|
115
|
+
#{error_event_entry('stream', 2)}
|
116
|
+
#
|
117
|
+
# stream.on_event do |event|
|
118
|
+
# # process all events arrive
|
119
|
+
# puts event.event_type
|
120
|
+
# ...
|
121
|
+
# end
|
122
|
+
#
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# Usage pattern b): pass in `:event_stream_handler` for ##{@method_name}
|
126
|
+
#
|
127
|
+
# 1) create a #{@output_eventstream} object
|
128
|
+
# Example for registering callbacks with specific events
|
129
|
+
#
|
130
|
+
# handler = #{@output_eventstream}.new
|
131
|
+
#{event_entry(:output, 'handler', 2)}
|
132
|
+
#
|
133
|
+
# #{@receiver}.#{@method_name}( # params input #, event_stream_handler: handler)
|
134
|
+
#
|
135
|
+
# 2) use a Ruby Proc object
|
136
|
+
# Example for registering callbacks with specific events
|
137
|
+
#
|
138
|
+
# handler = Proc.new do |stream|
|
139
|
+
#{event_entry(:output, 'stream', 2)}
|
140
|
+
# end
|
141
|
+
#
|
142
|
+
# #{@receiver}.#{@method_name}( # params input #, event_stream_handler: handler)
|
143
|
+
#
|
144
|
+
# Usage pattern c): hybird pattern of a) and b)
|
145
|
+
#
|
146
|
+
# handler = #{@output_eventstream}.new
|
147
|
+
#{event_entry(:output, 'handler', 2)}
|
148
|
+
#
|
149
|
+
# #{@receiver}.#{@method_name}( # params input #, event_stream_handler: handler) do |stream|
|
150
|
+
#{error_event_entry('stream', 2)}
|
151
|
+
# end
|
152
|
+
#
|
153
|
+
# Besides above usage patterns for process events when they arrive immediately, you can also
|
154
|
+
# iterate through events after response complete.
|
155
|
+
#
|
156
|
+
# Events are available at #{@resp_var}.#{@output_eventstream_member} # => Enumerator
|
157
|
+
# For parameter input example, please refer to following request syntax
|
158
|
+
EXAMPLE
|
159
|
+
end
|
160
|
+
|
161
|
+
def event_entry(type, ctx, indent = 0)
|
162
|
+
case type
|
163
|
+
when :input then input_event_entries(ctx, indent)
|
164
|
+
when :output then output_event_entries(ctx, indent)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def error_event_entry(ctx, indent = 0)
|
169
|
+
entries = []
|
170
|
+
entries << "# #{' ' * indent}#{ctx}.on_error_event do |event|"
|
171
|
+
entries << "# #{' ' * indent} # catch unmodeled error event in the stream"
|
172
|
+
entries << "# #{' ' * indent} raise event"
|
173
|
+
entries << "# #{' ' * indent} # => Aws::Errors::EventError"
|
174
|
+
entries << "# #{' ' * indent} # event.event_type => :error"
|
175
|
+
entries << "# #{' ' * indent} # event.error_code => String"
|
176
|
+
entries << "# #{' ' * indent} # event.error_message => String"
|
177
|
+
entries << "# #{' ' * indent}end"
|
178
|
+
entries.join("\n")
|
179
|
+
end
|
180
|
+
|
181
|
+
def input_event_entries(ctx, indent = 0)
|
182
|
+
@api['shapes'][@input_eventstream_shape]['members'].each.inject([]) do |entries, (name, _)|
|
183
|
+
event_type = Underscore.underscore(name)
|
184
|
+
# TODO, place holder values
|
185
|
+
entries << "# #{' ' * indent}#{ctx}.signal_#{event_type}_event( ... )"
|
186
|
+
entries
|
187
|
+
end.join("\n")
|
188
|
+
end
|
189
|
+
|
190
|
+
def output_event_entries(ctx, indent = 0)
|
191
|
+
@api['shapes'][@output_eventstream_shape]['members'].keys.each.inject([]) do |entry, name|
|
192
|
+
event_type = Underscore.underscore(name)
|
193
|
+
entry << "# #{' ' * indent}#{ctx}.on_#{event_type}_event do |event|"
|
194
|
+
entry << "# #{' ' * indent}event # => #{@module_name}::Types::#{name}"
|
195
|
+
entry << "# #{' ' * indent}end"
|
196
|
+
end.join("\n")
|
197
|
+
end
|
198
|
+
|
199
|
+
def input_eventstream_shape
|
200
|
+
input_shape = @api['shapes'][@operation['input']['shape']] if @operation['input']
|
201
|
+
if input_shape
|
202
|
+
input_shape['members'].each do |name, ref|
|
203
|
+
return [Underscore.underscore(name), ref['shape']] if Api.eventstream?(ref, @api)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
nil
|
207
|
+
end
|
208
|
+
|
209
|
+
def output_eventstream_shape
|
210
|
+
output_shape = @api['shapes'][@operation['output']['shape']] if @operation['output']
|
211
|
+
if output_shape
|
212
|
+
output_shape['members'].each do |name, ref|
|
213
|
+
return [Underscore.underscore(name), ref['shape']] if Api.eventstream?(ref, @api)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
nil
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
end
|