grpc-rest 0.3.1 → 0.5.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/release.yml +31 -0
- data/CHANGELOG +10 -0
- data/Gemfile.lock +156 -118
- data/README.md +28 -62
- data/Rakefile +3 -0
- data/lib/generator/controller.rb +51 -0
- data/lib/generator/method.rb +3 -3
- data/lib/generator/service.rb +10 -20
- data/lib/grpc_rest/railtie.rb +19 -0
- data/lib/grpc_rest/version.rb +1 -1
- data/lib/grpc_rest.rb +24 -12
- data/spec/grpc_rest_spec.rb +1 -1
- data/spec/gruf_spec.rb +1 -1
- data/spec/spec_helper.rb +11 -12
- data/spec/test_service_services_pb.rb +1 -2
- metadata +7 -29
- data/lib/generator/controller.rb.erb +0 -27
- data/lib/generator/grpc.rb.erb +0 -9
- data/lib/generator/output.rb +0 -28
- data/lib/generator/plugin_pb.rb +0 -25
- data/spec/__snapshots__/no_service.snap +0 -0
- data/spec/__snapshots__/service.snap +0 -73
- data/spec/gen/test_pb.rb +0 -15
- data/spec/gen/test_service_pb.rb +0 -23
- data/spec/gen/test_service_services_pb.rb +0 -26
- data/spec/generator_spec.rb +0 -49
- data/spec/testdata/base/app/controllers/my_service_controller.rb +0 -58
- data/spec/testdata/base/config/routes/grpc.rb +0 -10
- data/spec/testdata/no_service/.keep +0 -0
data/lib/generator/service.rb
CHANGED
@@ -2,35 +2,25 @@
|
|
2
2
|
|
3
3
|
require_relative 'method'
|
4
4
|
|
5
|
-
module
|
6
|
-
class
|
7
|
-
attr_accessor :methods
|
5
|
+
module GrpcRest
|
6
|
+
class GeneratedService
|
7
|
+
attr_accessor :methods, :service
|
8
8
|
|
9
|
-
# @param
|
10
|
-
|
11
|
-
|
12
|
-
# see https://github.com/protocolbuffers/protobuf/issues/21091 for why this is needed
|
9
|
+
# @param service [Class < GRPC::GenericService]
|
10
|
+
def initialize(service)
|
11
|
+
@service = service
|
13
12
|
# this will return a Google::Protobuf::ServiceDescriptor
|
14
|
-
@
|
15
|
-
if @service.nil?
|
16
|
-
ProtocGenRails::Output.exit_with_error("Could not find generated service: #{package}.#{service_proto.name}")
|
17
|
-
end
|
13
|
+
@service_proto = Google::Protobuf::DescriptorPool.generated_pool.lookup(service.service_name)
|
18
14
|
@methods = []
|
19
|
-
@
|
20
|
-
@service.each do |m|
|
15
|
+
@service_proto.each do |m|
|
21
16
|
# m is a Google::Protobuf::MethodDescriptor
|
22
|
-
@methods.push(
|
17
|
+
@methods.push(GrpcRest::GeneratedMethod.new(m))
|
23
18
|
end
|
24
19
|
end
|
25
20
|
|
26
21
|
# @return [String]
|
27
22
|
def name
|
28
|
-
@
|
29
|
-
end
|
30
|
-
|
31
|
-
# @return [String]
|
32
|
-
def namespace
|
33
|
-
@package.split('.').map(&:camelcase).join('::')
|
23
|
+
@service_proto.name.split('.').map(&:camelcase).join('::').demodulize
|
34
24
|
end
|
35
25
|
end
|
36
26
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "action_mailer/railtie"
|
2
|
+
require 'generator/service'
|
3
|
+
require 'generator/controller'
|
4
|
+
|
5
|
+
class GrpcRest::Railtie < Rails::Railtie
|
6
|
+
initializer 'grpc-rest' do
|
7
|
+
Rails.configuration.after_initialize do
|
8
|
+
grpc_services = GrpcRest.services
|
9
|
+
if grpc_services.blank? && defined?(Gruf)
|
10
|
+
grpc_services = ::Gruf::Controllers::Base.subclasses.map(&:bound_service)
|
11
|
+
end
|
12
|
+
grpc_services&.each do |s|
|
13
|
+
service = GrpcRest::GeneratedService.new(s)
|
14
|
+
GrpcRest.controller(service)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/grpc_rest/version.rb
CHANGED
data/lib/grpc_rest.rb
CHANGED
@@ -3,10 +3,15 @@
|
|
3
3
|
require 'google/protobuf/well_known_types'
|
4
4
|
require 'grpc'
|
5
5
|
require 'grpc/core/status_codes'
|
6
|
+
require 'grpc_rest/railtie'
|
6
7
|
|
7
8
|
module GrpcRest
|
9
|
+
|
10
|
+
GrpcRestCall = Struct.new(:metadata)
|
11
|
+
|
8
12
|
class << self
|
9
13
|
attr_accessor :strict_mode
|
14
|
+
attr_accessor :services
|
10
15
|
|
11
16
|
def underscore(s)
|
12
17
|
GRPC::GenericService.underscore(s)
|
@@ -191,7 +196,7 @@ module GrpcRest
|
|
191
196
|
message: error.message,
|
192
197
|
details: [
|
193
198
|
{
|
194
|
-
backtrace:
|
199
|
+
backtrace: error_info
|
195
200
|
}
|
196
201
|
]
|
197
202
|
}
|
@@ -208,21 +213,29 @@ module GrpcRest
|
|
208
213
|
end
|
209
214
|
end
|
210
215
|
|
211
|
-
def send_gruf_request(klass, service_obj, method, request)
|
216
|
+
def send_gruf_request(klass, service_obj, method, request, headers: {})
|
212
217
|
ref = service_obj.rpc_descs[method.classify.to_sym]
|
218
|
+
call = GrpcRestCall.new(headers)
|
213
219
|
handler = klass.new(
|
214
220
|
method_key: method.to_sym,
|
215
221
|
service: service_obj,
|
216
222
|
rpc_desc: ref,
|
217
|
-
active_call:
|
223
|
+
active_call: GrpcRestCall.new(headers),
|
224
|
+
message: request
|
225
|
+
)
|
226
|
+
controller_request = Gruf::Controllers::Request.new(
|
227
|
+
method_key: method.to_sym,
|
228
|
+
service: service_obj,
|
229
|
+
rpc_desc: ref,
|
230
|
+
active_call: call,
|
218
231
|
message: request
|
219
232
|
)
|
220
|
-
Gruf::Interceptors::Context.new(gruf_interceptors(
|
233
|
+
Gruf::Interceptors::Context.new(gruf_interceptors(controller_request)).intercept! do
|
221
234
|
handler.send(method.to_sym)
|
222
235
|
end
|
223
236
|
end
|
224
237
|
|
225
|
-
# @param request [
|
238
|
+
# @param request [Gruf::Controllers::Request]
|
226
239
|
# @return [Array<Gruf::Interceptors::Base>]
|
227
240
|
def gruf_interceptors(request)
|
228
241
|
error = Gruf::Error.new
|
@@ -232,23 +245,22 @@ module GrpcRest
|
|
232
245
|
end
|
233
246
|
|
234
247
|
def send_grpc_request(service, method, request)
|
235
|
-
klass = service.
|
248
|
+
klass = service.subclasses.first
|
236
249
|
klass.new.public_send(method, request)
|
237
250
|
end
|
238
251
|
|
239
|
-
def get_response(service, method, request)
|
252
|
+
def get_response(service, method, request, headers: {})
|
240
253
|
if defined?(Gruf)
|
241
|
-
service_obj = service.constantize::Service
|
242
254
|
klass = ::Gruf::Controllers::Base.subclasses.find do |k|
|
243
|
-
k.bound_service ==
|
255
|
+
k.bound_service == service
|
244
256
|
end
|
245
|
-
return send_gruf_request(klass,
|
257
|
+
return send_gruf_request(klass, service, method, request, headers: headers) if klass
|
246
258
|
end
|
247
259
|
send_grpc_request(service, method, request)
|
248
260
|
end
|
249
261
|
|
250
|
-
def send_request(service, method, request, options = {})
|
251
|
-
response = get_response(service, method, request)
|
262
|
+
def send_request(service, method, request, options = {}, headers: {})
|
263
|
+
response = get_response(service, method, request, headers: headers)
|
252
264
|
if options[:emit_defaults]
|
253
265
|
response.to_json(emit_defaults: true)
|
254
266
|
else
|
data/spec/grpc_rest_spec.rb
CHANGED
@@ -23,7 +23,7 @@ class ServerImpl < Testdata::MyService::Service
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
RSpec.describe
|
26
|
+
RSpec.describe 'generated controller', type: :request do
|
27
27
|
describe 'using get' do
|
28
28
|
it 'should be successful' do
|
29
29
|
get '/test/blah/xyz?test_id=abc'
|
data/spec/gruf_spec.rb
CHANGED
@@ -35,7 +35,7 @@ end
|
|
35
35
|
|
36
36
|
Gruf::Server.new.add_interceptor(TestInterceptor, option_foo: 'value 123')
|
37
37
|
|
38
|
-
RSpec.describe
|
38
|
+
RSpec.describe 'generated controller', type: :request do
|
39
39
|
describe 'using get' do
|
40
40
|
it 'should be successful and call interceptors' do
|
41
41
|
GrufServerImpl.intercepted = false
|
data/spec/spec_helper.rb
CHANGED
@@ -1,28 +1,33 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'action_controller/railtie'
|
4
|
+
require 'grpc_rest'
|
5
|
+
|
6
|
+
require 'rspec/rails'
|
7
|
+
require 'rspec/snapshot'
|
8
|
+
require 'zeitwerk'
|
4
9
|
|
5
10
|
class GrpcApp < Rails::Application
|
6
11
|
initializer(:host_config) do
|
7
12
|
Rails.application.config.hosts << 'www.example.com'
|
8
13
|
end
|
9
14
|
end
|
10
|
-
GrpcApp.initialize!
|
11
|
-
|
12
|
-
require 'rspec/rails'
|
13
|
-
require 'rspec/snapshot'
|
14
15
|
|
15
16
|
loader = Zeitwerk::Loader.new
|
16
17
|
loader.push_dir('./spec')
|
17
18
|
loader.inflector.inflect('protoc-gen-openapiv2' => 'ProtocGenOpenapiv2')
|
18
|
-
loader.ignore("#{Rails.root}/spec
|
19
|
+
loader.ignore("#{Rails.root}/spec/*.rb")
|
19
20
|
loader.setup
|
20
21
|
$LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
|
21
22
|
$LOAD_PATH.unshift(File.expand_path('gen', __dir__))
|
22
23
|
|
23
|
-
require "#{Rails.root}/spec/
|
24
|
+
require "#{Rails.root}/spec/test_service_services_pb.rb"
|
24
25
|
require "#{Rails.root}/lib/base_interceptor.rb"
|
25
26
|
|
27
|
+
GrpcRest.services = [Testdata::MyService::Service]
|
28
|
+
|
29
|
+
GrpcApp.initialize!
|
30
|
+
|
26
31
|
RSpec.configure do |config|
|
27
32
|
config.full_backtrace = true
|
28
33
|
config.render_views
|
@@ -32,9 +37,3 @@ RSpec.configure do |config|
|
|
32
37
|
mocks.verify_partial_doubles = true
|
33
38
|
end
|
34
39
|
end
|
35
|
-
|
36
|
-
require_relative 'testdata/base/app/controllers/my_service_controller'
|
37
|
-
Rails.application.routes.draw_paths.push("#{Rails.root}/spec/testdata/base/config/routes")
|
38
|
-
Rails.application.routes.draw do
|
39
|
-
draw(:grpc)
|
40
|
-
end
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
4
2
|
# Source: test_service.proto for package 'testdata'
|
5
3
|
|
@@ -9,6 +7,7 @@ require 'test_service_pb'
|
|
9
7
|
module Testdata
|
10
8
|
module MyService
|
11
9
|
class Service
|
10
|
+
|
12
11
|
include ::GRPC::GenericService
|
13
12
|
|
14
13
|
self.marshal_class_method = :encode
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grpc-rest
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Orner
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: google-protobuf
|
@@ -108,7 +107,6 @@ dependencies:
|
|
108
107
|
- - ">="
|
109
108
|
- !ruby/object:Gem::Version
|
110
109
|
version: '0'
|
111
|
-
description:
|
112
110
|
email:
|
113
111
|
- daniel.orner@flipp.com
|
114
112
|
executables:
|
@@ -117,6 +115,7 @@ extensions: []
|
|
117
115
|
extra_rdoc_files: []
|
118
116
|
files:
|
119
117
|
- ".github/workflows/CI.yml"
|
118
|
+
- ".github/workflows/release.yml"
|
120
119
|
- ".gitignore"
|
121
120
|
- ".rubocop.yml"
|
122
121
|
- CHANGELOG
|
@@ -124,27 +123,20 @@ files:
|
|
124
123
|
- Gemfile
|
125
124
|
- Gemfile.lock
|
126
125
|
- README.md
|
126
|
+
- Rakefile
|
127
127
|
- bin/protoc-gen-rails
|
128
128
|
- grpc-rest.gemspec
|
129
129
|
- lib/base_interceptor.rb
|
130
130
|
- lib/generator.rb
|
131
|
-
- lib/generator/controller.rb
|
132
|
-
- lib/generator/grpc.rb.erb
|
131
|
+
- lib/generator/controller.rb
|
133
132
|
- lib/generator/method.rb
|
134
|
-
- lib/generator/output.rb
|
135
|
-
- lib/generator/plugin_pb.rb
|
136
133
|
- lib/generator/service.rb
|
137
134
|
- lib/grpc_rest.rb
|
135
|
+
- lib/grpc_rest/railtie.rb
|
138
136
|
- lib/grpc_rest/version.rb
|
139
|
-
- spec/__snapshots__/no_service.snap
|
140
|
-
- spec/__snapshots__/service.snap
|
141
137
|
- spec/base_interceptor_spec.rb
|
142
138
|
- spec/gen/protoc-gen-openapiv2/options/annotations_pb.rb
|
143
139
|
- spec/gen/protoc-gen-openapiv2/options/openapiv2_pb.rb
|
144
|
-
- spec/gen/test_pb.rb
|
145
|
-
- spec/gen/test_service_pb.rb
|
146
|
-
- spec/gen/test_service_services_pb.rb
|
147
|
-
- spec/generator_spec.rb
|
148
140
|
- spec/google-deps/google/api/annotations.proto
|
149
141
|
- spec/google-deps/google/api/http.proto
|
150
142
|
- spec/google-deps/protoc-gen-openapiv2/options/annotations.proto
|
@@ -154,16 +146,12 @@ files:
|
|
154
146
|
- spec/spec_helper.rb
|
155
147
|
- spec/test_service_pb.rb
|
156
148
|
- spec/test_service_services_pb.rb
|
157
|
-
- spec/testdata/base/app/controllers/my_service_controller.rb
|
158
|
-
- spec/testdata/base/config/routes/grpc.rb
|
159
|
-
- spec/testdata/no_service/.keep
|
160
149
|
- spec/testdata/test.proto
|
161
150
|
- spec/testdata/test_service.proto
|
162
151
|
homepage: ''
|
163
152
|
licenses:
|
164
153
|
- MIT
|
165
154
|
metadata: {}
|
166
|
-
post_install_message:
|
167
155
|
rdoc_options: []
|
168
156
|
require_paths:
|
169
157
|
- lib
|
@@ -178,20 +166,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
178
166
|
- !ruby/object:Gem::Version
|
179
167
|
version: '0'
|
180
168
|
requirements: []
|
181
|
-
rubygems_version: 3.
|
182
|
-
signing_key:
|
169
|
+
rubygems_version: 3.6.9
|
183
170
|
specification_version: 4
|
184
171
|
summary: Generate Rails controllers and routes from gRPC definitions.
|
185
172
|
test_files:
|
186
|
-
- spec/__snapshots__/no_service.snap
|
187
|
-
- spec/__snapshots__/service.snap
|
188
173
|
- spec/base_interceptor_spec.rb
|
189
174
|
- spec/gen/protoc-gen-openapiv2/options/annotations_pb.rb
|
190
175
|
- spec/gen/protoc-gen-openapiv2/options/openapiv2_pb.rb
|
191
|
-
- spec/gen/test_pb.rb
|
192
|
-
- spec/gen/test_service_pb.rb
|
193
|
-
- spec/gen/test_service_services_pb.rb
|
194
|
-
- spec/generator_spec.rb
|
195
176
|
- spec/google-deps/google/api/annotations.proto
|
196
177
|
- spec/google-deps/google/api/http.proto
|
197
178
|
- spec/google-deps/protoc-gen-openapiv2/options/annotations.proto
|
@@ -201,8 +182,5 @@ test_files:
|
|
201
182
|
- spec/spec_helper.rb
|
202
183
|
- spec/test_service_pb.rb
|
203
184
|
- spec/test_service_services_pb.rb
|
204
|
-
- spec/testdata/base/app/controllers/my_service_controller.rb
|
205
|
-
- spec/testdata/base/config/routes/grpc.rb
|
206
|
-
- spec/testdata/no_service/.keep
|
207
185
|
- spec/testdata/test.proto
|
208
186
|
- spec/testdata/test_service.proto
|
@@ -1,27 +0,0 @@
|
|
1
|
-
####### THIS FILE IS AUTOMATICALLY GENERATED BY protoc-gen-rails. DO NOT MODIFY. #######
|
2
|
-
|
3
|
-
require 'grpc_rest'
|
4
|
-
class <%= service.name.demodulize %>Controller < ActionController::Base
|
5
|
-
protect_from_forgery with: :null_session
|
6
|
-
|
7
|
-
rescue_from StandardError do |e|
|
8
|
-
render json: GrpcRest.error_msg(e), status: :internal_server_error
|
9
|
-
end
|
10
|
-
rescue_from GRPC::BadStatus do |e|
|
11
|
-
render json: GrpcRest.error_msg(e), status: GrpcRest.grpc_http_status(e.code)
|
12
|
-
end
|
13
|
-
rescue_from ActionDispatch::Http::Parameters::ParseError, Google::Protobuf::TypeError do |e|
|
14
|
-
render json: GrpcRest.error_msg(e), status: :bad_request
|
15
|
-
end
|
16
|
-
METHOD_PARAM_MAP = <%= service.methods.to_h { |m| [m.name.underscore, m.path_info.map(&:to_h)]}.pretty_inspect %>.freeze
|
17
|
-
|
18
|
-
<% service.methods.each do |method| %>
|
19
|
-
def <%= method.name %>
|
20
|
-
parameters = request.parameters.to_h.deep_transform_keys(&:underscore).
|
21
|
-
except(*%w(controller action <%= service.name.underscore %>))
|
22
|
-
grpc_request = GrpcRest.init_request(<%= method.request_type %>, parameters)
|
23
|
-
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["<%= method.name.underscore %>"], "<%= method.option_body %>", request.parameters)
|
24
|
-
render json: GrpcRest.send_request("<%= service.namespace %>::<%= service.name.classify %>", "<%= method.name.underscore %>", grpc_request, <%= method.rest_options.inspect %>)
|
25
|
-
end
|
26
|
-
<% end %>
|
27
|
-
end
|
data/lib/generator/grpc.rb.erb
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
####### THIS FILE IS AUTOMATICALLY GENERATED BY protoc-gen-rails. DO NOT MODIFY. #######
|
4
|
-
|
5
|
-
<% services.each do |service| -%>
|
6
|
-
<% service.methods.each do |method| %>
|
7
|
-
<%= method.http_method %> '<%= method.sanitized_path %>' => '<%= service.name.demodulize.underscore %>#<%= method.name.underscore %>' <% -%>
|
8
|
-
<% end %>
|
9
|
-
<% end %>
|
data/lib/generator/output.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ProtocGenRails
|
4
|
-
module Output
|
5
|
-
class << self
|
6
|
-
# @param files [Array<FileResult>]
|
7
|
-
# @return [String]
|
8
|
-
def response(files)
|
9
|
-
response = Google::Protobuf::Compiler::CodeGeneratorResponse.new
|
10
|
-
response.supported_features = Google::Protobuf::Compiler::CodeGeneratorResponse::Feature::FEATURE_PROTO3_OPTIONAL
|
11
|
-
files.each do |file|
|
12
|
-
response.file << Google::Protobuf::Compiler::CodeGeneratorResponse::File.new(name: file.name,
|
13
|
-
content: file.content)
|
14
|
-
end
|
15
|
-
response.to_proto
|
16
|
-
end
|
17
|
-
|
18
|
-
# @param error [String]
|
19
|
-
def exit_with_error(error)
|
20
|
-
response = Google::Protobuf::Compiler::CodeGeneratorResponse.new
|
21
|
-
response.error = error
|
22
|
-
$stderr << "#{error}\n"
|
23
|
-
$stdout << response.to_proto
|
24
|
-
exit(1)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
data/lib/generator/plugin_pb.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
4
|
-
# source: google/protobuf/compiler/plugin.proto
|
5
|
-
|
6
|
-
require 'google/protobuf'
|
7
|
-
|
8
|
-
require 'google/protobuf/descriptor_pb'
|
9
|
-
|
10
|
-
descriptor_data = "\n%google/protobuf/compiler/plugin.proto\x12\x18google.protobuf.compiler\x1a google/protobuf/descriptor.proto\"F\n\x07Version\x12\r\n\x05major\x18\x01 \x01(\x05\x12\r\n\x05minor\x18\x02 \x01(\x05\x12\r\n\x05patch\x18\x03 \x01(\x05\x12\x0e\n\x06suffix\x18\x04 \x01(\t\"\x81\x02\n\x14\x43odeGeneratorRequest\x12\x18\n\x10\x66ile_to_generate\x18\x01 \x03(\t\x12\x11\n\tparameter\x18\x02 \x01(\t\x12\x38\n\nproto_file\x18\x0f \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\x12\x45\n\x17source_file_descriptors\x18\x11 \x03(\x0b\x32$.google.protobuf.FileDescriptorProto\x12;\n\x10\x63ompiler_version\x18\x03 \x01(\x0b\x32!.google.protobuf.compiler.Version\"\x92\x03\n\x15\x43odeGeneratorResponse\x12\r\n\x05\x65rror\x18\x01 \x01(\t\x12\x1a\n\x12supported_features\x18\x02 \x01(\x04\x12\x17\n\x0fminimum_edition\x18\x03 \x01(\x05\x12\x17\n\x0fmaximum_edition\x18\x04 \x01(\x05\x12\x42\n\x04\x66ile\x18\x0f \x03(\x0b\x32\x34.google.protobuf.compiler.CodeGeneratorResponse.File\x1a\x7f\n\x04\x46ile\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x17\n\x0finsertion_point\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x0f \x01(\t\x12?\n\x13generated_code_info\x18\x10 \x01(\x0b\x32\".google.protobuf.GeneratedCodeInfo\"W\n\x07\x46\x65\x61ture\x12\x10\n\x0c\x46\x45\x41TURE_NONE\x10\x00\x12\x1b\n\x17\x46\x45\x41TURE_PROTO3_OPTIONAL\x10\x01\x12\x1d\n\x19\x46\x45\x41TURE_SUPPORTS_EDITIONS\x10\x02\x42r\n\x1c\x63om.google.protobuf.compilerB\x0cPluginProtosZ)google.golang.org/protobuf/types/pluginpb\xaa\x02\x18Google.Protobuf.Compiler"
|
11
|
-
|
12
|
-
pool = Google::Protobuf::DescriptorPool.generated_pool
|
13
|
-
pool.add_serialized_file(descriptor_data)
|
14
|
-
|
15
|
-
module Google
|
16
|
-
module Protobuf
|
17
|
-
module Compiler
|
18
|
-
Version = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('google.protobuf.compiler.Version').msgclass
|
19
|
-
CodeGeneratorRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('google.protobuf.compiler.CodeGeneratorRequest').msgclass
|
20
|
-
CodeGeneratorResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('google.protobuf.compiler.CodeGeneratorResponse').msgclass
|
21
|
-
CodeGeneratorResponse::File = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('google.protobuf.compiler.CodeGeneratorResponse.File').msgclass
|
22
|
-
CodeGeneratorResponse::Feature = ::Google::Protobuf::DescriptorPool.generated_pool.lookup('google.protobuf.compiler.CodeGeneratorResponse.Feature').enummodule
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
File without changes
|
@@ -1,73 +0,0 @@
|
|
1
|
-
spec/app/app/controllers/my_service_controller.rb:
|
2
|
-
####### THIS FILE IS AUTOMATICALLY GENERATED BY protoc-gen-rails. DO NOT MODIFY. #######
|
3
|
-
|
4
|
-
require 'grpc_rest'
|
5
|
-
class MyServiceController < ActionController::Base
|
6
|
-
protect_from_forgery with: :null_session
|
7
|
-
|
8
|
-
rescue_from StandardError do |e|
|
9
|
-
render json: GrpcRest.error_msg(e), status: :internal_server_error
|
10
|
-
end
|
11
|
-
rescue_from GRPC::BadStatus do |e|
|
12
|
-
render json: GrpcRest.error_msg(e), status: GrpcRest.grpc_http_status(e.code)
|
13
|
-
end
|
14
|
-
rescue_from ActionDispatch::Http::Parameters::ParseError, Google::Protobuf::TypeError do |e|
|
15
|
-
render json: GrpcRest.error_msg(e), status: :bad_request
|
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
|
25
|
-
|
26
|
-
|
27
|
-
def test
|
28
|
-
parameters = request.parameters.to_h.deep_transform_keys(&:underscore).
|
29
|
-
except(*%w(controller action my_service))
|
30
|
-
grpc_request = GrpcRest.init_request(Testdata::TestRequest, parameters)
|
31
|
-
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test"], "", request.parameters)
|
32
|
-
render json: GrpcRest.send_request("Testdata::MyService", "test", grpc_request, {:emit_defaults=>true})
|
33
|
-
end
|
34
|
-
|
35
|
-
def test2
|
36
|
-
parameters = request.parameters.to_h.deep_transform_keys(&:underscore).
|
37
|
-
except(*%w(controller action my_service))
|
38
|
-
grpc_request = GrpcRest.init_request(Testdata::TestRequest, parameters)
|
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, {})
|
41
|
-
end
|
42
|
-
|
43
|
-
def test3
|
44
|
-
parameters = request.parameters.to_h.deep_transform_keys(&:underscore).
|
45
|
-
except(*%w(controller action my_service))
|
46
|
-
grpc_request = GrpcRest.init_request(Testdata::TestRequest, parameters)
|
47
|
-
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test3"], "", request.parameters)
|
48
|
-
render json: GrpcRest.send_request("Testdata::MyService", "test3", grpc_request, {})
|
49
|
-
end
|
50
|
-
|
51
|
-
def test4
|
52
|
-
parameters = request.parameters.to_h.deep_transform_keys(&:underscore).
|
53
|
-
except(*%w(controller action my_service))
|
54
|
-
grpc_request = GrpcRest.init_request(Testdata::TestRequest, parameters)
|
55
|
-
GrpcRest.assign_params(grpc_request, METHOD_PARAM_MAP["test4"], "*", request.parameters)
|
56
|
-
render json: GrpcRest.send_request("Testdata::MyService", "test4", grpc_request, {})
|
57
|
-
end
|
58
|
-
|
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
|
-
|
data/spec/gen/test_pb.rb
DELETED
@@ -1,15 +0,0 @@
|
|
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
|
data/spec/gen/test_service_pb.rb
DELETED
@@ -1,23 +0,0 @@
|
|
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
|
@@ -1,26 +0,0 @@
|
|
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
|
data/spec/generator_spec.rb
DELETED
@@ -1,49 +0,0 @@
|
|
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
|