grpc-rest 0.1.24 → 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 +6 -1
- 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 +40 -38
- 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 +71 -25
- data/spec/gruf_spec.rb +4 -3
- data/spec/spec_helper.rb +8 -6
- data/spec/test_service_pb.rb +1 -1
- 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
- data/{protoc-gen-rails → spec}/testdata/test_service.proto +1 -0
- metadata +90 -26
- 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/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
|
|
@@ -102,11 +101,16 @@ module GrpcRest
|
|
102
101
|
next if val.nil?
|
103
102
|
|
104
103
|
if descriptor.label == :repeated
|
105
|
-
|
104
|
+
# leave map entries as key => value
|
105
|
+
unless descriptor.subtype&.options&.to_h&.dig(:map_entry)
|
106
|
+
params[field] = val.map { |v| map_proto_type(descriptor, v) }
|
107
|
+
end
|
106
108
|
else
|
107
109
|
params[field] = map_proto_type(descriptor, val)
|
108
110
|
end
|
109
111
|
end
|
112
|
+
|
113
|
+
|
110
114
|
params
|
111
115
|
end
|
112
116
|
|
@@ -132,10 +136,10 @@ module GrpcRest
|
|
132
136
|
end
|
133
137
|
assign_value(request, entry[:name], value_to_use)
|
134
138
|
end
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
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)
|
139
143
|
end
|
140
144
|
|
141
145
|
# Ported from https://github.com/grpc-ecosystem/grpc-gateway/blob/main/runtime/errors.go#L36
|
@@ -171,25 +175,26 @@ module GrpcRest
|
|
171
175
|
end
|
172
176
|
|
173
177
|
def error_msg(error)
|
178
|
+
Rails.logger.error("#{error.message}, backtrace: #{error.backtrace.join("\n")}")
|
174
179
|
if error.respond_to?(:code)
|
175
|
-
|
180
|
+
{
|
176
181
|
code: error.code,
|
177
182
|
message: error.message,
|
178
183
|
details: [
|
179
|
-
|
180
|
-
|
181
|
-
|
184
|
+
{
|
185
|
+
backtrace: error.backtrace
|
186
|
+
}
|
182
187
|
]
|
183
|
-
|
188
|
+
}
|
184
189
|
else
|
185
190
|
{
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
191
|
+
code: 3,
|
192
|
+
message: "InvalidArgument: #{error.message}",
|
193
|
+
details: [
|
194
|
+
{
|
195
|
+
backtrace: error.backtrace
|
196
|
+
}
|
197
|
+
]
|
193
198
|
}
|
194
199
|
end
|
195
200
|
end
|
@@ -228,14 +233,12 @@ module GrpcRest
|
|
228
233
|
klass = ::Gruf::Controllers::Base.subclasses.find do |k|
|
229
234
|
k.bound_service == service_obj
|
230
235
|
end
|
231
|
-
if klass
|
232
|
-
return send_gruf_request(klass, service_obj, method, request)
|
233
|
-
end
|
236
|
+
return send_gruf_request(klass, service_obj, method, request) if klass
|
234
237
|
end
|
235
238
|
send_grpc_request(service, method, request)
|
236
239
|
end
|
237
240
|
|
238
|
-
def send_request(service, method, request, options={})
|
241
|
+
def send_request(service, method, request, options = {})
|
239
242
|
response = get_response(service, method, request)
|
240
243
|
if options[:emit_defaults]
|
241
244
|
response.to_json(emit_defaults: true)
|
@@ -244,5 +247,4 @@ module GrpcRest
|
|
244
247
|
end
|
245
248
|
end
|
246
249
|
end
|
247
|
-
|
248
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
|