grpc-rest 0.1.25 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/CI.yml +2 -41
- data/.rubocop.yml +3 -0
- data/CHANGELOG +2 -0
- data/Gemfile +3 -1
- data/Gemfile.lock +21 -10
- data/README.md +7 -8
- data/bin/protoc-gen-rails +6 -0
- data/grpc-rest.gemspec +4 -1
- data/lib/generator/controller.rb.erb +27 -0
- data/lib/generator/grpc.rb.erb +9 -0
- data/lib/generator/method.rb +96 -0
- data/lib/generator/output.rb +28 -0
- data/lib/generator/plugin_pb.rb +25 -0
- data/lib/generator/service.rb +36 -0
- data/lib/generator.rb +88 -0
- data/lib/grpc_rest/version.rb +3 -1
- data/lib/grpc_rest.rb +35 -37
- data/{protoc-gen-rails/testdata/base/app/controllers/my_service_controller.rb → spec/__snapshots__/service.snap} +33 -27
- data/spec/base_interceptor_spec.rb +6 -3
- data/spec/{protoc-gen-openapiv2 → gen/protoc-gen-openapiv2}/options/annotations_pb.rb +5 -4
- data/spec/{protoc-gen-openapiv2 → gen/protoc-gen-openapiv2}/options/openapiv2_pb.rb +30 -29
- data/spec/gen/test_pb.rb +15 -0
- data/spec/gen/test_service_pb.rb +23 -0
- data/spec/gen/test_service_services_pb.rb +26 -0
- data/spec/generator_spec.rb +49 -0
- data/spec/grpc_rest_spec.rb +65 -25
- data/spec/gruf_spec.rb +4 -3
- data/spec/spec_helper.rb +8 -6
- data/spec/test_service_services_pb.rb +2 -1
- data/spec/testdata/base/app/controllers/my_service_controller.rb +65 -0
- data/spec/testdata/no_service/.keep +0 -0
- metadata +89 -25
- data/protoc-gen-rails/.goreleaser.yml +0 -27
- data/protoc-gen-rails/LICENSE +0 -21
- data/protoc-gen-rails/go.mod +0 -25
- data/protoc-gen-rails/go.sum +0 -49
- data/protoc-gen-rails/internal/output.go +0 -165
- data/protoc-gen-rails/internal/parse.go +0 -101
- data/protoc-gen-rails/internal/utils.go +0 -57
- data/protoc-gen-rails/main.go +0 -104
- data/protoc-gen-rails/main_test.go +0 -158
- /data/{protoc-gen-rails/testdata/no_service/.keep → spec/__snapshots__/no_service.snap} +0 -0
- /data/{protoc-gen-rails → spec}/google-deps/google/api/annotations.proto +0 -0
- /data/{protoc-gen-rails → spec}/google-deps/google/api/http.proto +0 -0
- /data/{protoc-gen-rails → spec}/google-deps/protoc-gen-openapiv2/options/annotations.proto +0 -0
- /data/{protoc-gen-rails → spec}/google-deps/protoc-gen-openapiv2/options/openapiv2.proto +0 -0
- /data/{protoc-gen-rails → spec}/testdata/base/config/routes/grpc.rb +0 -0
- /data/{protoc-gen-rails → spec}/testdata/test.proto +0 -0
- /data/{protoc-gen-rails → spec}/testdata/test_service.proto +0 -0
data/lib/grpc_rest.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'google/protobuf/well_known_types'
|
2
4
|
require 'grpc'
|
3
5
|
require 'grpc/core/status_codes'
|
4
6
|
|
5
7
|
module GrpcRest
|
6
8
|
class << self
|
7
|
-
|
8
9
|
def underscore(s)
|
9
10
|
GRPC::GenericService.underscore(s)
|
10
11
|
end
|
@@ -39,7 +40,7 @@ module GrpcRest
|
|
39
40
|
|
40
41
|
# https://stackoverflow.com/a/2158473/5199431
|
41
42
|
def longest_common_substring(arr)
|
42
|
-
return
|
43
|
+
return '' if arr.empty?
|
43
44
|
|
44
45
|
result = 0
|
45
46
|
first_val = arr[0]
|
@@ -48,6 +49,7 @@ module GrpcRest
|
|
48
49
|
character = first_val[k]
|
49
50
|
arr.each { |str| all_matched &= (character == str[k]) }
|
50
51
|
break unless all_matched
|
52
|
+
|
51
53
|
result += 1
|
52
54
|
end
|
53
55
|
first_val.slice(0, result)
|
@@ -64,14 +66,12 @@ module GrpcRest
|
|
64
66
|
end
|
65
67
|
|
66
68
|
def map_proto_type(descriptor, val)
|
67
|
-
if descriptor.subtype.is_a?(Google::Protobuf::EnumDescriptor)
|
68
|
-
return handle_enum_values(descriptor, val)
|
69
|
-
end
|
69
|
+
return handle_enum_values(descriptor, val) if descriptor.subtype.is_a?(Google::Protobuf::EnumDescriptor)
|
70
70
|
|
71
71
|
case descriptor.type
|
72
|
-
when
|
72
|
+
when :int32, :int64, :uint32, :uint64, :sint32, :sint64, :fixed32, :fixed64, :sfixed32, :sfixed64
|
73
73
|
return val.to_i
|
74
|
-
when
|
74
|
+
when :float, :double
|
75
75
|
return val.to_f
|
76
76
|
when :bool
|
77
77
|
return !!val
|
@@ -79,19 +79,18 @@ module GrpcRest
|
|
79
79
|
|
80
80
|
case descriptor.subtype&.name
|
81
81
|
when 'google.protobuf.Struct'
|
82
|
-
|
82
|
+
Google::Protobuf::Struct.from_hash(val)
|
83
83
|
when 'google.protobuf.Timestamp'
|
84
|
-
if val.is_a?(Numeric)
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
84
|
+
return Google::Protobuf::Timestamp.from_time(Time.at(val)) if val.is_a?(Numeric)
|
85
|
+
|
86
|
+
Google::Protobuf::Timestamp.from_time(Time.new(val))
|
87
|
+
|
89
88
|
when 'google.protobuf.Value'
|
90
|
-
|
89
|
+
Google::Protobuf::Value.from_ruby(val)
|
91
90
|
when 'google.protobuf.ListValue'
|
92
|
-
|
91
|
+
Google::Protobuf::ListValue.from_a(val)
|
93
92
|
else
|
94
|
-
|
93
|
+
map_proto_record(descriptor.subtype, val)
|
95
94
|
end
|
96
95
|
end
|
97
96
|
|
@@ -110,6 +109,8 @@ module GrpcRest
|
|
110
109
|
params[field] = map_proto_type(descriptor, val)
|
111
110
|
end
|
112
111
|
end
|
112
|
+
|
113
|
+
|
113
114
|
params
|
114
115
|
end
|
115
116
|
|
@@ -135,10 +136,10 @@ module GrpcRest
|
|
135
136
|
end
|
136
137
|
assign_value(request, entry[:name], value_to_use)
|
137
138
|
end
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
139
|
+
return unless body_string.present? && body_string != '*'
|
140
|
+
|
141
|
+
# we need to "splat" the body parameters into the given sub-record rather than into the top-level.
|
142
|
+
sub_field(request, body_string, parameters)
|
142
143
|
end
|
143
144
|
|
144
145
|
# Ported from https://github.com/grpc-ecosystem/grpc-gateway/blob/main/runtime/errors.go#L36
|
@@ -176,24 +177,24 @@ module GrpcRest
|
|
176
177
|
def error_msg(error)
|
177
178
|
Rails.logger.error("#{error.message}, backtrace: #{error.backtrace.join("\n")}")
|
178
179
|
if error.respond_to?(:code)
|
179
|
-
|
180
|
+
{
|
180
181
|
code: error.code,
|
181
182
|
message: error.message,
|
182
183
|
details: [
|
183
|
-
|
184
|
-
|
185
|
-
|
184
|
+
{
|
185
|
+
backtrace: error.backtrace
|
186
|
+
}
|
186
187
|
]
|
187
|
-
|
188
|
+
}
|
188
189
|
else
|
189
190
|
{
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
191
|
+
code: 3,
|
192
|
+
message: "InvalidArgument: #{error.message}",
|
193
|
+
details: [
|
194
|
+
{
|
195
|
+
backtrace: error.backtrace
|
196
|
+
}
|
197
|
+
]
|
197
198
|
}
|
198
199
|
end
|
199
200
|
end
|
@@ -232,14 +233,12 @@ module GrpcRest
|
|
232
233
|
klass = ::Gruf::Controllers::Base.subclasses.find do |k|
|
233
234
|
k.bound_service == service_obj
|
234
235
|
end
|
235
|
-
if klass
|
236
|
-
return send_gruf_request(klass, service_obj, method, request)
|
237
|
-
end
|
236
|
+
return send_gruf_request(klass, service_obj, method, request) if klass
|
238
237
|
end
|
239
238
|
send_grpc_request(service, method, request)
|
240
239
|
end
|
241
240
|
|
242
|
-
def send_request(service, method, request, options={})
|
241
|
+
def send_request(service, method, request, options = {})
|
243
242
|
response = get_response(service, method, request)
|
244
243
|
if options[:emit_defaults]
|
245
244
|
response.to_json(emit_defaults: true)
|
@@ -248,5 +247,4 @@ module GrpcRest
|
|
248
247
|
end
|
249
248
|
end
|
250
249
|
end
|
251
|
-
|
252
250
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
spec/app/app/controllers/my_service_controller.rb:
|
2
2
|
####### THIS FILE IS AUTOMATICALLY GENERATED BY protoc-gen-rails. DO NOT MODIFY. #######
|
3
3
|
|
4
4
|
require 'grpc_rest'
|
@@ -14,54 +14,60 @@ class MyServiceController < ActionController::Base
|
|
14
14
|
rescue_from ActionDispatch::Http::Parameters::ParseError, Google::Protobuf::TypeError do |e|
|
15
15
|
render json: GrpcRest.error_msg(e), status: :bad_request
|
16
16
|
end
|
17
|
+
METHOD_PARAM_MAP = {"test"=>[{:name=>"foobar", :val=>"=blah/*", :split_name=>["foobar"]}],
|
18
|
+
"test2"=>[],
|
19
|
+
"test3"=>
|
20
|
+
[{:name=>"sub_record.sub_id",
|
21
|
+
:val=>"",
|
22
|
+
:split_name=>["sub_record", "sub_id"]}],
|
23
|
+
"test4"=>[]}
|
24
|
+
.freeze
|
17
25
|
|
18
|
-
METHOD_PARAM_MAP = {
|
19
|
-
|
20
|
-
"test" => [
|
21
|
-
{name: "foobar", val: "blah/*", split_name:["foobar"]},
|
22
|
-
],
|
23
|
-
|
24
|
-
"test_2" => [
|
25
|
-
],
|
26
|
-
|
27
|
-
"test_3" => [
|
28
|
-
{name: "sub_record.sub_id", val: nil, split_name:["sub_record","sub_id"]},
|
29
|
-
],
|
30
|
-
|
31
|
-
"test_4" => [
|
32
|
-
],
|
33
|
-
}.freeze
|
34
26
|
|
35
27
|
def test
|
36
28
|
fields = Testdata::TestRequest.descriptor.to_a.map(&:name)
|
37
29
|
parameters = request.parameters.to_h.deep_transform_keys(&:underscore)
|
38
30
|
grpc_request = GrpcRest.init_request(Testdata::TestRequest, parameters.slice(*fields))
|
39
31
|
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test"], "", request.parameters)
|
40
|
-
render json: GrpcRest.send_request("Testdata::MyService", "test", grpc_request, {emit_defaults
|
32
|
+
render json: GrpcRest.send_request("Testdata::MyService", "test", grpc_request, {:emit_defaults=>true})
|
41
33
|
end
|
42
34
|
|
43
|
-
def
|
35
|
+
def test2
|
44
36
|
fields = Testdata::TestRequest.descriptor.to_a.map(&:name)
|
45
37
|
parameters = request.parameters.to_h.deep_transform_keys(&:underscore)
|
46
38
|
grpc_request = GrpcRest.init_request(Testdata::TestRequest, parameters.slice(*fields))
|
47
|
-
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["
|
48
|
-
render json: GrpcRest.send_request("Testdata::MyService", "
|
39
|
+
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test2"], "second_record", request.parameters)
|
40
|
+
render json: GrpcRest.send_request("Testdata::MyService", "test2", grpc_request, {})
|
49
41
|
end
|
50
42
|
|
51
|
-
def
|
43
|
+
def test3
|
52
44
|
fields = Testdata::TestRequest.descriptor.to_a.map(&:name)
|
53
45
|
parameters = request.parameters.to_h.deep_transform_keys(&:underscore)
|
54
46
|
grpc_request = GrpcRest.init_request(Testdata::TestRequest, parameters.slice(*fields))
|
55
|
-
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["
|
56
|
-
render json: GrpcRest.send_request("Testdata::MyService", "
|
47
|
+
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test3"], "", request.parameters)
|
48
|
+
render json: GrpcRest.send_request("Testdata::MyService", "test3", grpc_request, {})
|
57
49
|
end
|
58
50
|
|
59
|
-
def
|
51
|
+
def test4
|
60
52
|
fields = Testdata::TestRequest.descriptor.to_a.map(&:name)
|
61
53
|
parameters = request.parameters.to_h.deep_transform_keys(&:underscore)
|
62
54
|
grpc_request = GrpcRest.init_request(Testdata::TestRequest, parameters.slice(*fields))
|
63
|
-
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["
|
64
|
-
render json: GrpcRest.send_request("Testdata::MyService", "
|
55
|
+
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test4"], "*", request.parameters)
|
56
|
+
render json: GrpcRest.send_request("Testdata::MyService", "test4", grpc_request, {})
|
65
57
|
end
|
66
58
|
|
67
59
|
end
|
60
|
+
|
61
|
+
|
62
|
+
spec/app/config/routes/grpc.rb:
|
63
|
+
# frozen_string_literal: true
|
64
|
+
|
65
|
+
####### THIS FILE IS AUTOMATICALLY GENERATED BY protoc-gen-rails. DO NOT MODIFY. #######
|
66
|
+
|
67
|
+
|
68
|
+
get '/test/*foobar' => 'my_service#test'
|
69
|
+
post '/test2' => 'my_service#test2'
|
70
|
+
post '/test3/*sub_id' => 'my_service#test3'
|
71
|
+
post '/test4' => 'my_service#test4'
|
72
|
+
|
73
|
+
|
@@ -5,7 +5,7 @@ require 'src/proto/grpc/testing/test_services_pb'
|
|
5
5
|
|
6
6
|
RSpec.describe GrpcRest::BaseInterceptor, type: :class do
|
7
7
|
let(:rpc_service) { Grpc::Testing::TestService::Service.new }
|
8
|
-
let(:rpc_desc) { Grpc::Testing::TestService::Service.rpc_descs.values.first}
|
8
|
+
let(:rpc_desc) { Grpc::Testing::TestService::Service.rpc_descs.values.first }
|
9
9
|
let(:message) { Grpc::Testing::SimpleRequest.new }
|
10
10
|
|
11
11
|
describe '#fail!' do
|
@@ -18,10 +18,13 @@ RSpec.describe GrpcRest::BaseInterceptor, type: :class do
|
|
18
18
|
service: rpc_service,
|
19
19
|
rpc_desc: rpc_desc,
|
20
20
|
active_call: nil,
|
21
|
-
message: message
|
21
|
+
message: message
|
22
|
+
)
|
22
23
|
interceptor = GrpcRest::BaseInterceptor.new(request, Gruf::Error.new)
|
23
24
|
|
24
|
-
expect
|
25
|
+
expect do
|
26
|
+
interceptor.fail!(error_code, error_code, error_message)
|
27
|
+
end.to raise_error(GRPC::InvalidArgument) do |error|
|
25
28
|
expect(error.message).to match(error_message)
|
26
29
|
expect(error.code).to eq(GRPC::Core::StatusCodes::INVALID_ARGUMENT)
|
27
30
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
4
|
# source: protoc-gen-openapiv2/options/annotations.proto
|
4
5
|
|
@@ -15,7 +16,7 @@ pool = Google::Protobuf::DescriptorPool.generated_pool
|
|
15
16
|
|
16
17
|
begin
|
17
18
|
pool.add_serialized_file(descriptor_data)
|
18
|
-
rescue TypeError
|
19
|
+
rescue TypeError
|
19
20
|
# Compatibility code: will be removed in the next major version.
|
20
21
|
require 'google/protobuf/descriptor_pb'
|
21
22
|
parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
|
@@ -24,7 +25,7 @@ rescue TypeError => e
|
|
24
25
|
file = pool.add_serialized_file(serialized)
|
25
26
|
warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
|
26
27
|
imports = [
|
27
|
-
[
|
28
|
+
['grpc.gateway.protoc_gen_openapiv2.options.Swagger', 'protoc-gen-openapiv2/options/openapiv2.proto']
|
28
29
|
]
|
29
30
|
imports.each do |type_name, expected_filename|
|
30
31
|
import_file = pool.lookup(type_name).file_descriptor
|
@@ -32,8 +33,8 @@ rescue TypeError => e
|
|
32
33
|
warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
|
33
34
|
end
|
34
35
|
end
|
35
|
-
warn
|
36
|
-
warn
|
36
|
+
warn 'Each proto file must use a consistent fully-qualified name.'
|
37
|
+
warn 'This will become an error in the next major version.'
|
37
38
|
end
|
38
39
|
|
39
40
|
module Grpc
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
3
4
|
# source: protoc-gen-openapiv2/options/openapiv2.proto
|
4
5
|
|
@@ -14,7 +15,7 @@ pool = Google::Protobuf::DescriptorPool.generated_pool
|
|
14
15
|
|
15
16
|
begin
|
16
17
|
pool.add_serialized_file(descriptor_data)
|
17
|
-
rescue TypeError
|
18
|
+
rescue TypeError
|
18
19
|
# Compatibility code: will be removed in the next major version.
|
19
20
|
require 'google/protobuf/descriptor_pb'
|
20
21
|
parsed = Google::Protobuf::FileDescriptorProto.decode(descriptor_data)
|
@@ -23,7 +24,7 @@ rescue TypeError => e
|
|
23
24
|
file = pool.add_serialized_file(serialized)
|
24
25
|
warn "Warning: Protobuf detected an import path issue while loading generated file #{__FILE__}"
|
25
26
|
imports = [
|
26
|
-
[
|
27
|
+
['google.protobuf.Value', 'google/protobuf/struct.proto']
|
27
28
|
]
|
28
29
|
imports.each do |type_name, expected_filename|
|
29
30
|
import_file = pool.lookup(type_name).file_descriptor
|
@@ -31,39 +32,39 @@ rescue TypeError => e
|
|
31
32
|
warn "- #{file.name} imports #{expected_filename}, but that import was loaded as #{import_file.name}"
|
32
33
|
end
|
33
34
|
end
|
34
|
-
warn
|
35
|
-
warn
|
35
|
+
warn 'Each proto file must use a consistent fully-qualified name.'
|
36
|
+
warn 'This will become an error in the next major version.'
|
36
37
|
end
|
37
38
|
|
38
39
|
module Grpc
|
39
40
|
module Gateway
|
40
41
|
module ProtocGenOpenapiv2
|
41
42
|
module Options
|
42
|
-
Swagger = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
43
|
-
Operation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
44
|
-
Parameters = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
45
|
-
HeaderParameter = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
46
|
-
HeaderParameter::Type = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
47
|
-
Header = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
48
|
-
Response = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
49
|
-
Info = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
50
|
-
Contact = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
51
|
-
License = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
52
|
-
ExternalDocumentation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
53
|
-
Schema = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
54
|
-
JSONSchema = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
55
|
-
JSONSchema::FieldConfiguration = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
56
|
-
JSONSchema::JSONSchemaSimpleTypes = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
57
|
-
Tag = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
58
|
-
SecurityDefinitions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
59
|
-
SecurityScheme = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
60
|
-
SecurityScheme::Type = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
61
|
-
SecurityScheme::In = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
62
|
-
SecurityScheme::Flow = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
63
|
-
SecurityRequirement = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
64
|
-
SecurityRequirement::SecurityRequirementValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
65
|
-
Scopes = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
66
|
-
Scheme = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(
|
43
|
+
Swagger = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Swagger').msgclass
|
44
|
+
Operation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Operation').msgclass
|
45
|
+
Parameters = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Parameters').msgclass
|
46
|
+
HeaderParameter = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.HeaderParameter').msgclass
|
47
|
+
HeaderParameter::Type = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.HeaderParameter.Type').enummodule
|
48
|
+
Header = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Header').msgclass
|
49
|
+
Response = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Response').msgclass
|
50
|
+
Info = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Info').msgclass
|
51
|
+
Contact = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Contact').msgclass
|
52
|
+
License = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.License').msgclass
|
53
|
+
ExternalDocumentation = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.ExternalDocumentation').msgclass
|
54
|
+
Schema = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Schema').msgclass
|
55
|
+
JSONSchema = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.JSONSchema').msgclass
|
56
|
+
JSONSchema::FieldConfiguration = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.JSONSchema.FieldConfiguration').msgclass
|
57
|
+
JSONSchema::JSONSchemaSimpleTypes = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.JSONSchema.JSONSchemaSimpleTypes').enummodule
|
58
|
+
Tag = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Tag').msgclass
|
59
|
+
SecurityDefinitions = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.SecurityDefinitions').msgclass
|
60
|
+
SecurityScheme = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme').msgclass
|
61
|
+
SecurityScheme::Type = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.Type').enummodule
|
62
|
+
SecurityScheme::In = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.In').enummodule
|
63
|
+
SecurityScheme::Flow = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.SecurityScheme.Flow').enummodule
|
64
|
+
SecurityRequirement = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement').msgclass
|
65
|
+
SecurityRequirement::SecurityRequirementValue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.SecurityRequirement.SecurityRequirementValue').msgclass
|
66
|
+
Scopes = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Scopes').msgclass
|
67
|
+
Scheme = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('grpc.gateway.protoc_gen_openapiv2.options.Scheme').enummodule
|
67
68
|
end
|
68
69
|
end
|
69
70
|
end
|
data/spec/gen/test_pb.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
4
|
+
# source: test.proto
|
5
|
+
|
6
|
+
require 'google/protobuf'
|
7
|
+
|
8
|
+
descriptor_data = "\n\ntest.proto\x12\x04test\"\x14\n\x04Test\x12\x0c\n\x04test\x18\x01 \x01(\tb\x06proto3"
|
9
|
+
|
10
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
11
|
+
pool.add_serialized_file(descriptor_data)
|
12
|
+
|
13
|
+
module Test
|
14
|
+
Test = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('test.Test').msgclass
|
15
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
4
|
+
# source: test_service.proto
|
5
|
+
|
6
|
+
require 'google/protobuf'
|
7
|
+
|
8
|
+
require 'google/api/annotations_pb'
|
9
|
+
require 'google/protobuf/struct_pb'
|
10
|
+
require 'google/protobuf/timestamp_pb'
|
11
|
+
require 'protoc-gen-openapiv2/options/annotations_pb'
|
12
|
+
|
13
|
+
descriptor_data = "\n\x12test_service.proto\x12\x08testdata\x1a\x1cgoogle/api/annotations.proto\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a.protoc-gen-openapiv2/options/annotations.proto\"\xd7\x03\n\x0bTestRequest\x12\x0f\n\x07test_id\x18\x01 \x01(\t\x12\x0e\n\x06\x66oobar\x18\x02 \x01(\t\x12\x17\n\x0frepeated_string\x18\x03 \x03(\t\x12\'\n\nsub_record\x18\x04 \x01(\x0b\x32\x13.testdata.SubRecord\x12*\n\rsecond_record\x18\x05 \x01(\x0b\x32\x13.testdata.SubRecord\x12-\n\x0cstruct_field\x18\x06 \x01(\x0b\x32\x17.google.protobuf.Struct\x12\x33\n\x0ftimestamp_field\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nlist_value\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.ListValue\x12*\n\nbare_value\x18\t \x01(\x0b\x32\x16.google.protobuf.Value\x12(\n\x0bsub_records\x18\n \x03(\x0b\x32\x13.testdata.SubRecord\x12\x10\n\x08some_int\x18\x0b \x01(\x05\x12%\n\tsome_enum\x18\x0c \x01(\x0e\x32\x12.testdata.TestEnum\x12\x16\n\x0erepeated_float\x18\r \x03(\x02\"/\n\tSubRecord\x12\x0e\n\x06sub_id\x18\x01 \x01(\t\x12\x12\n\nanother_id\x18\x02 \x01(\t\"L\n\x0cTestResponse\x12\x10\n\x08some_int\x18\x01 \x01(\x05\x12\x15\n\rfull_response\x18\x02 \x01(\t\x12\x13\n\x0bignored_key\x18\x03 \x01(\t*K\n\x08TestEnum\x12\x19\n\x15TEST_ENUM_UNSPECIFIED\x10\x00\x12\x11\n\rTEST_ENUM_FOO\x10\x01\x12\x11\n\rTEST_ENUM_BAR\x10\x02\x32\x83\x03\n\tMyService\x12x\n\x04Test\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"A\x92\x41!j\x1f\n\x19x-grpc-rest-emit-defaults\x12\x02 \x01\x82\xd3\xe4\x93\x02\x17\x12\x15/test/{foobar=blah/*}\x12U\n\x05Test2\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\x1d\x82\xd3\xe4\x93\x02\x17\"\x06/test2:\rsecond_record\x12Z\n\x05Test3\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\"\x82\xd3\xe4\x93\x02\x1c\"\x1a/test3/{sub_record.sub_id}\x12I\n\x05Test4\x12\x15.testdata.TestRequest\x1a\x16.testdata.TestResponse\"\x11\x82\xd3\xe4\x93\x02\x0b\"\x06/test4:\x01*b\x06proto3"
|
14
|
+
|
15
|
+
pool = Google::Protobuf::DescriptorPool.generated_pool
|
16
|
+
pool.add_serialized_file(descriptor_data)
|
17
|
+
|
18
|
+
module Testdata
|
19
|
+
TestRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('testdata.TestRequest').msgclass
|
20
|
+
SubRecord = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('testdata.SubRecord').msgclass
|
21
|
+
TestResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('testdata.TestResponse').msgclass
|
22
|
+
TestEnum = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('testdata.TestEnum').enummodule
|
23
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
4
|
+
# Source: test_service.proto for package 'testdata'
|
5
|
+
|
6
|
+
require 'grpc'
|
7
|
+
require 'test_service_pb'
|
8
|
+
|
9
|
+
module Testdata
|
10
|
+
module MyService
|
11
|
+
class Service
|
12
|
+
include ::GRPC::GenericService
|
13
|
+
|
14
|
+
self.marshal_class_method = :encode
|
15
|
+
self.unmarshal_class_method = :decode
|
16
|
+
self.service_name = 'testdata.MyService'
|
17
|
+
|
18
|
+
rpc :Test, ::Testdata::TestRequest, ::Testdata::TestResponse
|
19
|
+
rpc :Test2, ::Testdata::TestRequest, ::Testdata::TestResponse
|
20
|
+
rpc :Test3, ::Testdata::TestRequest, ::Testdata::TestResponse
|
21
|
+
rpc :Test4, ::Testdata::TestRequest, ::Testdata::TestResponse
|
22
|
+
end
|
23
|
+
|
24
|
+
Stub = Service.rpc_stub_class
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This is used to check the generated files all at once.
|
4
|
+
class MultiFileSerializer
|
5
|
+
def process_string(s)
|
6
|
+
# Ruby 3.4 changes how hashes are printed
|
7
|
+
if Gem::Version.new(RUBY_VERSION) > Gem::Version.new('3.4.0')
|
8
|
+
s.gsub(/{"(.*)" => /, '{"\1"=>')
|
9
|
+
else
|
10
|
+
s
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def dump(value)
|
15
|
+
value.keys.sort.map { |k| "#{k}:\n#{process_string(value[k])}\n" }.join("\n")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# The easiest way to test a protoc plugin is by actually running protoc. Here we are specifying
|
20
|
+
# the binary to use for the rails plugin and passing in the dependency paths and the
|
21
|
+
# place to find the generated Ruby files (which we generated in advance and live inside `spec/gen`.)
|
22
|
+
def protoc(files)
|
23
|
+
`bundle exec protoc \
|
24
|
+
--proto_path=#{__dir__} \
|
25
|
+
--proto_path=#{__dir__}/google-deps \
|
26
|
+
--plugin=protoc-gen-rails=#{__dir__}/../bin/protoc-gen-rails \
|
27
|
+
--rails_out=#{__dir__}/app \
|
28
|
+
--rails_opt=require=#{__dir__}/gen #{files.join(' ')}`
|
29
|
+
end
|
30
|
+
|
31
|
+
RSpec.describe 'protoc-gen-rails' do
|
32
|
+
let(:files) { Dir['spec/app/**/*.rb'].map { |f| [f, File.read(f)] }.to_h }
|
33
|
+
before(:each) do
|
34
|
+
FileUtils.mkdir('spec/app') unless File.exist?('spec/app')
|
35
|
+
end
|
36
|
+
after(:each) do
|
37
|
+
FileUtils.rm_rf('spec/app') if File.exist?('spec/app')
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should generate for a service' do
|
41
|
+
protoc(%w[testdata/test.proto testdata/test_service.proto])
|
42
|
+
expect(files).to match_snapshot('service', snapshot_serializer: MultiFileSerializer)
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should not generate if no services' do
|
46
|
+
protoc(%w[testdata/test.proto])
|
47
|
+
expect(files).to match_snapshot('no_service', snapshot_serializer: MultiFileSerializer)
|
48
|
+
end
|
49
|
+
end
|