protobuffy 3.6.0 → 4.0.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/.gitignore +1 -0
- data/.rubocop.yml +67 -0
- data/.rubocop_todo.yml +145 -0
- data/.travis.yml +25 -5
- data/CHANGES.md +55 -0
- data/CONTRIBUTING.md +1 -1
- data/LICENSE.txt +17 -9
- data/README.md +13 -12
- data/Rakefile +15 -11
- data/bin/protoc-gen-ruby +8 -3
- data/bin/rpc_server +1 -0
- data/examples/lib/example/reverse-client.rb +2 -2
- data/install-protobuf.sh +28 -0
- data/lib/protobuf.rb +57 -53
- data/lib/protobuf/cli.rb +94 -74
- data/lib/protobuf/code_generator.rb +60 -9
- data/lib/protobuf/decoder.rb +19 -65
- data/lib/protobuf/deprecation.rb +117 -0
- data/lib/protobuf/descriptors/google/protobuf/compiler/plugin.pb.rb +11 -1
- data/lib/protobuf/descriptors/google/protobuf/descriptor.pb.rb +55 -3
- data/lib/protobuf/encoder.rb +13 -53
- data/lib/protobuf/enum.rb +58 -63
- data/lib/protobuf/field.rb +4 -4
- data/lib/protobuf/field/base_field.rb +101 -173
- data/lib/protobuf/field/bool_field.rb +17 -11
- data/lib/protobuf/field/bytes_field.rb +21 -35
- data/lib/protobuf/field/double_field.rb +0 -1
- data/lib/protobuf/field/enum_field.rb +23 -22
- data/lib/protobuf/field/field_array.rb +5 -4
- data/lib/protobuf/field/fixed32_field.rb +1 -1
- data/lib/protobuf/field/fixed64_field.rb +0 -1
- data/lib/protobuf/field/float_field.rb +4 -1
- data/lib/protobuf/field/int32_field.rb +0 -1
- data/lib/protobuf/field/int64_field.rb +0 -1
- data/lib/protobuf/field/integer_field.rb +0 -1
- data/lib/protobuf/field/message_field.rb +13 -28
- data/lib/protobuf/field/sfixed32_field.rb +0 -1
- data/lib/protobuf/field/sfixed64_field.rb +0 -1
- data/lib/protobuf/field/signed_integer_field.rb +0 -1
- data/lib/protobuf/field/sint32_field.rb +0 -1
- data/lib/protobuf/field/sint64_field.rb +0 -1
- data/lib/protobuf/field/string_field.rb +2 -4
- data/lib/protobuf/field/uint32_field.rb +0 -1
- data/lib/protobuf/field/uint64_field.rb +0 -1
- data/lib/protobuf/field/varint_field.rb +30 -13
- data/lib/protobuf/generators/base.rb +30 -16
- data/lib/protobuf/generators/enum_generator.rb +6 -9
- data/lib/protobuf/generators/extension_generator.rb +1 -2
- data/lib/protobuf/generators/field_generator.rb +25 -13
- data/lib/protobuf/generators/file_generator.rb +157 -35
- data/lib/protobuf/generators/group_generator.rb +22 -17
- data/lib/protobuf/generators/message_generator.rb +13 -14
- data/lib/protobuf/generators/option_generator.rb +17 -0
- data/lib/protobuf/generators/printable.rb +12 -13
- data/lib/protobuf/generators/service_generator.rb +2 -3
- data/lib/protobuf/http.rb +2 -2
- data/lib/protobuf/lifecycle.rb +20 -33
- data/lib/protobuf/logging.rb +39 -0
- data/lib/protobuf/message.rb +114 -47
- data/lib/protobuf/message/fields.rb +170 -88
- data/lib/protobuf/message/serialization.rb +19 -18
- data/lib/protobuf/optionable.rb +53 -6
- data/lib/protobuf/rpc/buffer.rb +18 -19
- data/lib/protobuf/rpc/client.rb +22 -50
- data/lib/protobuf/rpc/connectors/base.rb +177 -12
- data/lib/protobuf/rpc/connectors/http.rb +14 -9
- data/lib/protobuf/rpc/connectors/ping.rb +89 -0
- data/lib/protobuf/rpc/connectors/socket.rb +13 -8
- data/lib/protobuf/rpc/connectors/zmq.rb +178 -73
- data/lib/protobuf/rpc/dynamic_discovery.pb.rb +4 -1
- data/lib/protobuf/rpc/env.rb +12 -12
- data/lib/protobuf/rpc/error.rb +3 -3
- data/lib/protobuf/rpc/error/client_error.rb +4 -4
- data/lib/protobuf/rpc/error/server_error.rb +9 -9
- data/lib/protobuf/rpc/middleware/exception_handler.rb +6 -2
- data/lib/protobuf/rpc/middleware/logger.rb +8 -4
- data/lib/protobuf/rpc/middleware/request_decoder.rb +17 -21
- data/lib/protobuf/rpc/middleware/response_encoder.rb +22 -27
- data/lib/protobuf/rpc/middleware/statsd.rb +3 -3
- data/lib/protobuf/rpc/rpc.pb.rb +4 -1
- data/lib/protobuf/rpc/server.rb +1 -1
- data/lib/protobuf/rpc/servers/http/server.rb +19 -17
- data/lib/protobuf/rpc/servers/socket/server.rb +78 -70
- data/lib/protobuf/rpc/servers/socket/worker.rb +4 -4
- data/lib/protobuf/rpc/servers/socket_runner.rb +27 -15
- data/lib/protobuf/rpc/servers/zmq/broker.rb +70 -31
- data/lib/protobuf/rpc/servers/zmq/server.rb +55 -47
- data/lib/protobuf/rpc/servers/zmq/util.rb +14 -13
- data/lib/protobuf/rpc/servers/zmq/worker.rb +16 -16
- data/lib/protobuf/rpc/servers/zmq_runner.rb +26 -7
- data/lib/protobuf/rpc/service.rb +21 -27
- data/lib/protobuf/rpc/service_directory.rb +43 -27
- data/lib/protobuf/rpc/service_dispatcher.rb +9 -10
- data/lib/protobuf/rpc/service_filters.rb +32 -55
- data/lib/protobuf/rpc/stat.rb +4 -8
- data/lib/protobuf/socket.rb +1 -2
- data/lib/protobuf/tasks/compile.rake +3 -4
- data/lib/protobuf/varint.rb +9 -0
- data/lib/protobuf/varint_pure.rb +13 -0
- data/lib/protobuf/version.rb +1 -1
- data/lib/protobuf/zmq.rb +2 -2
- data/proto/google/protobuf/descriptor.proto +190 -31
- data/protobuffy.gemspec +30 -17
- data/spec/benchmark/tasks.rb +27 -19
- data/spec/bin/protoc-gen-ruby_spec.rb +11 -6
- data/spec/encoding/all_types_spec.rb +96 -84
- data/spec/encoding/extreme_values_spec.rb +0 -0
- data/spec/functional/class_inheritance_spec.rb +52 -0
- data/spec/functional/code_generator_spec.rb +38 -0
- data/spec/functional/socket_server_spec.rb +15 -15
- data/spec/functional/zmq_server_spec.rb +29 -27
- data/spec/lib/protobuf/cli_spec.rb +82 -67
- data/spec/lib/protobuf/code_generator_spec.rb +37 -10
- data/spec/lib/protobuf/enum_spec.rb +77 -46
- data/spec/lib/protobuf/field/bool_field_spec.rb +91 -0
- data/spec/lib/protobuf/field/double_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/enum_field_spec.rb +26 -0
- data/spec/lib/protobuf/field/field_array_spec.rb +69 -0
- data/spec/lib/protobuf/field/fixed32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/fixed64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/float_field_spec.rb +90 -0
- data/spec/lib/protobuf/field/int32_field_spec.rb +114 -1
- data/spec/lib/protobuf/field/int64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/message_field_spec.rb +132 -0
- data/spec/lib/protobuf/field/sfixed32_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sfixed64_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sint32_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/sint64_field_spec.rb +9 -0
- data/spec/lib/protobuf/field/string_field_spec.rb +44 -11
- data/spec/lib/protobuf/field/uint32_field_spec.rb +7 -0
- data/spec/lib/protobuf/field/uint64_field_spec.rb +7 -0
- data/spec/lib/protobuf/field_spec.rb +4 -6
- data/spec/lib/protobuf/generators/base_spec.rb +80 -13
- data/spec/lib/protobuf/generators/enum_generator_spec.rb +35 -21
- data/spec/lib/protobuf/generators/extension_generator_spec.rb +12 -13
- data/spec/lib/protobuf/generators/field_generator_spec.rb +73 -21
- data/spec/lib/protobuf/generators/file_generator_spec.rb +89 -6
- data/spec/lib/protobuf/generators/service_generator_spec.rb +25 -13
- data/spec/lib/protobuf/lifecycle_spec.rb +25 -20
- data/spec/lib/protobuf/message_spec.rb +578 -79
- data/spec/lib/protobuf/optionable_spec.rb +202 -26
- data/spec/lib/protobuf/rpc/client_spec.rb +16 -16
- data/spec/lib/protobuf/rpc/connectors/base_spec.rb +167 -13
- data/spec/lib/protobuf/rpc/connectors/connector_spec.rb +4 -5
- data/spec/lib/protobuf/rpc/connectors/http_spec.rb +13 -11
- data/spec/lib/protobuf/rpc/connectors/ping_spec.rb +69 -0
- data/spec/lib/protobuf/rpc/connectors/socket_spec.rb +6 -7
- data/spec/lib/protobuf/rpc/connectors/zmq_spec.rb +35 -52
- data/spec/lib/protobuf/rpc/middleware/exception_handler_spec.rb +10 -10
- data/spec/lib/protobuf/rpc/middleware/logger_spec.rb +11 -11
- data/spec/lib/protobuf/rpc/middleware/request_decoder_spec.rb +23 -23
- data/spec/lib/protobuf/rpc/middleware/response_encoder_spec.rb +11 -11
- data/spec/lib/protobuf/rpc/middleware/statsd_spec.rb +6 -6
- data/spec/lib/protobuf/rpc/servers/http/server_spec.rb +47 -44
- data/spec/lib/protobuf/rpc/servers/socket_server_spec.rb +6 -6
- data/spec/lib/protobuf/rpc/servers/zmq/server_spec.rb +12 -10
- data/spec/lib/protobuf/rpc/servers/zmq/util_spec.rb +11 -11
- data/spec/lib/protobuf/rpc/servers/zmq/worker_spec.rb +7 -7
- data/spec/lib/protobuf/rpc/service_directory_spec.rb +47 -49
- data/spec/lib/protobuf/rpc/service_dispatcher_spec.rb +8 -25
- data/spec/lib/protobuf/rpc/service_filters_spec.rb +102 -69
- data/spec/lib/protobuf/rpc/service_spec.rb +37 -36
- data/spec/lib/protobuf/rpc/stat_spec.rb +7 -9
- data/spec/lib/protobuf/varint_spec.rb +29 -0
- data/spec/lib/protobuf_spec.rb +55 -28
- data/spec/spec_helper.rb +12 -27
- data/spec/support/all.rb +0 -1
- data/spec/support/packed_field.rb +4 -3
- data/spec/support/{test → protos}/all_types.data.bin +0 -0
- data/spec/support/{test → protos}/all_types.data.txt +0 -0
- data/spec/support/{test → protos}/enum.pb.rb +8 -4
- data/spec/support/{test → protos}/enum.proto +4 -1
- data/spec/support/{test → protos}/extreme_values.data.bin +0 -0
- data/spec/support/protos/google_unittest.bin +0 -0
- data/spec/support/protos/google_unittest.pb.rb +798 -0
- data/spec/support/{test → protos}/google_unittest.proto +237 -66
- data/spec/support/protos/google_unittest_custom_options.bin +0 -0
- data/spec/support/protos/google_unittest_custom_options.pb.rb +268 -0
- data/spec/support/protos/google_unittest_custom_options.proto +424 -0
- data/spec/support/protos/google_unittest_import.pb.rb +55 -0
- data/spec/support/{test → protos}/google_unittest_import.proto +19 -10
- data/spec/support/protos/google_unittest_import_public.pb.rb +31 -0
- data/spec/support/{test → protos}/google_unittest_import_public.proto +8 -5
- data/spec/support/{test → protos}/multi_field_extensions.pb.rb +5 -2
- data/spec/support/{test → protos}/multi_field_extensions.proto +2 -0
- data/spec/support/{test → protos}/resource.pb.rb +47 -11
- data/spec/support/{test → protos}/resource.proto +24 -1
- data/spec/support/resource_service.rb +23 -0
- data/spec/support/server.rb +32 -61
- metadata +119 -59
- data/lib/protobuf/deprecator.rb +0 -42
- data/lib/protobuf/logger.rb +0 -93
- data/lib/protobuf/rpc/connector.rb +0 -21
- data/lib/protobuf/rpc/connectors/common.rb +0 -172
- data/spec/data/data.bin +0 -3
- data/spec/data/types.bin +0 -0
- data/spec/lib/protobuf/logger_spec.rb +0 -145
- data/spec/lib/protobuf/rpc/connector_spec.rb +0 -26
- data/spec/lib/protobuf/rpc/connectors/common_spec.rb +0 -170
- data/spec/support/test/defaults.pb.rb +0 -25
- data/spec/support/test/defaults.proto +0 -9
- data/spec/support/test/extended.pb.rb +0 -22
- data/spec/support/test/extended.proto +0 -10
- data/spec/support/test/google_unittest.pb.rb +0 -543
- data/spec/support/test/google_unittest_import.pb.rb +0 -37
- data/spec/support/test/google_unittest_import_public.pb.rb +0 -8
- data/spec/support/test/resource_service.rb +0 -26
- data/spec/support/tolerance_matcher.rb +0 -40
data/lib/protobuf/rpc/error.rb
CHANGED
@@ -8,8 +8,8 @@ module Protobuf
|
|
8
8
|
class PbError < StandardError
|
9
9
|
attr_reader :error_type
|
10
10
|
|
11
|
-
def initialize(message='An unknown RpcError occurred', error_type='RPC_ERROR')
|
12
|
-
@error_type = error_type.is_a?(String) ? Socketrpc::ErrorReason.const_get(error_type) : error_type
|
11
|
+
def initialize(message = 'An unknown RpcError occurred', error_type = 'RPC_ERROR')
|
12
|
+
@error_type = error_type.is_a?(String) ? ::Protobuf::Socketrpc::ErrorReason.const_get(error_type) : error_type
|
13
13
|
super message
|
14
14
|
end
|
15
15
|
|
@@ -18,7 +18,7 @@ module Protobuf
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def to_response
|
21
|
-
Socketrpc::Response.new(:error => message, :error_reason => error_type)
|
21
|
+
::Protobuf::Socketrpc::Response.new(:error => message, :error_reason => error_type)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -4,25 +4,25 @@ module Protobuf
|
|
4
4
|
module Rpc
|
5
5
|
|
6
6
|
class InvalidRequestProto < PbError
|
7
|
-
def initialize(message='Invalid request type given')
|
7
|
+
def initialize(message = 'Invalid request type given')
|
8
8
|
super message, 'INVALID_REQUEST_PROTO'
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
class BadResponseProto < PbError
|
13
|
-
def initialize(message='Bad response type from server')
|
13
|
+
def initialize(message = 'Bad response type from server')
|
14
14
|
super message, 'BAD_RESPONSE_PROTO'
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
class UnkownHost < PbError
|
19
|
-
def initialize(message='Unknown host or port')
|
19
|
+
def initialize(message = 'Unknown host or port')
|
20
20
|
super message, 'UNKNOWN_HOST'
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
class IOError < PbError
|
25
|
-
def initialize(message='IO Error occurred')
|
25
|
+
def initialize(message = 'IO Error occurred')
|
26
26
|
super message, 'IO_ERROR'
|
27
27
|
end
|
28
28
|
end
|
@@ -4,55 +4,55 @@ module Protobuf
|
|
4
4
|
module Rpc
|
5
5
|
|
6
6
|
class BadRequestData < PbError
|
7
|
-
def initialize
|
7
|
+
def initialize(message = 'Unable to parse request')
|
8
8
|
super message, 'BAD_REQUEST_DATA'
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
12
|
class BadRequestProto < PbError
|
13
|
-
def initialize
|
13
|
+
def initialize(message = 'Request is of wrong type')
|
14
14
|
super message, 'BAD_REQUEST_PROTO'
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
class ServiceNotFound < PbError
|
19
|
-
def initialize
|
19
|
+
def initialize(message = 'Service class not found')
|
20
20
|
super message, 'SERVICE_NOT_FOUND'
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
class MethodNotFound < PbError
|
25
|
-
def initialize
|
25
|
+
def initialize(message = 'Service method not found')
|
26
26
|
super message, 'METHOD_NOT_FOUND'
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
class RpcError < PbError
|
31
|
-
def initialize
|
31
|
+
def initialize(message = 'RPC exception occurred')
|
32
32
|
super message, 'RPC_ERROR'
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
class RpcFailed < PbError
|
37
|
-
def initialize
|
37
|
+
def initialize(message = 'RPC failed')
|
38
38
|
super message, 'RPC_FAILED'
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
42
|
class UnauthorizedRequest < PbError
|
43
|
-
def initialize
|
43
|
+
def initialize(message = 'The request requires user authentication')
|
44
44
|
super message, 'UNAUTHORIZED_REQUEST'
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
48
|
class ForbiddenRequest < PbError
|
49
|
-
def initialize
|
49
|
+
def initialize(message = 'User authentificated but does not have permissions')
|
50
50
|
super message, 'FORBIDDEN_REQUEST'
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
54
|
class DataNotFound < PbError
|
55
|
-
def initialize
|
55
|
+
def initialize(message = 'Requested data not found')
|
56
56
|
super message, 'DATA_NOT_FOUND'
|
57
57
|
end
|
58
58
|
end
|
@@ -2,7 +2,7 @@ module Protobuf
|
|
2
2
|
module Rpc
|
3
3
|
module Middleware
|
4
4
|
class ExceptionHandler
|
5
|
-
include ::Protobuf::
|
5
|
+
include ::Protobuf::Logging
|
6
6
|
|
7
7
|
attr_reader :app
|
8
8
|
|
@@ -11,6 +11,10 @@ module Protobuf
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def call(env)
|
14
|
+
dup._call(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
def _call(env)
|
14
18
|
app.call(env)
|
15
19
|
rescue => exception
|
16
20
|
log_exception(exception)
|
@@ -22,7 +26,7 @@ module Protobuf
|
|
22
26
|
env
|
23
27
|
end
|
24
28
|
|
25
|
-
|
29
|
+
private
|
26
30
|
|
27
31
|
# Wrap exceptions in a generic Protobuf errors unless they already are
|
28
32
|
#
|
@@ -8,6 +8,10 @@ module Protobuf
|
|
8
8
|
|
9
9
|
# TODO: Figure out how to control when logs are flushed
|
10
10
|
def call(env)
|
11
|
+
dup._call(env)
|
12
|
+
end
|
13
|
+
|
14
|
+
def _call(env)
|
11
15
|
instrumenter.start
|
12
16
|
instrumenter.flush(env) # Log request stats
|
13
17
|
|
@@ -19,7 +23,7 @@ module Protobuf
|
|
19
23
|
env
|
20
24
|
end
|
21
25
|
|
22
|
-
|
26
|
+
private
|
23
27
|
|
24
28
|
def instrumenter
|
25
29
|
@instrumenter ||= Instrumenter.new
|
@@ -42,7 +46,7 @@ module Protobuf
|
|
42
46
|
attr_reader :env
|
43
47
|
|
44
48
|
def flush(env)
|
45
|
-
Protobuf::
|
49
|
+
::Protobuf::Logging.logger.info { to_s(env) }
|
46
50
|
end
|
47
51
|
|
48
52
|
def start
|
@@ -63,11 +67,11 @@ module Protobuf
|
|
63
67
|
rpc,
|
64
68
|
sizes,
|
65
69
|
elapsed_time,
|
66
|
-
@end_time.try(:iso8601)
|
70
|
+
@end_time.try(:iso8601),
|
67
71
|
].compact.join(' - ')
|
68
72
|
end
|
69
73
|
|
70
|
-
|
74
|
+
private
|
71
75
|
|
72
76
|
def elapsed_time
|
73
77
|
(@start_time && @end_time ? "#{(@end_time - @start_time).round(4)}s" : nil)
|
@@ -2,7 +2,7 @@ module Protobuf
|
|
2
2
|
module Rpc
|
3
3
|
module Middleware
|
4
4
|
class RequestDecoder
|
5
|
-
include ::Protobuf::
|
5
|
+
include ::Protobuf::Logging
|
6
6
|
|
7
7
|
attr_reader :app, :env
|
8
8
|
|
@@ -11,8 +11,13 @@ module Protobuf
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def call(env)
|
14
|
+
dup._call(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
def _call(env)
|
14
18
|
@env = env
|
15
19
|
|
20
|
+
logger.debug { sign_message("Decoding request: #{env.encoded_request}") }
|
16
21
|
env.service_name = service_name
|
17
22
|
env.method_name = method_name
|
18
23
|
env.request = request
|
@@ -30,38 +35,29 @@ module Protobuf
|
|
30
35
|
env.log_signature || super
|
31
36
|
end
|
32
37
|
|
33
|
-
|
38
|
+
private
|
34
39
|
|
35
40
|
def method_name
|
36
|
-
@method_name
|
37
|
-
method_name = request_wrapper.method_name.underscore.to_sym
|
38
|
-
|
39
|
-
unless service.rpc_method?(method_name)
|
40
|
-
raise MethodNotFound.new("#{service.name}##{method_name} is not a defined RPC method.")
|
41
|
-
end
|
41
|
+
return @method_name unless @method_name.nil?
|
42
42
|
|
43
|
-
|
44
|
-
|
43
|
+
@method_name = request_wrapper.method_name.underscore.to_sym
|
44
|
+
fail MethodNotFound, "#{service.name}##{@method_name} is not a defined RPC method." unless service.rpc_method?(@method_name)
|
45
|
+
@method_name
|
45
46
|
end
|
46
47
|
|
47
48
|
def request
|
48
|
-
|
49
|
-
|
50
|
-
rpc_method.request_type.decode(data)
|
51
|
-
end
|
49
|
+
fail if request_wrapper.request_proto.blank?
|
50
|
+
@request ||= rpc_method.request_type.decode(request_wrapper.request_proto)
|
52
51
|
rescue => exception
|
53
|
-
raise BadRequestData
|
52
|
+
raise BadRequestData, "Unable to decode request: #{exception.message}"
|
54
53
|
end
|
55
54
|
|
56
55
|
# Decode the incoming request object into our expected request object
|
57
56
|
#
|
58
57
|
def request_wrapper
|
59
|
-
@request_wrapper ||=
|
60
|
-
log_debug { sign_message("Decoding request: #{env.encoded_request}") }
|
61
|
-
Socketrpc::Request.decode(env.encoded_request)
|
62
|
-
end
|
58
|
+
@request_wrapper ||= ::Protobuf::Socketrpc::Request.decode(env.encoded_request)
|
63
59
|
rescue => exception
|
64
|
-
raise BadRequestData
|
60
|
+
raise BadRequestData, "Unable to decode request: #{exception.message}"
|
65
61
|
end
|
66
62
|
|
67
63
|
def rpc_method
|
@@ -71,7 +67,7 @@ module Protobuf
|
|
71
67
|
def service
|
72
68
|
@service ||= service_name.constantize
|
73
69
|
rescue NameError
|
74
|
-
raise ServiceNotFound
|
70
|
+
raise ServiceNotFound, "Service class #{service_name} is not defined."
|
75
71
|
end
|
76
72
|
|
77
73
|
def service_name
|
@@ -2,7 +2,7 @@ module Protobuf
|
|
2
2
|
module Rpc
|
3
3
|
module Middleware
|
4
4
|
class ResponseEncoder
|
5
|
-
include ::Protobuf::
|
5
|
+
include ::Protobuf::Logging
|
6
6
|
|
7
7
|
attr_reader :app, :env
|
8
8
|
|
@@ -11,6 +11,10 @@ module Protobuf
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def call(env)
|
14
|
+
dup._call(env)
|
15
|
+
end
|
16
|
+
|
17
|
+
def _call(env)
|
14
18
|
@env = app.call(env)
|
15
19
|
|
16
20
|
env.response = response
|
@@ -22,12 +26,12 @@ module Protobuf
|
|
22
26
|
env.log_signature || super
|
23
27
|
end
|
24
28
|
|
25
|
-
|
29
|
+
private
|
26
30
|
|
27
31
|
# Encode the response wrapper to return to the client
|
28
32
|
#
|
29
33
|
def encoded_response
|
30
|
-
|
34
|
+
logger.debug { sign_message("Encoding response: #{response.inspect}") }
|
31
35
|
|
32
36
|
env.encoded_response = wrapped_response.encode
|
33
37
|
rescue => exception
|
@@ -35,38 +39,29 @@ module Protobuf
|
|
35
39
|
|
36
40
|
# Rescue encoding exceptions, re-wrap them as generic protobuf errors,
|
37
41
|
# and re-raise them
|
38
|
-
raise PbError
|
42
|
+
raise PbError, exception.message
|
39
43
|
end
|
40
44
|
|
41
45
|
# Prod the object to see if we can produce a proto object as a response
|
42
46
|
# candidate. Validate the candidate protos.
|
43
47
|
def response
|
44
|
-
@response
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
when candidate.is_a?(PbError) then
|
54
|
-
candidate
|
55
|
-
else
|
56
|
-
validate!(candidate)
|
57
|
-
end
|
58
|
-
end
|
48
|
+
return @response unless @response.nil?
|
49
|
+
|
50
|
+
candidate = env.response
|
51
|
+
return @response = validate!(candidate) if candidate.is_a?(Message)
|
52
|
+
return @response = validate!(candidate.to_proto) if candidate.respond_to?(:to_proto)
|
53
|
+
return @response = env.response_type.new(candidate.to_hash) if candidate.respond_to?(:to_hash)
|
54
|
+
return @response = candidate if candidate.is_a?(PbError)
|
55
|
+
|
56
|
+
@response = validate!(candidate)
|
59
57
|
end
|
60
58
|
|
61
59
|
# Ensure that the response candidate we've been given is of the type
|
62
60
|
# we expect so that deserialization on the client side works.
|
63
61
|
#
|
64
62
|
def validate!(candidate)
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
if expected != actual
|
69
|
-
raise BadResponseProto.new("Expected response to be of type #{expected.name} but was #{actual.name}")
|
63
|
+
if candidate.class != env.response_type
|
64
|
+
fail BadResponseProto, "Expected response to be of type #{env.response_type.name} but was #{candidate.class.name}"
|
70
65
|
end
|
71
66
|
|
72
67
|
candidate
|
@@ -76,10 +71,10 @@ module Protobuf
|
|
76
71
|
# it up so that it's in the correct spot in the response wrapper
|
77
72
|
#
|
78
73
|
def wrapped_response
|
79
|
-
if response.is_a?(Protobuf::Rpc::PbError)
|
80
|
-
Socketrpc::Response.new(:error => response.message, :error_reason => response.error_type)
|
74
|
+
if response.is_a?(::Protobuf::Rpc::PbError)
|
75
|
+
::Protobuf::Socketrpc::Response.new(:error => response.message, :error_reason => response.error_type)
|
81
76
|
else
|
82
|
-
Socketrpc::Response.new(:response_proto => response.encode)
|
77
|
+
::Protobuf::Socketrpc::Response.new(:response_proto => response.encode)
|
83
78
|
end
|
84
79
|
end
|
85
80
|
end
|
@@ -4,6 +4,8 @@ module Protobuf
|
|
4
4
|
module Rpc
|
5
5
|
module Middleware
|
6
6
|
class Statsd
|
7
|
+
include ::Protobuf::Logging
|
8
|
+
|
7
9
|
def initialize(app)
|
8
10
|
@app = app
|
9
11
|
end
|
@@ -23,8 +25,6 @@ module Protobuf
|
|
23
25
|
def statsd_base_path(env)
|
24
26
|
if env.service_name && env.method_name
|
25
27
|
"rpc-server.#{env.service_name}.#{env.method_name}".gsub('::', '.').downcase
|
26
|
-
else
|
27
|
-
nil
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -46,7 +46,7 @@ module Protobuf
|
|
46
46
|
statsd_client.timing("#{path}.time", end_time - start_time)
|
47
47
|
rescue => e
|
48
48
|
# We insert ourself after Exception handler, so no exceptions allowed!
|
49
|
-
|
49
|
+
logger.warn { "Error with Statsd middleware: #{e.message}" }
|
50
50
|
end
|
51
51
|
private :record_stats
|
52
52
|
end
|
data/lib/protobuf/rpc/rpc.pb.rb
CHANGED
@@ -1,10 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
1
3
|
##
|
2
4
|
# This file is auto-generated. DO NOT EDIT!
|
3
5
|
#
|
4
|
-
require 'protobuf
|
6
|
+
require 'protobuf'
|
5
7
|
|
6
8
|
module Protobuf
|
7
9
|
module Socketrpc
|
10
|
+
::Protobuf::Optionable.inject(self) { ::Google::Protobuf::FileOptions }
|
8
11
|
|
9
12
|
##
|
10
13
|
# Enum Classes
|
data/lib/protobuf/rpc/server.rb
CHANGED
@@ -8,7 +8,7 @@ module Protobuf
|
|
8
8
|
module Http
|
9
9
|
class Server
|
10
10
|
include ::Protobuf::Rpc::Server
|
11
|
-
include ::Protobuf::
|
11
|
+
include ::Protobuf::Logging
|
12
12
|
|
13
13
|
# TODO: more comprehensive mapping?
|
14
14
|
HTTP_STATUSES = {
|
@@ -24,8 +24,8 @@ module Protobuf
|
|
24
24
|
Protobuf::Socketrpc::ErrorReason::INVALID_REQUEST_PROTO => 500,
|
25
25
|
Protobuf::Socketrpc::ErrorReason::BAD_RESPONSE_PROTO => 500,
|
26
26
|
Protobuf::Socketrpc::ErrorReason::UNKNOWN_HOST => 500,
|
27
|
-
Protobuf::Socketrpc::ErrorReason::IO_ERROR => 500
|
28
|
-
}
|
27
|
+
Protobuf::Socketrpc::ErrorReason::IO_ERROR => 500,
|
28
|
+
}.freeze
|
29
29
|
|
30
30
|
def initialize(options = {})
|
31
31
|
@options = options
|
@@ -36,11 +36,13 @@ module Protobuf
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def call(env)
|
39
|
-
path_components = env['PATH_INFO'].split("/")
|
39
|
+
path_components = env['PATH_INFO'].split("/")
|
40
|
+
.map { |x| CGI.unescape(x) }
|
41
|
+
.compact.reject(&:empty?)
|
40
42
|
if path_components.length < 2
|
41
43
|
return protobuf_http_response 400,
|
42
|
-
|
43
|
-
|
44
|
+
:error => "Expected path format /CLASS/METHOD",
|
45
|
+
:reason => Protobuf::Socketrpc::ErrorReason::INVALID_REQUEST_PROTO
|
44
46
|
end
|
45
47
|
|
46
48
|
service_name = path_components[0..-2].join("::")
|
@@ -53,26 +55,26 @@ module Protobuf
|
|
53
55
|
:caller => env['HTTP_X_PROTOBUF_CALLER'] || ''
|
54
56
|
)
|
55
57
|
|
56
|
-
encoded_request = rpc_request.encode
|
58
|
+
encoded_request = rpc_request.encode
|
57
59
|
|
58
60
|
begin
|
59
61
|
encoded_response = handle_request(encoded_request, env)
|
60
|
-
rescue
|
62
|
+
rescue StandardError => e
|
61
63
|
return protobuf_http_response 500,
|
62
|
-
|
63
|
-
|
64
|
+
:error => "Handle request failed: #{e}",
|
65
|
+
:reason => Protobuf::Socketrpc::ErrorReason::RPC_ERROR
|
64
66
|
end
|
65
67
|
|
66
68
|
rpc_response = Protobuf::Socketrpc::Response.decode(encoded_response)
|
67
69
|
|
68
|
-
if rpc_response[:error].
|
69
|
-
status = HTTP_STATUSES[rpc_response[:error_reason]]
|
70
|
+
if rpc_response[:error].present?
|
71
|
+
status = HTTP_STATUSES[rpc_response[:error_reason]] || 500
|
70
72
|
return protobuf_http_response status,
|
71
|
-
|
72
|
-
|
73
|
+
:error => rpc_response[:error],
|
74
|
+
:reason => rpc_response[:error_reason]
|
73
75
|
end
|
74
|
-
|
75
|
-
|
76
|
+
|
77
|
+
protobuf_http_response 200, :body => rpc_response['response_proto']
|
76
78
|
end
|
77
79
|
|
78
80
|
def protobuf_http_response(status, options)
|
@@ -93,7 +95,7 @@ module Protobuf
|
|
93
95
|
end
|
94
96
|
|
95
97
|
def running?
|
96
|
-
!!@running
|
98
|
+
!!@running # rubocop:disable Style/DoubleNegation
|
97
99
|
end
|
98
100
|
|
99
101
|
def stop
|