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.
Files changed (131) hide show
  1. checksums.yaml +5 -5
  2. data/lib/aws-sdk-code-generator.rb +68 -75
  3. data/lib/aws-sdk-code-generator/api.rb +130 -0
  4. data/lib/aws-sdk-code-generator/apply_docs.rb +15 -2
  5. data/lib/aws-sdk-code-generator/client_constructor.rb +39 -0
  6. data/lib/aws-sdk-code-generator/client_operation_documentation.rb +268 -0
  7. data/lib/aws-sdk-code-generator/client_operation_list.rb +148 -0
  8. data/lib/aws-sdk-code-generator/client_response_structure_example.rb +108 -0
  9. data/lib/aws-sdk-code-generator/code_builder.rb +146 -133
  10. data/lib/aws-sdk-code-generator/crosslink.rb +42 -0
  11. data/lib/aws-sdk-code-generator/docstring.rb +199 -0
  12. data/lib/aws-sdk-code-generator/error_list.rb +77 -0
  13. data/lib/aws-sdk-code-generator/errors.rb +2 -0
  14. data/lib/aws-sdk-code-generator/eventstream_example.rb +220 -0
  15. data/lib/aws-sdk-code-generator/gem_builder.rb +19 -25
  16. data/lib/aws-sdk-code-generator/hash_formatter.rb +5 -2
  17. data/lib/aws-sdk-code-generator/helper.rb +77 -61
  18. data/lib/aws-sdk-code-generator/plugin_list.rb +146 -0
  19. data/lib/aws-sdk-code-generator/resource_action.rb +69 -0
  20. data/lib/aws-sdk-code-generator/resource_action_code.rb +57 -0
  21. data/lib/aws-sdk-code-generator/resource_association.rb +37 -0
  22. data/lib/aws-sdk-code-generator/resource_attribute.rb +76 -0
  23. data/lib/aws-sdk-code-generator/resource_batch_action.rb +56 -0
  24. data/lib/aws-sdk-code-generator/resource_batch_action_code.rb +136 -0
  25. data/lib/aws-sdk-code-generator/resource_batch_action_documentation.rb +108 -0
  26. data/lib/aws-sdk-code-generator/resource_batch_builder.rb +212 -0
  27. data/lib/aws-sdk-code-generator/resource_builder.rb +48 -0
  28. data/lib/aws-sdk-code-generator/resource_client_request.rb +62 -0
  29. data/lib/aws-sdk-code-generator/resource_client_request_documentation.rb +81 -0
  30. data/lib/aws-sdk-code-generator/resource_client_request_params.rb +86 -0
  31. data/lib/aws-sdk-code-generator/resource_data_method.rb +60 -0
  32. data/lib/aws-sdk-code-generator/resource_has_association.rb +117 -0
  33. data/lib/aws-sdk-code-generator/resource_has_many_association.rb +52 -0
  34. data/lib/aws-sdk-code-generator/resource_has_many_association_code.rb +76 -0
  35. data/lib/aws-sdk-code-generator/resource_identifier.rb +44 -0
  36. data/lib/aws-sdk-code-generator/resource_identifiers_method.rb +29 -0
  37. data/lib/aws-sdk-code-generator/resource_load_method.rb +68 -0
  38. data/lib/aws-sdk-code-generator/resource_method.rb +22 -0
  39. data/lib/aws-sdk-code-generator/resource_skip_params.rb +36 -0
  40. data/lib/aws-sdk-code-generator/resource_value_source.rb +68 -0
  41. data/lib/aws-sdk-code-generator/resource_waiter.rb +80 -0
  42. data/lib/aws-sdk-code-generator/service.rb +30 -7
  43. data/lib/aws-sdk-code-generator/shared_example.rb +131 -0
  44. data/lib/aws-sdk-code-generator/syntax_example.rb +60 -0
  45. data/lib/aws-sdk-code-generator/syntax_example_hash.rb +174 -0
  46. data/lib/aws-sdk-code-generator/underscore.rb +10 -5
  47. data/lib/aws-sdk-code-generator/view.rb +33 -0
  48. data/lib/aws-sdk-code-generator/views.rb +2 -0
  49. data/lib/aws-sdk-code-generator/views/apig_endpoint_class.rb +25 -0
  50. data/lib/aws-sdk-code-generator/views/apig_readme.rb +32 -0
  51. data/lib/aws-sdk-code-generator/views/async_client_class.rb +68 -0
  52. data/lib/aws-sdk-code-generator/views/authorizer_class.rb +17 -0
  53. data/lib/aws-sdk-code-generator/views/client_api_module.rb +583 -0
  54. data/lib/aws-sdk-code-generator/views/client_class.rb +93 -0
  55. data/lib/aws-sdk-code-generator/views/docstring.rb +27 -0
  56. data/lib/aws-sdk-code-generator/views/errors_module.rb +32 -0
  57. data/lib/aws-sdk-code-generator/views/event_streams_module.rb +149 -0
  58. data/lib/aws-sdk-code-generator/views/features/env.rb +9 -0
  59. data/lib/aws-sdk-code-generator/views/features/smoke.rb +51 -0
  60. data/lib/aws-sdk-code-generator/views/features/smoke_step_definitions.rb +26 -0
  61. data/lib/aws-sdk-code-generator/views/features/step_definitions.rb +2 -0
  62. data/lib/aws-sdk-code-generator/views/gemspec.rb +39 -5
  63. data/lib/aws-sdk-code-generator/views/resource_class.rb +122 -0
  64. data/lib/aws-sdk-code-generator/views/root_resource_class.rb +58 -0
  65. data/lib/aws-sdk-code-generator/views/service_module.rb +30 -14
  66. data/lib/aws-sdk-code-generator/views/spec/spec_helper.rb +9 -0
  67. data/lib/aws-sdk-code-generator/views/types_module.rb +294 -0
  68. data/lib/aws-sdk-code-generator/views/version.rb +2 -0
  69. data/lib/aws-sdk-code-generator/views/waiters_module.rb +37 -0
  70. data/lib/aws-sdk-code-generator/waiter.rb +95 -0
  71. data/lib/aws-sdk-code-generator/yard_option_tag.rb +43 -0
  72. metadata +61 -68
  73. data/lib/aws-sdk-code-generator/dsl/access_control_statement.rb +0 -23
  74. data/lib/aws-sdk-code-generator/dsl/attribute_accessor.rb +0 -43
  75. data/lib/aws-sdk-code-generator/dsl/attribute_reader.rb +0 -11
  76. data/lib/aws-sdk-code-generator/dsl/attribute_writer.rb +0 -11
  77. data/lib/aws-sdk-code-generator/dsl/autoload_statement.rb +0 -15
  78. data/lib/aws-sdk-code-generator/dsl/block_param.rb +0 -11
  79. data/lib/aws-sdk-code-generator/dsl/class.rb +0 -27
  80. data/lib/aws-sdk-code-generator/dsl/code_literal.rb +0 -66
  81. data/lib/aws-sdk-code-generator/dsl/code_object.rb +0 -33
  82. data/lib/aws-sdk-code-generator/dsl/docstring.rb +0 -36
  83. data/lib/aws-sdk-code-generator/dsl/eigenclass.rb +0 -15
  84. data/lib/aws-sdk-code-generator/dsl/extend_statement.rb +0 -12
  85. data/lib/aws-sdk-code-generator/dsl/formatter.rb +0 -25
  86. data/lib/aws-sdk-code-generator/dsl/include_statement.rb +0 -17
  87. data/lib/aws-sdk-code-generator/dsl/main.rb +0 -105
  88. data/lib/aws-sdk-code-generator/dsl/method.rb +0 -108
  89. data/lib/aws-sdk-code-generator/dsl/module.rb +0 -167
  90. data/lib/aws-sdk-code-generator/dsl/option_tag.rb +0 -36
  91. data/lib/aws-sdk-code-generator/dsl/param.rb +0 -43
  92. data/lib/aws-sdk-code-generator/dsl/param_list.rb +0 -38
  93. data/lib/aws-sdk-code-generator/dsl/return_tag.rb +0 -19
  94. data/lib/aws-sdk-code-generator/dsl/tag_default.rb +0 -20
  95. data/lib/aws-sdk-code-generator/dsl/tag_docstring.rb +0 -27
  96. data/lib/aws-sdk-code-generator/dsl/tag_type.rb +0 -18
  97. data/lib/aws-sdk-code-generator/generators/client_api_module.rb +0 -334
  98. data/lib/aws-sdk-code-generator/generators/client_class.rb +0 -389
  99. data/lib/aws-sdk-code-generator/generators/client_operation_documentation.rb +0 -166
  100. data/lib/aws-sdk-code-generator/generators/errors_module.rb +0 -25
  101. data/lib/aws-sdk-code-generator/generators/resource/action.rb +0 -88
  102. data/lib/aws-sdk-code-generator/generators/resource/batch_builder.rb +0 -211
  103. data/lib/aws-sdk-code-generator/generators/resource/builder.rb +0 -50
  104. data/lib/aws-sdk-code-generator/generators/resource/client_getter.rb +0 -15
  105. data/lib/aws-sdk-code-generator/generators/resource/client_request.rb +0 -49
  106. data/lib/aws-sdk-code-generator/generators/resource/client_request_docs.rb +0 -97
  107. data/lib/aws-sdk-code-generator/generators/resource/client_request_params.rb +0 -88
  108. data/lib/aws-sdk-code-generator/generators/resource/collection_class.rb +0 -180
  109. data/lib/aws-sdk-code-generator/generators/resource/data_attribute_getter.rb +0 -24
  110. data/lib/aws-sdk-code-generator/generators/resource/data_loaded_method.rb +0 -18
  111. data/lib/aws-sdk-code-generator/generators/resource/data_method.rb +0 -49
  112. data/lib/aws-sdk-code-generator/generators/resource/exists_method.rb +0 -29
  113. data/lib/aws-sdk-code-generator/generators/resource/extract_identifier_method.rb +0 -32
  114. data/lib/aws-sdk-code-generator/generators/resource/has_association.rb +0 -101
  115. data/lib/aws-sdk-code-generator/generators/resource/has_many_association.rb +0 -108
  116. data/lib/aws-sdk-code-generator/generators/resource/identifier_getter.rb +0 -26
  117. data/lib/aws-sdk-code-generator/generators/resource/identifiers_method.rb +0 -28
  118. data/lib/aws-sdk-code-generator/generators/resource/initialize_method.rb +0 -67
  119. data/lib/aws-sdk-code-generator/generators/resource/load_method.rb +0 -65
  120. data/lib/aws-sdk-code-generator/generators/resource/value_source.rb +0 -68
  121. data/lib/aws-sdk-code-generator/generators/resource/waiter_method.rb +0 -61
  122. data/lib/aws-sdk-code-generator/generators/resource_class.rb +0 -325
  123. data/lib/aws-sdk-code-generator/generators/response_structure_example.rb +0 -83
  124. data/lib/aws-sdk-code-generator/generators/root_resource_class.rb +0 -42
  125. data/lib/aws-sdk-code-generator/generators/service_documentation.rb +0 -64
  126. data/lib/aws-sdk-code-generator/generators/shared_example.rb +0 -132
  127. data/lib/aws-sdk-code-generator/generators/structure_type_class.rb +0 -95
  128. data/lib/aws-sdk-code-generator/generators/syntax_example.rb +0 -169
  129. data/lib/aws-sdk-code-generator/generators/types_module.rb +0 -52
  130. data/lib/aws-sdk-code-generator/generators/waiter_class.rb +0 -62
  131. 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
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module AwsSdkCodeGenerator
2
4
  module Errors
3
5
 
@@ -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