istox_gruf 2.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +246 -0
- data/CODE_OF_CONDUCT.md +46 -0
- data/README.md +544 -0
- data/bin/gruf +29 -0
- data/lib/gruf.rb +50 -0
- data/lib/gruf/cli/executor.rb +99 -0
- data/lib/gruf/client.rb +217 -0
- data/lib/gruf/client/error.rb +66 -0
- data/lib/gruf/client/error_factory.rb +105 -0
- data/lib/gruf/configuration.rb +137 -0
- data/lib/gruf/controllers/base.rb +102 -0
- data/lib/gruf/controllers/request.rb +121 -0
- data/lib/gruf/controllers/service_binder.rb +117 -0
- data/lib/gruf/error.rb +230 -0
- data/lib/gruf/errors/debug_info.rb +56 -0
- data/lib/gruf/errors/field.rb +56 -0
- data/lib/gruf/errors/helpers.rb +44 -0
- data/lib/gruf/hooks/base.rb +34 -0
- data/lib/gruf/hooks/executor.rb +47 -0
- data/lib/gruf/hooks/registry.rb +159 -0
- data/lib/gruf/instrumentable_grpc_server.rb +64 -0
- data/lib/gruf/integrations/rails/railtie.rb +10 -0
- data/lib/gruf/interceptors/active_record/connection_reset.rb +48 -0
- data/lib/gruf/interceptors/authentication/basic.rb +87 -0
- data/lib/gruf/interceptors/base.rb +53 -0
- data/lib/gruf/interceptors/client_interceptor.rb +125 -0
- data/lib/gruf/interceptors/context.rb +56 -0
- data/lib/gruf/interceptors/instrumentation/output_metadata_timer.rb +61 -0
- data/lib/gruf/interceptors/instrumentation/request_logging/formatters/base.rb +41 -0
- data/lib/gruf/interceptors/instrumentation/request_logging/formatters/logstash.rb +43 -0
- data/lib/gruf/interceptors/instrumentation/request_logging/formatters/plain.rb +48 -0
- data/lib/gruf/interceptors/instrumentation/request_logging/interceptor.rb +225 -0
- data/lib/gruf/interceptors/instrumentation/statsd.rb +82 -0
- data/lib/gruf/interceptors/registry.rb +161 -0
- data/lib/gruf/interceptors/server_interceptor.rb +34 -0
- data/lib/gruf/interceptors/timer.rb +85 -0
- data/lib/gruf/loggable.rb +30 -0
- data/lib/gruf/logging.rb +53 -0
- data/lib/gruf/outbound/request_context.rb +71 -0
- data/lib/gruf/response.rb +71 -0
- data/lib/gruf/serializers/errors/base.rb +57 -0
- data/lib/gruf/serializers/errors/json.rb +43 -0
- data/lib/gruf/server.rb +294 -0
- data/lib/gruf/synchronized_client.rb +97 -0
- data/lib/gruf/timer.rb +78 -0
- data/lib/gruf/version.rb +20 -0
- metadata +203 -0
data/bin/gruf
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# coding: utf-8
|
3
|
+
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
6
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
7
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
8
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
11
|
+
# Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
14
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
15
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
16
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
17
|
+
#
|
18
|
+
require 'rubygems'
|
19
|
+
require 'bundler/setup'
|
20
|
+
begin
|
21
|
+
require 'rails'
|
22
|
+
rescue LoadError
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
load 'config/environment.rb' if defined?(Rails)
|
26
|
+
require 'gruf'
|
27
|
+
|
28
|
+
cli = Gruf::Cli::Executor.new
|
29
|
+
cli.run
|
data/lib/gruf.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
6
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
7
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
8
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
11
|
+
# Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
14
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
15
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
16
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
17
|
+
#
|
18
|
+
require 'grpc'
|
19
|
+
require 'active_support/core_ext/module/delegation'
|
20
|
+
require 'active_support/concern'
|
21
|
+
require 'active_support/inflector'
|
22
|
+
require 'base64'
|
23
|
+
require_relative 'gruf/version'
|
24
|
+
require_relative 'gruf/logging'
|
25
|
+
require_relative 'gruf/loggable'
|
26
|
+
require_relative 'gruf/configuration'
|
27
|
+
require_relative 'gruf/errors/helpers'
|
28
|
+
require_relative 'gruf/cli/executor'
|
29
|
+
require_relative 'gruf/controllers/base'
|
30
|
+
require_relative 'gruf/outbound/request_context'
|
31
|
+
require_relative 'gruf/interceptors/registry'
|
32
|
+
require_relative 'gruf/interceptors/base'
|
33
|
+
require_relative 'gruf/hooks/registry'
|
34
|
+
require_relative 'gruf/hooks/executor'
|
35
|
+
require_relative 'gruf/hooks/base'
|
36
|
+
require_relative 'gruf/timer'
|
37
|
+
require_relative 'gruf/response'
|
38
|
+
require_relative 'gruf/error'
|
39
|
+
require_relative 'gruf/client'
|
40
|
+
require_relative 'gruf/synchronized_client'
|
41
|
+
require_relative 'gruf/instrumentable_grpc_server'
|
42
|
+
require_relative 'gruf/server'
|
43
|
+
require_relative 'gruf/integrations/rails/railtie' if defined?(Rails)
|
44
|
+
|
45
|
+
##
|
46
|
+
# Initializes configuration of gruf core module
|
47
|
+
#
|
48
|
+
module Gruf
|
49
|
+
extend Configuration
|
50
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
6
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
7
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
8
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
11
|
+
# Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
14
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
15
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
16
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
17
|
+
#
|
18
|
+
require 'slop'
|
19
|
+
|
20
|
+
module Gruf
|
21
|
+
module Cli
|
22
|
+
##
|
23
|
+
# Handles execution of the gruf binstub, along with command-line arguments
|
24
|
+
#
|
25
|
+
class Executor
|
26
|
+
##
|
27
|
+
# @param [Hash|ARGV]
|
28
|
+
#
|
29
|
+
def initialize(
|
30
|
+
args = ARGV,
|
31
|
+
server: nil,
|
32
|
+
services: nil,
|
33
|
+
hook_executor: nil,
|
34
|
+
logger: nil
|
35
|
+
)
|
36
|
+
@args = args
|
37
|
+
setup! # ensure we set some defaults from CLI here so we can allow configuration
|
38
|
+
@services = services || Gruf.services
|
39
|
+
@hook_executor = hook_executor || Gruf::Hooks::Executor.new(hooks: Gruf.hooks&.prepare)
|
40
|
+
@server = server || Gruf::Server.new(Gruf.server_options)
|
41
|
+
@logger = logger || Gruf.logger || ::Logger.new(STDERR)
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Run the server
|
46
|
+
#
|
47
|
+
def run
|
48
|
+
exception = nil
|
49
|
+
begin
|
50
|
+
@services.each { |s| @server.add_service(s) }
|
51
|
+
@hook_executor.call(:before_server_start, server: @server)
|
52
|
+
@server.start!
|
53
|
+
rescue StandardError => e
|
54
|
+
exception = e
|
55
|
+
# Catch the exception here so that we always ensure the post hook runs
|
56
|
+
# This allows systems wanting to provide external server instrumentation
|
57
|
+
# the ability to properly handle server failures
|
58
|
+
@logger.fatal("FATAL ERROR: #{e.message} #{e.backtrace.join("\n")}")
|
59
|
+
end
|
60
|
+
@hook_executor.call(:after_server_stop, server: @server)
|
61
|
+
raise exception if exception
|
62
|
+
|
63
|
+
if @server.required_restart
|
64
|
+
restart
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def restart
|
69
|
+
@server = Gruf::Server.new(Gruf.server_options)
|
70
|
+
run
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
##
|
76
|
+
# Setup options for CLI execution and configure Gruf based on inputs
|
77
|
+
#
|
78
|
+
def setup!
|
79
|
+
opts = Slop.parse(@args) do |o|
|
80
|
+
o.null '-h', '--help', 'Display help message' do
|
81
|
+
puts o
|
82
|
+
exit(0)
|
83
|
+
end
|
84
|
+
o.string '--host', 'Specify the binding url for the gRPC service'
|
85
|
+
o.bool '--suppress-default-interceptors', 'Do not use the default interceptors'
|
86
|
+
o.bool '--backtrace-on-error', 'Push backtraces on exceptions to the error serializer'
|
87
|
+
o.null '-v', '--version', 'print gruf version' do
|
88
|
+
puts Gruf::VERSION
|
89
|
+
exit(0)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
Gruf.server_binding_url = opts[:host] if opts[:host]
|
94
|
+
Gruf.use_default_interceptors = false if opts.suppress_default_interceptors?
|
95
|
+
Gruf.backtrace_on_error = true if opts.backtrace_on_error?
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/gruf/client.rb
ADDED
@@ -0,0 +1,217 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
6
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
7
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
8
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
11
|
+
# Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
14
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
15
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
16
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
17
|
+
#
|
18
|
+
require_relative 'client/error'
|
19
|
+
require_relative 'client/error_factory'
|
20
|
+
|
21
|
+
module Gruf
|
22
|
+
##
|
23
|
+
# Abstracts out the calling interface for interacting with gRPC clients. Streamlines calling and provides
|
24
|
+
# instrumented response objects that also can contain deserialized error messages via serialized objects transported
|
25
|
+
# via the service's trailing metadata.
|
26
|
+
#
|
27
|
+
# begin
|
28
|
+
# client = ::Gruf::Client.new(service: ::Demo::ThingService)
|
29
|
+
# response = client.call(:GetMyThing, id: 123)
|
30
|
+
# puts response.message.inspect
|
31
|
+
# rescue Gruf::Client::Error => e
|
32
|
+
# puts e.error.inspect
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# Utilizes SimpleDelegator to wrap the given service that the client is connecting to, which allows a clean interface
|
36
|
+
# to the underlying RPC descriptors and methods.
|
37
|
+
#
|
38
|
+
class Client < SimpleDelegator
|
39
|
+
include Gruf::Loggable
|
40
|
+
|
41
|
+
# @return [Class] The base, friendly name of the service being requested
|
42
|
+
attr_reader :base_klass
|
43
|
+
# @return [Class] The class name of the gRPC service being requested
|
44
|
+
attr_reader :service_klass
|
45
|
+
# @return [Hash] A hash of options for the client
|
46
|
+
attr_reader :opts
|
47
|
+
|
48
|
+
##
|
49
|
+
# Initialize the client and setup the stub
|
50
|
+
#
|
51
|
+
# @param [Module] service The namespace of the client Stub that is desired to load
|
52
|
+
# @param [Hash] options A hash of options for the client
|
53
|
+
# @option options [String] :password The password for basic authentication for the service.
|
54
|
+
# @option options [String] :hostname The hostname of the service. Defaults to linkerd.
|
55
|
+
# @param [Hash] client_options A hash of options to pass to the gRPC client stub
|
56
|
+
#
|
57
|
+
def initialize(service:, options: {}, client_options: {})
|
58
|
+
@base_klass = service
|
59
|
+
@service_klass = "#{base_klass}::Service".constantize
|
60
|
+
@opts = options || {}
|
61
|
+
@opts[:password] = @opts.fetch(:password, '').to_s
|
62
|
+
@opts[:hostname] = @opts.fetch(:hostname, Gruf.default_client_host)
|
63
|
+
@error_factory = Gruf::Client::ErrorFactory.new
|
64
|
+
client_options[:timeout] = client_options[:timeout].to_i if client_options.key?(:timeout)
|
65
|
+
client = "#{service}::Stub".constantize.new(@opts[:hostname], build_ssl_credentials, client_options)
|
66
|
+
super(client)
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# Call the client's method with given params
|
71
|
+
#
|
72
|
+
# @param [String|Symbol] request_method The method that is being requested on the service
|
73
|
+
# @param [Hash] params (Optional) A hash of parameters that will be inserted into the gRPC request message that is
|
74
|
+
# required for the given above call
|
75
|
+
# @param [Hash] metadata (Optional) A hash of metadata key/values that are transported with the client request
|
76
|
+
# @param [Hash] opts (Optional) A hash of options to send to the gRPC request_response method
|
77
|
+
# @return [Gruf::Response] The response from the server
|
78
|
+
# @raise [Gruf::Client::Error|GRPC::BadStatus] If an error occurs, an exception will be raised according to the
|
79
|
+
# error type that was returned
|
80
|
+
#
|
81
|
+
def call(request_method, params = {}, metadata = {}, opts = {}, &block)
|
82
|
+
request_method = request_method.to_sym
|
83
|
+
req = streaming_request?(request_method) ? params : request_object(request_method, params)
|
84
|
+
md = build_metadata(metadata)
|
85
|
+
call_sig = call_signature(request_method)
|
86
|
+
|
87
|
+
unless call_sig
|
88
|
+
raise NotImplementedError, "The method #{request_method} has not been implemented in this service."
|
89
|
+
end
|
90
|
+
|
91
|
+
resp, operation = execute(call_sig, req, md, opts, &block)
|
92
|
+
|
93
|
+
raise @error_factory.from_exception(resp.result) unless resp.success?
|
94
|
+
|
95
|
+
Gruf::Response.new(operation: operation, message: resp.result, execution_time: resp.time)
|
96
|
+
end
|
97
|
+
|
98
|
+
##
|
99
|
+
# Returns the currently set timeout on the client stub
|
100
|
+
#
|
101
|
+
# @return [Integer|NilClass]
|
102
|
+
#
|
103
|
+
def timeout
|
104
|
+
__getobj__.instance_variable_get(:@timeout)
|
105
|
+
end
|
106
|
+
|
107
|
+
private
|
108
|
+
|
109
|
+
##
|
110
|
+
# @param [Symbol] request_method
|
111
|
+
# @return [Boolean]
|
112
|
+
#
|
113
|
+
def streaming_request?(request_method)
|
114
|
+
desc = rpc_desc(request_method)
|
115
|
+
desc && (desc.client_streamer? || desc.bidi_streamer?)
|
116
|
+
end
|
117
|
+
|
118
|
+
##
|
119
|
+
# Execute the given request to the service
|
120
|
+
#
|
121
|
+
# @param [Symbol] call_sig The call signature being executed
|
122
|
+
# @param [Object] req (Optional) The protobuf request message to send
|
123
|
+
# @param [Hash] metadata (Optional) A hash of metadata key/values that are transported with the client request
|
124
|
+
# @param [Hash] opts (Optional) A hash of options to send to the gRPC request_response method
|
125
|
+
# @return [Array<Gruf::Timer::Result, GRPC::ActiveCall::Operation>]
|
126
|
+
#
|
127
|
+
def execute(call_sig, req, metadata, opts = {}, &block)
|
128
|
+
operation = nil
|
129
|
+
result = Gruf::Timer.time do
|
130
|
+
opts[:return_op] = true
|
131
|
+
opts[:metadata] = metadata
|
132
|
+
operation = send(call_sig, req, opts, &block)
|
133
|
+
operation.execute
|
134
|
+
end
|
135
|
+
[result, operation]
|
136
|
+
end
|
137
|
+
|
138
|
+
##
|
139
|
+
# Get the appropriate RPC descriptor given the method on the service being called
|
140
|
+
#
|
141
|
+
# @param [Symbol] request_method The method name being called on the remote service
|
142
|
+
# @return [Struct<GRPC::RpcDesc>] Return the given RPC descriptor given the method on the service being called
|
143
|
+
#
|
144
|
+
def rpc_desc(request_method)
|
145
|
+
service_klass.rpc_descs[request_method]
|
146
|
+
end
|
147
|
+
|
148
|
+
##
|
149
|
+
# Get the appropriate protobuf request message for the given request method on the service being called
|
150
|
+
#
|
151
|
+
# @param [Symbol] request_method The method name being called on the remote service
|
152
|
+
# @param [Hash] params (Optional) A hash of parameters that will populate the request object
|
153
|
+
# @return [Class] The request object that corresponds to the method being called
|
154
|
+
#
|
155
|
+
def request_object(request_method, params = {})
|
156
|
+
desc = rpc_desc(request_method)
|
157
|
+
desc&.input ? desc.input.new(params) : nil
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# Properly find the appropriate call signature for the GRPC::GenericService given the request method name
|
162
|
+
#
|
163
|
+
# @return [Symbol]
|
164
|
+
#
|
165
|
+
def call_signature(request_method)
|
166
|
+
desc = rpc_desc(request_method)
|
167
|
+
desc&.name ? desc.name.to_s.underscore.to_sym : nil
|
168
|
+
end
|
169
|
+
|
170
|
+
##
|
171
|
+
# Build a sanitized, authenticated metadata hash for the given request
|
172
|
+
#
|
173
|
+
# @param [Hash] metadata A base metadata hash to build from
|
174
|
+
# @return [Hash] The compiled metadata hash that is ready to be transported over the wire
|
175
|
+
#
|
176
|
+
def build_metadata(metadata = {})
|
177
|
+
unless opts[:password].empty?
|
178
|
+
username = opts.fetch(:username, 'grpc').to_s
|
179
|
+
username = username.empty? ? '' : "#{username}:"
|
180
|
+
auth_string = Base64.encode64("#{username}#{opts[:password]}")
|
181
|
+
metadata[:authorization] = "Basic #{auth_string}".tr("\n", '')
|
182
|
+
end
|
183
|
+
metadata
|
184
|
+
end
|
185
|
+
|
186
|
+
##
|
187
|
+
# Build the SSL/TLS credentials for the outbound gRPC request
|
188
|
+
#
|
189
|
+
# @return [Symbol|GRPC::Core::ChannelCredentials] The generated SSL credentials for the outbound gRPC request
|
190
|
+
#
|
191
|
+
# :nocov:
|
192
|
+
def build_ssl_credentials
|
193
|
+
cert = nil
|
194
|
+
if opts[:ssl_certificate_file]
|
195
|
+
cert = File.read(opts[:ssl_certificate_file]).to_s.strip
|
196
|
+
elsif opts[:ssl_certificate]
|
197
|
+
cert = opts[:ssl_certificate].to_s.strip
|
198
|
+
end
|
199
|
+
|
200
|
+
cert ? GRPC::Core::ChannelCredentials.new(cert) : :this_channel_is_insecure
|
201
|
+
end
|
202
|
+
# :nocov:
|
203
|
+
|
204
|
+
##
|
205
|
+
# Return the specified error deserializer class by the configuration
|
206
|
+
#
|
207
|
+
# @return [Class] The proper error deserializer class. Defaults to JSON.
|
208
|
+
#
|
209
|
+
def error_deserializer_class
|
210
|
+
if Gruf.error_serializer
|
211
|
+
Gruf.error_serializer.is_a?(Class) ? Gruf.error_serializer : Gruf.error_serializer.to_s.constantize
|
212
|
+
else
|
213
|
+
Gruf::Serializers::Errors::Json
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
6
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
7
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
8
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
11
|
+
# Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
14
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
15
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
16
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
17
|
+
#
|
18
|
+
module Gruf
|
19
|
+
class Client < SimpleDelegator
|
20
|
+
##
|
21
|
+
# Represents an error that was returned from the server's trailing metadata. Used as a custom exception object
|
22
|
+
# that is instead raised in the case of the service returning serialized error data, as opposed to the normal
|
23
|
+
# GRPC::BadStatus error
|
24
|
+
#
|
25
|
+
class Error < StandardError
|
26
|
+
# @return [Object] error The deserialized error
|
27
|
+
attr_reader :error
|
28
|
+
|
29
|
+
##
|
30
|
+
# Initialize the client error
|
31
|
+
#
|
32
|
+
# @param [Object] error The deserialized error
|
33
|
+
#
|
34
|
+
def initialize(error)
|
35
|
+
@error = error
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# See https://github.com/grpc/grpc-go/blob/master/codes/codes.go for a detailed summary of each error type
|
41
|
+
#
|
42
|
+
module Errors
|
43
|
+
class Base < Gruf::Client::Error; end
|
44
|
+
class Error < Base; end
|
45
|
+
class Validation < Base; end
|
46
|
+
|
47
|
+
class Ok < Base; end
|
48
|
+
|
49
|
+
class InvalidArgument < Validation; end
|
50
|
+
class NotFound < Validation; end
|
51
|
+
class AlreadyExists < Validation; end
|
52
|
+
class OutOfRange < Validation; end
|
53
|
+
|
54
|
+
class Cancelled < Error; end
|
55
|
+
class DataLoss < Error; end
|
56
|
+
class DeadlineExceeded < Error; end
|
57
|
+
class FailedPrecondition < Error; end
|
58
|
+
class Internal < Error; end
|
59
|
+
class PermissionDenied < Error; end
|
60
|
+
class Unauthenticated < Error; end
|
61
|
+
class Unavailable < Error; end
|
62
|
+
class Unimplemented < Error; end
|
63
|
+
class Unknown < Error; end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|