gapic-generator 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -0
- data/lib/gapic/generator/version.rb +1 -1
- data/lib/gapic/generators/default_generator.rb +18 -5
- data/lib/gapic/generators/default_generator_parameters.rb +8 -4
- data/lib/gapic/presenters.rb +3 -0
- data/lib/gapic/presenters/field_presenter.rb +44 -0
- data/lib/gapic/presenters/gem_presenter.rb +47 -10
- data/lib/gapic/presenters/method_presenter.rb +36 -16
- data/lib/gapic/presenters/method_rest_presenter.rb +194 -0
- data/lib/gapic/presenters/package_presenter.rb +18 -0
- data/lib/gapic/presenters/service_presenter.rb +42 -4
- data/lib/gapic/presenters/service_rest_presenter.rb +139 -0
- data/lib/gapic/presenters/snippet_presenter.rb +103 -0
- data/lib/gapic/runner.rb +2 -1
- data/lib/gapic/schema/api.rb +58 -16
- data/lib/gapic/schema/request_param_parser.rb +46 -12
- data/lib/google/protobuf/any.pb.rb +1 -1
- data/lib/google/protobuf/compiler/plugin.pb.rb +9 -6
- data/lib/google/protobuf/descriptor.pb.rb +2 -2
- data/lib/google/protobuf/empty.pb.rb +1 -1
- data/templates/default/gem/readme.erb +2 -2
- data/templates/default/lib/_package.erb +11 -1
- data/templates/default/lib/_service.erb +31 -1
- data/templates/default/lib/rest/_rest.erb +11 -0
- data/templates/default/service/rest.erb +6 -0
- data/templates/default/service/rest/client.erb +6 -0
- data/templates/default/service/rest/client/_client.erb +115 -0
- data/templates/default/service/rest/client/_config.erb +74 -0
- data/templates/default/service/rest/client/_requires.erb +1 -0
- data/templates/default/service/rest/client/method/_def.erb +18 -0
- data/templates/default/service/rest/client/method/def/_options_defaults.erb +15 -0
- data/templates/default/service/rest/client/method/def/_rescue.erb +3 -0
- data/templates/default/service/rest/client/method/def/_response_normal.erb +17 -0
- data/templates/default/service/rest/client/method/docs/_error.erb +2 -0
- data/templates/default/service/rest/client/method/docs/_request.erb +27 -0
- data/templates/default/service/rest/client/method/docs/_result.erb +6 -0
- data/templates/default/service/rest/grpc_transcoding.erb +6 -0
- data/templates/default/service/rest/grpc_transcoding/_grpc_transcoding.erb +9 -0
- data/templates/default/service/rest/grpc_transcoding/method/_def.erb +21 -0
- data/templates/default/service/rest/grpc_transcoding/method/def/_query_string_param.erb +8 -0
- data/templates/default/service/rest/test/client.erb +18 -0
- data/templates/default/service/rest/test/method/_assert_response.erb +2 -0
- data/templates/default/service/rest/test/method/_configure.erb +19 -0
- data/templates/default/service/rest/test/method/_normal.erb +71 -0
- data/templates/default/service/rest/test/method/_setup.erb +38 -0
- data/templates/default/snippets/gemfile.erb +17 -0
- data/templates/default/snippets/snippet/_structure.erb +71 -0
- data/templates/default/snippets/standalone.erb +6 -0
- metadata +31 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c8a401f416529802324b86833c5c3a9fcef01afd699439053ce868a7862c5c8
|
4
|
+
data.tar.gz: 6f794cc05eb33a4c201bdcc62dc62524406ae2fb003f0b2d9c536482517a4109
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 536731d9a866b0c58540b6eb6f62469eef75f10f82a9fba3c45e0e5a2c5d08b7f5b97b0b385b3e6063e418e0faba687faf45c44cc700ab69da554c9d28a46049
|
7
|
+
data.tar.gz: c1b99ad4ebfae8c4085522924ba4fd11f1a2628b67d64dfc549f22df40aadf5d79ae127bcac73ca5fe2795937f29556b6f656d5b86c66aaef43c78ec644b6772
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,46 @@
|
|
1
1
|
# Release History for gapic-generator
|
2
2
|
|
3
|
+
### 0.8.0 / 2021-06-16
|
4
|
+
|
5
|
+
* Initial implementation of standalone snippet generation.
|
6
|
+
* Updated gapic-common dependencies to require at least 0.5 and to support future 1.x versions.
|
7
|
+
* Generated unit tests for REST clients.
|
8
|
+
* Generated proper x-goog-api-client headers for REST clients.
|
9
|
+
* Added generation arguments to generated repo metadata.
|
10
|
+
* Allow multiple versions in the extra-dependency command line argument.
|
11
|
+
* Fixed treatment of boolean-valued command line arguments to the generator.
|
12
|
+
* Fixed behavior of wrapper-gem-override if given an empty value.
|
13
|
+
* Fixed default env_prefix computation to avoid the version part of the proto namespace.
|
14
|
+
* Fixed Bazel front-end to preserve file permissions.
|
15
|
+
|
16
|
+
### 0.7.5 / 2021-05-18
|
17
|
+
|
18
|
+
* Bazel jobs now provide a prebuilt ruby binary.
|
19
|
+
* Fixed generated indentation for a few cases, by updating to Rubocop 1.15.
|
20
|
+
* Added library_type to generated repo metadata files.
|
21
|
+
|
22
|
+
### 0.7.4 / 2021-05-07
|
23
|
+
|
24
|
+
* Fixed the broken link in the generated libraries' README.md
|
25
|
+
* Generated libraries with REST transport now use presense testing instead of rejecting defaults to determine which fields to transcode into the query string parameters
|
26
|
+
|
27
|
+
### 0.7.3 / 2021-03-24
|
28
|
+
|
29
|
+
* Fixed gapic metadata (drift manifest) generation
|
30
|
+
* Gapic metadata generation is disabled by default in gapic-generator
|
31
|
+
(enabled by default in gapic-generator-cloud)
|
32
|
+
* Can now generate libraries with REST transport in addition to GRPC
|
33
|
+
* gapic-common 0.4 is the default version for the generated libraries now (was 0.3)
|
34
|
+
(required for the generated libraries with the REST transport)
|
35
|
+
|
36
|
+
### 0.7.2 / 2021-03-05
|
37
|
+
|
38
|
+
* No changes.
|
39
|
+
|
40
|
+
### 0.7.1 / 2021-02-27
|
41
|
+
|
42
|
+
* Update generated readmes to reflect that Ruby 2.5 or later is now required.
|
43
|
+
|
3
44
|
### 0.7.0 / 2021-02-27
|
4
45
|
|
5
46
|
* Update minimum Ruby version to 2.5 for generated libraries.
|
@@ -54,13 +54,24 @@ module Gapic
|
|
54
54
|
package.services.each do |service|
|
55
55
|
# Service level files
|
56
56
|
files << g("service.erb", "lib/#{service.service_file_path}", service: service)
|
57
|
-
files << g("service/
|
57
|
+
files << g("service/rest.erb", "lib/#{service.rest.service_rest_file_path}", service: service) if @api.generate_rest_clients? and service.methods_rest_bindings?
|
58
|
+
files << g("service/client.erb", "lib/#{service.client_file_path}", service: service) unless @api.generate_rest_clients?
|
58
59
|
files << g("service/credentials.erb", "lib/#{service.credentials_file_path}", service: service) unless gem.generic_endpoint?
|
59
60
|
files << g("service/paths.erb", "lib/#{service.paths_file_path}", service: service) if service.paths?
|
60
|
-
files << g("service/operations.erb", "lib/#{service.operations_file_path}", service: service) if service.lro?
|
61
|
-
files << g("service/
|
61
|
+
files << g("service/operations.erb", "lib/#{service.operations_file_path}", service: service) if service.lro? && !@api.generate_rest_clients?
|
62
|
+
files << g("service/rest/client.erb", "lib/#{service.rest.client_file_path}", service: service) if @api.generate_rest_clients? and service.methods_rest_bindings?
|
63
|
+
files << g("service/rest/grpc_transcoding.erb", "lib/#{service.rest.transcoding_helper_file_path}", service: service) if @api.generate_rest_clients? and service.methods_rest_bindings?
|
64
|
+
files << g("service/rest/test/client.erb", "test/#{service.rest.test_client_file_path}", service: service) if @api.generate_rest_clients? and service.methods_rest_bindings?
|
65
|
+
files << g("service/test/client.erb", "test/#{service.test_client_file_path}", service: service) unless @api.generate_rest_clients?
|
62
66
|
files << g("service/test/client_paths.erb", "test/#{service.test_paths_file_path}", service: service) if service.paths?
|
63
|
-
files << g("service/test/client_operations.erb", "test/#{service.test_client_operations_file_path}", service: service) if service.lro?
|
67
|
+
files << g("service/test/client_operations.erb", "test/#{service.test_client_operations_file_path}", service: service) if service.lro? && !@api.generate_rest_clients?
|
68
|
+
|
69
|
+
if @api.generate_standalone_snippets?
|
70
|
+
service.methods.each do |method|
|
71
|
+
snippet = method.snippet
|
72
|
+
files << g("snippets/standalone.erb", "snippets/#{snippet.snippet_file_path}", snippet: snippet)
|
73
|
+
end
|
74
|
+
end
|
64
75
|
end
|
65
76
|
end
|
66
77
|
|
@@ -77,7 +88,9 @@ module Gapic
|
|
77
88
|
files << g("gem/yardopts.erb", ".yardopts", gem: gem)
|
78
89
|
files << g("gem/license.erb", "LICENSE.md", gem: gem)
|
79
90
|
files << g("gem/entrypoint.erb", "lib/#{gem.name}.rb", gem: gem)
|
80
|
-
files << g("gem/gapic_metadata_json.erb", "gapic_metadata.json", gem: gem)
|
91
|
+
files << g("gem/gapic_metadata_json.erb", "gapic_metadata.json", gem: gem) if @api.generate_metadata
|
92
|
+
|
93
|
+
files << g("snippets/gemfile.erb", "snippets/Gemfile", gem: gem) if @api.generate_standalone_snippets?
|
81
94
|
|
82
95
|
gem.proto_files.each do |proto_file|
|
83
96
|
files << g("proto_docs/proto_file.erb", "proto_docs/#{proto_file.docs_file_path}", file: proto_file)
|
@@ -23,7 +23,8 @@ module Gapic
|
|
23
23
|
BOOL_PARAMETERS = [
|
24
24
|
":gem.:free_tier",
|
25
25
|
":gem.:yard_strict",
|
26
|
-
":gem.:generic_endpoint"
|
26
|
+
":gem.:generic_endpoint",
|
27
|
+
":generate_metadata"
|
27
28
|
].freeze
|
28
29
|
|
29
30
|
STRING_PARAMETERS = [
|
@@ -42,11 +43,13 @@ module Gapic
|
|
42
43
|
":gem.:api_shortname",
|
43
44
|
":gem.:factory_method_suffix",
|
44
45
|
":defaults.:service.:default_host",
|
45
|
-
"grpc_service_config"
|
46
|
+
"grpc_service_config",
|
47
|
+
":overrides.:wrapper_gem_name"
|
46
48
|
].freeze
|
47
49
|
|
48
50
|
ARRAY_PARAMETERS = [
|
49
|
-
":defaults.:service.:oauth_scopes"
|
51
|
+
":defaults.:service.:oauth_scopes",
|
52
|
+
":transports"
|
50
53
|
].freeze
|
51
54
|
|
52
55
|
MAP_PARAMETERS = [
|
@@ -83,7 +86,8 @@ module Gapic
|
|
83
86
|
}.freeze
|
84
87
|
|
85
88
|
ARRAY_PARAMETERS_ALIASES = {
|
86
|
-
"default-oauth-scopes" => ":defaults.:service.:oauth_scopes"
|
89
|
+
"default-oauth-scopes" => ":defaults.:service.:oauth_scopes",
|
90
|
+
"transports" => ":transports"
|
87
91
|
}.freeze
|
88
92
|
|
89
93
|
MAP_PARAMETERS_ALIASES = {
|
data/lib/gapic/presenters.rb
CHANGED
@@ -21,10 +21,13 @@ require "gapic/presenters/file_presenter"
|
|
21
21
|
require "gapic/presenters/gem_presenter"
|
22
22
|
require "gapic/presenters/message_presenter"
|
23
23
|
require "gapic/presenters/method_presenter"
|
24
|
+
require "gapic/presenters/method_rest_presenter"
|
24
25
|
require "gapic/presenters/package_presenter"
|
25
26
|
require "gapic/presenters/resource_presenter"
|
26
27
|
require "gapic/presenters/sample_presenter"
|
27
28
|
require "gapic/presenters/service_presenter"
|
29
|
+
require "gapic/presenters/service_rest_presenter"
|
30
|
+
require "gapic/presenters/snippet_presenter"
|
28
31
|
|
29
32
|
module Gapic
|
30
33
|
##
|
@@ -88,6 +88,10 @@ module Gapic
|
|
88
88
|
@field.repeated?
|
89
89
|
end
|
90
90
|
|
91
|
+
def required?
|
92
|
+
@field.required?
|
93
|
+
end
|
94
|
+
|
91
95
|
def map?
|
92
96
|
@field.map?
|
93
97
|
end
|
@@ -100,6 +104,34 @@ module Gapic
|
|
100
104
|
@message.oneof_decl[@field.oneof_index].name
|
101
105
|
end
|
102
106
|
|
107
|
+
##
|
108
|
+
# Returns a stringified default value for the protobuf types
|
109
|
+
# that are possible to fit into the query string parameter
|
110
|
+
# and nil for the other types (e.g. Messages)
|
111
|
+
#
|
112
|
+
# @return [String, nil]
|
113
|
+
#
|
114
|
+
def default_value_for_type
|
115
|
+
if @field.message?
|
116
|
+
nil
|
117
|
+
elsif @field.enum?
|
118
|
+
":#{@field.enum.values.first.name}"
|
119
|
+
else
|
120
|
+
case @field.type
|
121
|
+
when 1, 2, 3, 4, 5, 6, 7, 13, 15, 16, 17, 18 then "0" # floating point or integer
|
122
|
+
when 9, 12 then "\"\""
|
123
|
+
when 8 then "false"
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
##
|
129
|
+
# Name of this field, camel-cased
|
130
|
+
# @return [String]
|
131
|
+
def camel_name
|
132
|
+
camel_name_for name
|
133
|
+
end
|
134
|
+
|
103
135
|
protected
|
104
136
|
|
105
137
|
def field_doc_types field, output
|
@@ -161,6 +193,18 @@ module Gapic
|
|
161
193
|
def message_ruby_type message
|
162
194
|
ruby_namespace @api, message.address.join(".")
|
163
195
|
end
|
196
|
+
|
197
|
+
##
|
198
|
+
# Converts a snake_case parameter name into camelCase for query string parameters
|
199
|
+
# @param attr_name [String]
|
200
|
+
# @return [String] camel-cased parameter name
|
201
|
+
def camel_name_for attr_name
|
202
|
+
parts = attr_name.split "_"
|
203
|
+
first_part = parts[0]
|
204
|
+
other_parts = parts[1..-1]
|
205
|
+
other_parts_pascal = other_parts.map(&:capitalize).join
|
206
|
+
"#{first_part}#{other_parts_pascal}"
|
207
|
+
end
|
164
208
|
end
|
165
209
|
end
|
166
210
|
end
|
@@ -32,6 +32,9 @@ module Gapic
|
|
32
32
|
@api = api
|
33
33
|
end
|
34
34
|
|
35
|
+
##
|
36
|
+
# @return [Enumerable<Gapic::Presenters::PackagePresenter>]
|
37
|
+
#
|
35
38
|
def packages
|
36
39
|
@packages ||= begin
|
37
40
|
packages = @api.generate_files.map(&:package).uniq.sort
|
@@ -124,7 +127,11 @@ module Gapic
|
|
124
127
|
end
|
125
128
|
|
126
129
|
def env_prefix
|
127
|
-
|
130
|
+
prefix = gem_config(:env_prefix) || begin
|
131
|
+
segs = name.split("-").reverse
|
132
|
+
segs.find { |seg| seg !~ /^v\d/ } || segs.first || "UNKNOWN"
|
133
|
+
end
|
134
|
+
prefix.upcase
|
128
135
|
end
|
129
136
|
|
130
137
|
def iam_dependency?
|
@@ -153,18 +160,26 @@ module Gapic
|
|
153
160
|
gem_config :issue_tracker_url
|
154
161
|
end
|
155
162
|
|
163
|
+
##
|
164
|
+
# @return [Boolean]
|
165
|
+
#
|
156
166
|
def free_tier?
|
157
|
-
|
158
|
-
gem_config(:free_tier) == "true"
|
167
|
+
gem_config(:free_tier) || false
|
159
168
|
end
|
160
169
|
|
170
|
+
##
|
171
|
+
# @return [Boolean]
|
172
|
+
#
|
161
173
|
def yard_strict?
|
162
174
|
# Default to true unless the config is explicitly set to "false"
|
163
|
-
gem_config(:yard_strict)
|
175
|
+
gem_config(:yard_strict).nil? || gem_config(:yard_strict)
|
164
176
|
end
|
165
177
|
|
178
|
+
##
|
179
|
+
# @return [Boolean]
|
180
|
+
#
|
166
181
|
def generic_endpoint?
|
167
|
-
gem_config(:generic_endpoint)
|
182
|
+
gem_config(:generic_endpoint) || false
|
168
183
|
end
|
169
184
|
|
170
185
|
def entrypoint_require
|
@@ -180,11 +195,13 @@ module Gapic
|
|
180
195
|
end
|
181
196
|
|
182
197
|
def dependencies
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
198
|
+
@dependencies ||= begin
|
199
|
+
deps = { "gapic-common" => [">= 0.5", "< 2.a"] }
|
200
|
+
deps["grpc-google-iam-v1"] = [">= 0.6.10", "< 2.a"] if iam_dependency?
|
201
|
+
extra_deps = gem_config_dependencies
|
202
|
+
deps.merge! extra_deps if extra_deps
|
203
|
+
deps
|
204
|
+
end
|
188
205
|
end
|
189
206
|
|
190
207
|
def dependency_list
|
@@ -222,6 +239,26 @@ module Gapic
|
|
222
239
|
@api.configuration[:gem][key]
|
223
240
|
end
|
224
241
|
|
242
|
+
##
|
243
|
+
# There is a special case (from PoV of generator parameters)
|
244
|
+
# in gem dependencies where a dependency needs to be an array of strings
|
245
|
+
# e.g. ">= 1.6", "< 2.a"
|
246
|
+
# Rather than creating a special generator param case for this I will special-case it here.
|
247
|
+
# '|' is the separator.
|
248
|
+
# The above would be represented as ">= 1.6|< 2.a"
|
249
|
+
#
|
250
|
+
# @return [Hash<String, String>, Hash{String=>Array<String>}, nil]
|
251
|
+
def gem_config_dependencies
|
252
|
+
return unless gem_config :extra_dependencies
|
253
|
+
gem_config(:extra_dependencies).map do |dep_name, dep_versions|
|
254
|
+
if dep_versions.include? "|"
|
255
|
+
[dep_name, dep_versions.split("|")]
|
256
|
+
else
|
257
|
+
[dep_name, dep_versions]
|
258
|
+
end
|
259
|
+
end.to_h
|
260
|
+
end
|
261
|
+
|
225
262
|
def blacklist_protos
|
226
263
|
blacklist = gem_config :blacklist
|
227
264
|
|
@@ -15,7 +15,6 @@
|
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
17
|
require "active_support/inflector"
|
18
|
-
require "gapic/uri_template"
|
19
18
|
require "gapic/ruby_info"
|
20
19
|
require "gapic/helpers/namespace_helper"
|
21
20
|
|
@@ -27,16 +26,34 @@ module Gapic
|
|
27
26
|
class MethodPresenter
|
28
27
|
include Gapic::Helpers::NamespaceHelper
|
29
28
|
|
29
|
+
# @return [Gapic::Schema::Method]
|
30
|
+
attr_accessor :method
|
31
|
+
|
32
|
+
# @return [Gapic::Presenters::MethodRestPresenter]
|
33
|
+
attr_accessor :rest
|
34
|
+
|
35
|
+
##
|
36
|
+
# @param service_presenter [Gapic::Presenters::ServicePresenter]
|
37
|
+
# @param api [Gapic::Schema::Api]
|
38
|
+
# @param method [Gapic::Schema::Method]
|
30
39
|
def initialize service_presenter, api, method
|
31
40
|
@service_presenter = service_presenter
|
32
41
|
@api = api
|
33
42
|
@method = method
|
43
|
+
@rest = MethodRestPresenter.new self
|
34
44
|
end
|
35
45
|
|
46
|
+
##
|
47
|
+
# @return [Gapic::Presenters::ServicePresenter]
|
48
|
+
#
|
36
49
|
def service
|
37
50
|
@service_presenter
|
38
51
|
end
|
39
52
|
|
53
|
+
def snippet
|
54
|
+
SnippetPresenter.new self, @api
|
55
|
+
end
|
56
|
+
|
40
57
|
def name
|
41
58
|
@name ||= begin
|
42
59
|
candidate = ActiveSupport::Inflector.underscore @method.name
|
@@ -195,15 +212,17 @@ module Gapic
|
|
195
212
|
end
|
196
213
|
|
197
214
|
##
|
198
|
-
#
|
199
215
|
# @return [Array<String>] The segment key names.
|
200
216
|
#
|
201
217
|
def routing_params
|
202
|
-
|
218
|
+
rest.routing_params
|
203
219
|
end
|
204
220
|
|
221
|
+
##
|
222
|
+
# @return [Boolean] Whether any routing params are present
|
223
|
+
#
|
205
224
|
def routing_params?
|
206
|
-
routing_params
|
225
|
+
rest.routing_params?
|
207
226
|
end
|
208
227
|
|
209
228
|
def grpc_service_config
|
@@ -217,6 +236,19 @@ module Gapic
|
|
217
236
|
@method.name
|
218
237
|
end
|
219
238
|
|
239
|
+
##
|
240
|
+
# Returns a hash with a drift_manifest of this rpc method
|
241
|
+
# describing correspondence between the proto description
|
242
|
+
# of the rpc with the generated code for the method.
|
243
|
+
# For ruby currently [03/2021] only one method is generated per RPC,
|
244
|
+
# so the correspondence is very basic.
|
245
|
+
# See https://github.com/googleapis/googleapis/blob/master/gapic/metadata/gapic_metadata.proto
|
246
|
+
#
|
247
|
+
# @return [Hash]
|
248
|
+
def drift_manifest
|
249
|
+
{ methods: [name] }
|
250
|
+
end
|
251
|
+
|
220
252
|
protected
|
221
253
|
|
222
254
|
def message_ruby_type message
|
@@ -266,18 +298,6 @@ module Gapic
|
|
266
298
|
end
|
267
299
|
end
|
268
300
|
|
269
|
-
def method_path
|
270
|
-
return "" if @method.http.nil?
|
271
|
-
|
272
|
-
method = [
|
273
|
-
@method.http.get, @method.http.post, @method.http.put,
|
274
|
-
@method.http.patch, @method.http.delete
|
275
|
-
].find { |x| !x.empty? }
|
276
|
-
return method unless method.nil?
|
277
|
-
|
278
|
-
return @method.http.custom.path unless @method.http.custom.nil?
|
279
|
-
end
|
280
|
-
|
281
301
|
def paged_request? request
|
282
302
|
page_token = request.fields.find do |f|
|
283
303
|
f.name == "page_token" && f.type == Google::Protobuf::FieldDescriptorProto::Type::TYPE_STRING
|
@@ -0,0 +1,194 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2021 Google LLC
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# https://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
require "gapic/uri_template"
|
18
|
+
|
19
|
+
module Gapic
|
20
|
+
module Presenters
|
21
|
+
##
|
22
|
+
# A presenter for rpc methods (REST submethods)
|
23
|
+
#
|
24
|
+
class MethodRestPresenter
|
25
|
+
def initialize main_method
|
26
|
+
@main_method = main_method
|
27
|
+
@proto_method = main_method.method
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# @return [Boolean] Whether a http verb is present for this method
|
32
|
+
#
|
33
|
+
def verb?
|
34
|
+
!verb.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# @return [Symbol] a http verb for this method
|
39
|
+
#
|
40
|
+
def verb
|
41
|
+
return nil if @proto_method.http.nil?
|
42
|
+
|
43
|
+
method = {
|
44
|
+
get: @proto_method.http.get,
|
45
|
+
post: @proto_method.http.post,
|
46
|
+
put: @proto_method.http.put,
|
47
|
+
patch: @proto_method.http.patch,
|
48
|
+
delete: @proto_method.http.delete
|
49
|
+
}.find { |_, value| !value.empty? }
|
50
|
+
|
51
|
+
method[0] unless method.nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# @return [Boolean] Whether a method path is present and non-empty
|
56
|
+
#
|
57
|
+
def path?
|
58
|
+
!path.empty?
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# @return [String] A method path or an empty string if not present
|
63
|
+
#
|
64
|
+
def path
|
65
|
+
return "" if @proto_method.http.nil?
|
66
|
+
|
67
|
+
verb_path = [
|
68
|
+
@proto_method.http.get, @proto_method.http.post, @proto_method.http.put,
|
69
|
+
@proto_method.http.patch, @proto_method.http.delete
|
70
|
+
].find { |x| !x.empty? }
|
71
|
+
|
72
|
+
verb_path || @proto_method.http.custom&.path || ""
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# @return [Boolean] Whether any routing params are present
|
77
|
+
#
|
78
|
+
def routing_params?
|
79
|
+
routing_params.any?
|
80
|
+
end
|
81
|
+
|
82
|
+
##
|
83
|
+
# @return [Array<String>] The segment key names.
|
84
|
+
#
|
85
|
+
def routing_params
|
86
|
+
Gapic::UriTemplate.parse_arguments path
|
87
|
+
end
|
88
|
+
|
89
|
+
##
|
90
|
+
# Performs a limited version of grpc transcoding to create a string that will interpolate
|
91
|
+
# the values from the request object to create a request URI at runtime.
|
92
|
+
# Currently only supports "value" into "request_object.value"
|
93
|
+
# @param [String] request_obj_name the name of the request object for the interpolation
|
94
|
+
# defaults to "request_pb"
|
95
|
+
# @return [String] A string to interpolate values from the request object into URI
|
96
|
+
#
|
97
|
+
def uri_interpolated request_obj_name = "request_pb"
|
98
|
+
return path unless routing_params?
|
99
|
+
|
100
|
+
routing_params.reduce path do |uri, param|
|
101
|
+
param_esc = Regexp.escape param
|
102
|
+
uri.gsub(/{#{param_esc}[^}]*}/, "\#{#{request_obj_name}.#{param}}")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
##
|
107
|
+
# @return [Boolean] Whether method has body specified in proto
|
108
|
+
#
|
109
|
+
def body?
|
110
|
+
return false if @proto_method.http.nil?
|
111
|
+
|
112
|
+
!@proto_method.http.body.empty?
|
113
|
+
end
|
114
|
+
|
115
|
+
##
|
116
|
+
# Name of the variable to use for storing the body result of the transcoding call
|
117
|
+
# Normally "body" but use "_body" for discarding the result for
|
118
|
+
# the calls that do not send body
|
119
|
+
# @return [String]
|
120
|
+
def body_var_name
|
121
|
+
body? ? "body" : "_body"
|
122
|
+
end
|
123
|
+
|
124
|
+
##
|
125
|
+
# @return [String] A body specified for the given method in proto or an empty string if not specified
|
126
|
+
#
|
127
|
+
def body
|
128
|
+
@proto_method.http&.body || ""
|
129
|
+
end
|
130
|
+
|
131
|
+
##
|
132
|
+
# @return [Boolean] True if body contains full request object (`*` in the annotation), false otherwise
|
133
|
+
#
|
134
|
+
def body_is_request_object?
|
135
|
+
body == "*"
|
136
|
+
end
|
137
|
+
|
138
|
+
##
|
139
|
+
# Performs a limited version of grpc transcoding to create a string that will interpolate
|
140
|
+
# the values from the request object to create a request body at runtime.
|
141
|
+
# Currently only supports either "*" for "the whole request object" or
|
142
|
+
# "value" for "request_object.value"
|
143
|
+
#
|
144
|
+
# @param [String] request_obj_name the name of the request object for the interpolation
|
145
|
+
# defaults to "request_pb"
|
146
|
+
#
|
147
|
+
# @return [String] A string to interpolate values from the request object into body
|
148
|
+
#
|
149
|
+
def body_interpolated request_obj_name = "request_pb"
|
150
|
+
return "\"\"" unless body?
|
151
|
+
|
152
|
+
return "#{request_obj_name}.to_json" if body_is_request_object?
|
153
|
+
|
154
|
+
"#{request_obj_name}.#{body}.to_json"
|
155
|
+
end
|
156
|
+
|
157
|
+
##
|
158
|
+
# @return [Boolean] whether any query string parameters are present
|
159
|
+
#
|
160
|
+
def query_string_params?
|
161
|
+
query_string_params.any?
|
162
|
+
end
|
163
|
+
|
164
|
+
# @return [Array<String>]
|
165
|
+
def query_string_params
|
166
|
+
return [] if body_is_request_object?
|
167
|
+
|
168
|
+
routing_params_set = routing_params.to_set
|
169
|
+
@main_method.arguments
|
170
|
+
.reject { |arg| routing_params_set.include? arg.name }
|
171
|
+
.reject { |arg| body == arg.name }
|
172
|
+
.reject(&:message?)
|
173
|
+
.reject { |arg| arg.default_value_for_type.nil? }
|
174
|
+
end
|
175
|
+
|
176
|
+
##
|
177
|
+
# Name of the variable to use for storing the query_string_params result of the transcoding call
|
178
|
+
# Normally "query_string_params" but use "_query_string_params" for discarding the result for
|
179
|
+
# the calls that do not sent query_string_params
|
180
|
+
# @return [String]
|
181
|
+
def query_string_params_var_name
|
182
|
+
query_string_params? ? "query_string_params" : "_query_string_params"
|
183
|
+
end
|
184
|
+
|
185
|
+
##
|
186
|
+
# Name for the GRPC transcoding helper method
|
187
|
+
#
|
188
|
+
# @return [String]
|
189
|
+
def transcoding_helper_name
|
190
|
+
"transcode_#{@main_method.name}"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|