Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions lib/temporal/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
35 changes: 35 additions & 0 deletions lib/temporal/connection/converter/payload/proto_json.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
require 'temporal/json'

module Temporal
module Connection
module Converter
module Payload
class ProtoJSON
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
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',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This data type won't get picked by the target converter, right? It's not a subclass of Google::Protobuf::MessageExts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added comment. using Temporal::Api::Common::V1::Payload as the input given it's an available proto message. to_payload wraps it, so the result data is the json'd input w/ the metadata

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see, makes sense. It might be a bit clearer if you were to pick a proto that has nothing to do with payloads. But the comment solves this issue

)

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