aws-sdk-code-generator 0.1.0.pre → 0.2.0.pre

Sign up to get free protection for your applications and to get access to all the features.
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