istox_gruf 2.7.1

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.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +246 -0
  3. data/CODE_OF_CONDUCT.md +46 -0
  4. data/README.md +544 -0
  5. data/bin/gruf +29 -0
  6. data/lib/gruf.rb +50 -0
  7. data/lib/gruf/cli/executor.rb +99 -0
  8. data/lib/gruf/client.rb +217 -0
  9. data/lib/gruf/client/error.rb +66 -0
  10. data/lib/gruf/client/error_factory.rb +105 -0
  11. data/lib/gruf/configuration.rb +137 -0
  12. data/lib/gruf/controllers/base.rb +102 -0
  13. data/lib/gruf/controllers/request.rb +121 -0
  14. data/lib/gruf/controllers/service_binder.rb +117 -0
  15. data/lib/gruf/error.rb +230 -0
  16. data/lib/gruf/errors/debug_info.rb +56 -0
  17. data/lib/gruf/errors/field.rb +56 -0
  18. data/lib/gruf/errors/helpers.rb +44 -0
  19. data/lib/gruf/hooks/base.rb +34 -0
  20. data/lib/gruf/hooks/executor.rb +47 -0
  21. data/lib/gruf/hooks/registry.rb +159 -0
  22. data/lib/gruf/instrumentable_grpc_server.rb +64 -0
  23. data/lib/gruf/integrations/rails/railtie.rb +10 -0
  24. data/lib/gruf/interceptors/active_record/connection_reset.rb +48 -0
  25. data/lib/gruf/interceptors/authentication/basic.rb +87 -0
  26. data/lib/gruf/interceptors/base.rb +53 -0
  27. data/lib/gruf/interceptors/client_interceptor.rb +125 -0
  28. data/lib/gruf/interceptors/context.rb +56 -0
  29. data/lib/gruf/interceptors/instrumentation/output_metadata_timer.rb +61 -0
  30. data/lib/gruf/interceptors/instrumentation/request_logging/formatters/base.rb +41 -0
  31. data/lib/gruf/interceptors/instrumentation/request_logging/formatters/logstash.rb +43 -0
  32. data/lib/gruf/interceptors/instrumentation/request_logging/formatters/plain.rb +48 -0
  33. data/lib/gruf/interceptors/instrumentation/request_logging/interceptor.rb +225 -0
  34. data/lib/gruf/interceptors/instrumentation/statsd.rb +82 -0
  35. data/lib/gruf/interceptors/registry.rb +161 -0
  36. data/lib/gruf/interceptors/server_interceptor.rb +34 -0
  37. data/lib/gruf/interceptors/timer.rb +85 -0
  38. data/lib/gruf/loggable.rb +30 -0
  39. data/lib/gruf/logging.rb +53 -0
  40. data/lib/gruf/outbound/request_context.rb +71 -0
  41. data/lib/gruf/response.rb +71 -0
  42. data/lib/gruf/serializers/errors/base.rb +57 -0
  43. data/lib/gruf/serializers/errors/json.rb +43 -0
  44. data/lib/gruf/server.rb +294 -0
  45. data/lib/gruf/synchronized_client.rb +97 -0
  46. data/lib/gruf/timer.rb +78 -0
  47. data/lib/gruf/version.rb +20 -0
  48. metadata +203 -0
@@ -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
@@ -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
@@ -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