From 333eb173e3174cd538b3168cdc45a0cedfd4b13a Mon Sep 17 00:00:00 2001 From: John Stuppy Date: Tue, 6 Sep 2022 13:14:50 -0500 Subject: [PATCH 1/2] Adds ProtoJSON support for protobuf inputs --- lib/temporal/configuration.rb | 2 + .../converter/payload/proto_json.rb | 37 +++++++++++++++++++ .../converter/payload/proto_json_spec.rb | 22 +++++++++++ 3 files changed, 61 insertions(+) create mode 100644 lib/temporal/connection/converter/payload/proto_json.rb create mode 100644 spec/unit/lib/temporal/connection/converter/payload/proto_json_spec.rb diff --git a/lib/temporal/configuration.rb b/lib/temporal/configuration.rb index 99e582a2..b93c9dbb 100644 --- a/lib/temporal/configuration.rb +++ b/lib/temporal/configuration.rb @@ -3,6 +3,7 @@ require 'temporal/connection/converter/payload/nil' require 'temporal/connection/converter/payload/bytes' require 'temporal/connection/converter/payload/json' +require 'temporal/connection/converter/payload/proto_json' require 'temporal/connection/converter/composite' module Temporal @@ -39,6 +40,7 @@ class Configuration payload_converters: [ Temporal::Connection::Converter::Payload::Nil.new, Temporal::Connection::Converter::Payload::Bytes.new, + Temporal::Connection::Converter::Payload::ProtoJSON.new, Temporal::Connection::Converter::Payload::JSON.new, ] ).freeze diff --git a/lib/temporal/connection/converter/payload/proto_json.rb b/lib/temporal/connection/converter/payload/proto_json.rb new file mode 100644 index 00000000..423fa588 --- /dev/null +++ b/lib/temporal/connection/converter/payload/proto_json.rb @@ -0,0 +1,37 @@ +require 'temporal/json' + +module Temporal + module Connection + module Converter + module Payload + class ProtoJSON + class InvalidPayload < RuntimeError; end + + ENCODING = 'json/protobuf'.freeze + + def encoding + ENCODING + end + + def from_payload(payload) + # TODO: Add error handling. + message_type = payload.metadata['messageType'] + descriptor = Google::Protobuf::DescriptorPool.generated_pool.lookup(message_type) + descriptor.msgclass.decode_json(payload.data) + end + + def to_payload(data) + return unless data&.is_a?(Google::Protobuf::MessageExts) + Temporal::Api::Common::V1::Payload.new( + metadata: { + 'encoding' => ENCODING, + 'messageType' => data.class.descriptor.name, + }, + data: data.to_json, + ) + end + end + end + end + end +end diff --git a/spec/unit/lib/temporal/connection/converter/payload/proto_json_spec.rb b/spec/unit/lib/temporal/connection/converter/payload/proto_json_spec.rb new file mode 100644 index 00000000..757fc82f --- /dev/null +++ b/spec/unit/lib/temporal/connection/converter/payload/proto_json_spec.rb @@ -0,0 +1,22 @@ +require 'temporal/connection/converter/payload/json' + +describe Temporal::Connection::Converter::Payload::ProtoJSON do + subject { described_class.new } + + describe 'round trip' do + it 'converts' do + input = Temporal::Api::Common::V1::Payload.new( + metadata: { 'hello' => 'world' }, + data: 'hello world', + ) + + expect(subject.from_payload(subject.to_payload(input))).to eq(input) + end + end + + it 'skips if not proto message' do + input = { hello: 'world' } + + expect(subject.to_payload(input)).to be nil + end +end From 50a4f8671bb2986006b2a1f1ac33ebd6ca8b0c29 Mon Sep 17 00:00:00 2001 From: John Stuppy Date: Fri, 9 Sep 2022 11:38:08 -0500 Subject: [PATCH 2/2] review feedback update --- lib/temporal/connection/converter/payload/proto_json.rb | 4 +--- .../temporal/connection/converter/payload/proto_json_spec.rb | 5 ++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/temporal/connection/converter/payload/proto_json.rb b/lib/temporal/connection/converter/payload/proto_json.rb index 423fa588..994c1e24 100644 --- a/lib/temporal/connection/converter/payload/proto_json.rb +++ b/lib/temporal/connection/converter/payload/proto_json.rb @@ -5,8 +5,6 @@ module Connection module Converter module Payload class ProtoJSON - class InvalidPayload < RuntimeError; end - ENCODING = 'json/protobuf'.freeze def encoding @@ -21,7 +19,7 @@ def from_payload(payload) end def to_payload(data) - return unless data&.is_a?(Google::Protobuf::MessageExts) + return unless data.is_a?(Google::Protobuf::MessageExts) Temporal::Api::Common::V1::Payload.new( metadata: { 'encoding' => ENCODING, diff --git a/spec/unit/lib/temporal/connection/converter/payload/proto_json_spec.rb b/spec/unit/lib/temporal/connection/converter/payload/proto_json_spec.rb index 757fc82f..5570d9df 100644 --- a/spec/unit/lib/temporal/connection/converter/payload/proto_json_spec.rb +++ b/spec/unit/lib/temporal/connection/converter/payload/proto_json_spec.rb @@ -1,10 +1,13 @@ -require 'temporal/connection/converter/payload/json' +require 'temporal/connection/converter/payload/proto_json' describe Temporal::Connection::Converter::Payload::ProtoJSON do subject { described_class.new } describe 'round trip' do it 'converts' do + # Temporal::Api::Common::V1::Payload is a protobuf. + # Using it as the "input" here to show the roundtrip. + # #to_payload will return a wrapped Payload around this one. input = Temporal::Api::Common::V1::Payload.new( metadata: { 'hello' => 'world' }, data: 'hello world',