Skip to content

Commit 5fe28c6

Browse files
authored
Added thrift serialization to JsonDataConverter (#146)
* Added thrift serialization to JsonDataConverter * license and minor bug * Changed ThriftSerializer to create a new instance per request as it is not thread safe * PR comments
1 parent 1d6385c commit 5fe28c6

File tree

2 files changed

+83
-2
lines changed

2 files changed

+83
-2
lines changed

src/main/java/com/uber/cadence/converter/JsonDataConverter.java

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,17 @@
3838
import java.util.function.Function;
3939
import java.util.regex.Matcher;
4040
import java.util.regex.Pattern;
41+
import org.apache.thrift.TBase;
42+
import org.apache.thrift.TDeserializer;
43+
import org.apache.thrift.TSerializer;
44+
import org.apache.thrift.protocol.TJSONProtocol;
4145
import org.slf4j.Logger;
4246
import org.slf4j.LoggerFactory;
4347

4448
/**
4549
* Implements conversion through GSON JSON processor. To extend use {@link
46-
* JsonDataConverter(Function)} constructor.
50+
* JsonDataConverter(Function)} constructor. Thrift structures are converted using {@link
51+
* TJSONProtocol}. When using thrift only one argument of a method is expected.
4752
*
4853
* @author fateev
4954
*/
@@ -113,7 +118,12 @@ public byte[] toData(Object... values) throws DataConverterException {
113118
}
114119
try {
115120
if (values.length == 1) {
116-
String json = gson.toJson(values[0]);
121+
Object value = values[0];
122+
// Serialize thrift objects using Thrift serializer
123+
if (value instanceof TBase) {
124+
return newThriftSerializer().toString((TBase) value).getBytes(StandardCharsets.UTF_8);
125+
}
126+
String json = gson.toJson(value);
117127
return json.getBytes(StandardCharsets.UTF_8);
118128
}
119129
String json = gson.toJson(values);
@@ -129,6 +139,12 @@ public <T> T fromData(byte[] content, Class<T> valueType) throws DataConverterEx
129139
return null;
130140
}
131141
try {
142+
// Deserialize thrift values.
143+
if (TBase.class.isAssignableFrom(valueType)) {
144+
T instance = valueType.getConstructor().newInstance();
145+
newThriftDeserializer().deserialize((TBase) instance, content);
146+
return instance;
147+
}
132148
return gson.fromJson(new String(content, StandardCharsets.UTF_8), valueType);
133149
} catch (Exception e) {
134150
throw new DataConverterException(content, e);
@@ -165,6 +181,7 @@ public Object[] fromDataArray(byte[] content, Class<?>... valueType)
165181
* <p>Implementation idea is based on https://github.com/google/gson/issues/43
166182
*/
167183
private static class ThrowableTypeAdapterFactory implements TypeAdapterFactory {
184+
168185
@Override
169186
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
170187
// Special handling of fields of DataConverter type.
@@ -307,4 +324,12 @@ private static StackTraceElement parseStackTraceElement(String line) {
307324
}
308325
return new StackTraceElement(declaringClass, methodName, fileName, lineNumber);
309326
}
327+
328+
private static TSerializer newThriftSerializer() {
329+
return new TSerializer(new TJSONProtocol.Factory());
330+
}
331+
332+
private static TDeserializer newThriftDeserializer() {
333+
return new TDeserializer(new TJSONProtocol.Factory());
334+
}
310335
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Modifications copyright (C) 2017 Uber Technologies, Inc.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not
7+
* use this file except in compliance with the License. A copy of the License is
8+
* located at
9+
*
10+
* http://aws.amazon.com/apache2.0
11+
*
12+
* or in the "license" file accompanying this file. This file is distributed on
13+
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14+
* express or implied. See the License for the specific language governing
15+
* permissions and limitations under the License.
16+
*/
17+
18+
package com.uber.cadence.converter;
19+
20+
import static org.junit.Assert.*;
21+
22+
import com.uber.cadence.History;
23+
import com.uber.cadence.HistoryEvent;
24+
import com.uber.cadence.TaskList;
25+
import com.uber.cadence.WorkflowExecutionStartedEventAttributes;
26+
import com.uber.cadence.WorkflowType;
27+
import java.nio.charset.StandardCharsets;
28+
import java.util.ArrayList;
29+
import java.util.List;
30+
import org.junit.Test;
31+
32+
public class JsonDataConverterTest {
33+
34+
private final DataConverter converter = JsonDataConverter.getInstance();
35+
36+
@Test
37+
public void testThrift() {
38+
List<HistoryEvent> events = new ArrayList<>();
39+
WorkflowExecutionStartedEventAttributes started =
40+
new WorkflowExecutionStartedEventAttributes()
41+
.setExecutionStartToCloseTimeoutSeconds(11)
42+
.setIdentity("testIdentity")
43+
.setInput("input".getBytes(StandardCharsets.UTF_8))
44+
.setWorkflowType(new WorkflowType().setName("workflowType1"))
45+
.setTaskList(new TaskList().setName("taskList1"));
46+
events.add(
47+
new HistoryEvent()
48+
.setTimestamp(1234567)
49+
.setEventId(321)
50+
.setWorkflowExecutionStartedEventAttributes(started));
51+
History history = new History().setEvents(events);
52+
byte[] converted = converter.toData(history);
53+
History fromConverted = converter.fromData(converted, History.class);
54+
assertEquals(new String(converted, StandardCharsets.UTF_8), history, fromConverted);
55+
}
56+
}

0 commit comments

Comments
 (0)