From 7871a30df0680ab3ca7dda905cd1221ec2da1841 Mon Sep 17 00:00:00 2001 From: Shijie Sheng Date: Fri, 30 May 2025 14:09:10 -0700 Subject: [PATCH 1/3] remove raw history (#1004) What changed? Remove raw history support in client Why? History is stored as Thrift encoded binary. Sending raw history in Thrift will no longer be supported in V4 How did you test it? Unit Test --- .../internal/common/InternalUtils.java | 97 ---------------- .../shadowing/ReplayWorkflowActivityImpl.java | 13 +-- .../testservice/TestWorkflowStoreImpl.java | 8 +- .../WorkflowServiceTChannel.java | 13 +-- .../internal/common/InternalUtilsTest.java | 106 ------------------ .../shadowing/ReplayWorkflowActivityTest.java | 20 ++-- 6 files changed, 20 insertions(+), 237 deletions(-) diff --git a/src/main/java/com/uber/cadence/internal/common/InternalUtils.java b/src/main/java/com/uber/cadence/internal/common/InternalUtils.java index 520d8efbb..e5b4b330b 100644 --- a/src/main/java/com/uber/cadence/internal/common/InternalUtils.java +++ b/src/main/java/com/uber/cadence/internal/common/InternalUtils.java @@ -18,11 +18,6 @@ package com.uber.cadence.internal.common; import com.google.common.base.Defaults; -import com.google.common.collect.Lists; -import com.uber.cadence.DataBlob; -import com.uber.cadence.History; -import com.uber.cadence.HistoryEvent; -import com.uber.cadence.HistoryEventFilterType; import com.uber.cadence.Memo; import com.uber.cadence.SearchAttributes; import com.uber.cadence.TaskList; @@ -33,15 +28,10 @@ import com.uber.cadence.workflow.WorkflowMethod; import java.lang.reflect.Method; import java.nio.ByteBuffer; -import java.util.Arrays; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; -import org.apache.thrift.TDeserializer; -import org.apache.thrift.TException; -import org.apache.thrift.TSerializer; /** Utility functions shared by the implementation code. */ public final class InternalUtils { @@ -164,93 +154,6 @@ public static SearchAttributes convertMapToSearchAttributes( return new SearchAttributes().setIndexedFields(mapOfByteBuffer); } - // This method serializes history to blob data - public static DataBlob SerializeFromHistoryToBlobData(History history) { - - // TODO: move to global dependency after https://issues.apache.org/jira/browse/THRIFT-2218 - TSerializer serializer = new TSerializer(); - DataBlob blob = new DataBlob(); - try { - blob.setData(serializer.serialize(history)); - } catch (org.apache.thrift.TException err) { - throw new RuntimeException("Serialize history to blob data failed", err); - } - - return blob; - } - - // This method deserialize the DataBlob data to the History data - public static History DeserializeFromBlobDataToHistory( - List blobData, HistoryEventFilterType historyEventFilterType) throws TException { - - // TODO: move to global dependency after https://issues.apache.org/jira/browse/THRIFT-2218 - TDeserializer deSerializer = new TDeserializer(); - List events = Lists.newArrayList(); - for (DataBlob data : blobData) { - History history = new History(); - try { - byte[] dataByte = data.getData(); - // TODO: verify the beginning index - dataByte = Arrays.copyOfRange(dataByte, 0, dataByte.length); - deSerializer.deserialize(history, dataByte); - - if (history == null || history.getEvents() == null || history.getEvents().size() == 0) { - return null; - } - } catch (org.apache.thrift.TException err) { - throw new TException("Deserialize blob data to history failed with unknown error"); - } - - events.addAll(history.getEvents()); - } - - if (events.size() > 0 && historyEventFilterType == HistoryEventFilterType.CLOSE_EVENT) { - events = events.subList(events.size() - 1, events.size()); - } - - return new History().setEvents(events); - } - - // This method serializes history event to blob data - public static List SerializeFromHistoryEventToBlobData(List events) { - - // TODO: move to global dependency after https://issues.apache.org/jira/browse/THRIFT-2218 - TSerializer serializer = new TSerializer(); - List blobs = Lists.newArrayListWithCapacity(events.size()); - for (HistoryEvent event : events) { - DataBlob blob = new DataBlob(); - try { - blob.setData(serializer.serialize(event)); - } catch (org.apache.thrift.TException err) { - throw new RuntimeException("Serialize history event to blob data failed", err); - } - blobs.add(blob); - } - return blobs; - } - - // This method serializes blob data to history event - public static List DeserializeFromBlobDataToHistoryEvents(List blobData) - throws TException { - - // TODO: move to global dependency after https://issues.apache.org/jira/browse/THRIFT-2218 - TDeserializer deSerializer = new TDeserializer(); - List events = Lists.newArrayList(); - for (DataBlob data : blobData) { - try { - HistoryEvent event = new HistoryEvent(); - byte[] dataByte = data.getData(); - // TODO: verify the beginning index - dataByte = Arrays.copyOfRange(dataByte, 0, dataByte.length); - deSerializer.deserialize(event, dataByte); - events.add(event); - } catch (org.apache.thrift.TException err) { - throw new TException("Deserialize blob data to history event failed with unknown error"); - } - } - return events; - } - /** Prohibit instantiation */ private InternalUtils() {} } diff --git a/src/main/java/com/uber/cadence/internal/shadowing/ReplayWorkflowActivityImpl.java b/src/main/java/com/uber/cadence/internal/shadowing/ReplayWorkflowActivityImpl.java index d2432889f..eae82edb0 100644 --- a/src/main/java/com/uber/cadence/internal/shadowing/ReplayWorkflowActivityImpl.java +++ b/src/main/java/com/uber/cadence/internal/shadowing/ReplayWorkflowActivityImpl.java @@ -19,12 +19,9 @@ import com.google.common.collect.Lists; import com.uber.cadence.GetWorkflowExecutionHistoryResponse; -import com.uber.cadence.History; import com.uber.cadence.HistoryEvent; -import com.uber.cadence.HistoryEventFilterType; import com.uber.cadence.activity.Activity; import com.uber.cadence.common.WorkflowExecutionHistory; -import com.uber.cadence.internal.common.InternalUtils; import com.uber.cadence.internal.common.RpcRetryer; import com.uber.cadence.internal.common.WorkflowExecutionUtils; import com.uber.cadence.internal.metrics.MetricsType; @@ -185,14 +182,10 @@ protected WorkflowExecutionHistory getFullHistory(String domain, WorkflowExecuti nextPageToken, this.serviceClient, domain, execution.toThrift())); pageToken = resp.getNextPageToken(); - // handle raw history + // TODO support raw history feature once server removes default Thrift encoding if (resp.getRawHistory() != null && resp.getRawHistory().size() > 0) { - History history = - InternalUtils.DeserializeFromBlobDataToHistory( - resp.getRawHistory(), HistoryEventFilterType.ALL_EVENT); - if (history != null && history.getEvents() != null) { - histories.addAll(history.getEvents()); - } + throw new UnsupportedOperationException( + "Raw history is not supported. Please turn off frontend.sendRawWorkflowHistory feature flag in frontend service to recover"); } else { histories.addAll(resp.getHistory().getEvents()); } diff --git a/src/main/java/com/uber/cadence/internal/testservice/TestWorkflowStoreImpl.java b/src/main/java/com/uber/cadence/internal/testservice/TestWorkflowStoreImpl.java index 5759f4562..06f18eab2 100644 --- a/src/main/java/com/uber/cadence/internal/testservice/TestWorkflowStoreImpl.java +++ b/src/main/java/com/uber/cadence/internal/testservice/TestWorkflowStoreImpl.java @@ -18,7 +18,6 @@ package com.uber.cadence.internal.testservice; import com.uber.cadence.BadRequestError; -import com.uber.cadence.DataBlob; import com.uber.cadence.EntityNotExistsError; import com.uber.cadence.EventType; import com.uber.cadence.GetWorkflowExecutionHistoryRequest; @@ -34,7 +33,6 @@ import com.uber.cadence.StickyExecutionAttributes; import com.uber.cadence.WorkflowExecution; import com.uber.cadence.WorkflowExecutionInfo; -import com.uber.cadence.internal.common.InternalUtils; import com.uber.cadence.internal.common.WorkflowExecutionUtils; import com.uber.cadence.internal.testservice.RequestContext.Timer; import java.time.Duration; @@ -348,12 +346,10 @@ public GetWorkflowExecutionHistoryResponse getWorkflowExecutionHistory( if (!getRequest.isWaitForNewEvent() && getRequest.getHistoryEventFilterType() != HistoryEventFilterType.CLOSE_EVENT) { List events = history.getEventsLocked(); - List blobs = InternalUtils.SerializeFromHistoryEventToBlobData(events); // Copy the list as it is mutable. Individual events assumed immutable. ArrayList eventsCopy = new ArrayList<>(events); return new GetWorkflowExecutionHistoryResponse() - .setHistory(new History().setEvents(eventsCopy)) - .setRawHistory(blobs); + .setHistory(new History().setEvents(eventsCopy)); } expectedNextEventId = history.getNextEventIdLocked(); } finally { @@ -361,11 +357,9 @@ public GetWorkflowExecutionHistoryResponse getWorkflowExecutionHistory( } List events = history.waitForNewEvents(expectedNextEventId, getRequest.getHistoryEventFilterType()); - List blobs = InternalUtils.SerializeFromHistoryEventToBlobData(events); GetWorkflowExecutionHistoryResponse result = new GetWorkflowExecutionHistoryResponse(); if (events != null) { result.setHistory(new History().setEvents(events)); - result.setRawHistory(blobs); } return result; } diff --git a/src/main/java/com/uber/cadence/serviceclient/WorkflowServiceTChannel.java b/src/main/java/com/uber/cadence/serviceclient/WorkflowServiceTChannel.java index 2878e6fac..7c45bb8ca 100644 --- a/src/main/java/com/uber/cadence/serviceclient/WorkflowServiceTChannel.java +++ b/src/main/java/com/uber/cadence/serviceclient/WorkflowServiceTChannel.java @@ -28,7 +28,6 @@ import com.uber.cadence.WorkflowService.GetWorkflowExecutionHistory_result; import com.uber.cadence.internal.Version; import com.uber.cadence.internal.common.CheckedExceptionWrapper; -import com.uber.cadence.internal.common.InternalUtils; import com.uber.cadence.internal.metrics.MetricsTag; import com.uber.cadence.internal.metrics.MetricsType; import com.uber.cadence.internal.metrics.ServiceMethod; @@ -766,10 +765,8 @@ private GetWorkflowExecutionHistoryResponse getWorkflowExecutionHistory( if (response.getResponseCode() == ResponseCode.OK) { GetWorkflowExecutionHistoryResponse res = result.getSuccess(); if (res.getRawHistory() != null) { - History history = - InternalUtils.DeserializeFromBlobDataToHistory( - res.getRawHistory(), getRequest.getHistoryEventFilterType()); - res.setHistory(history); + throw new TException( + "Raw history is not supported. Please turn off frontend.sendRawWorkflowHistory feature flag in frontend service to recover"); } return res; } @@ -2593,10 +2590,8 @@ private void getWorkflowExecutionHistory( if (r.getResponseCode() == ResponseCode.OK) { GetWorkflowExecutionHistoryResponse res = result.getSuccess(); if (res.getRawHistory() != null) { - History history = - InternalUtils.DeserializeFromBlobDataToHistory( - res.getRawHistory(), getRequest.getHistoryEventFilterType()); - res.setHistory(history); + throw new TException( + "Raw history is not supported. Please turn off frontend.sendRawWorkflowHistory feature flag in frontend service to recover"); } resultHandler.onComplete(res); return; diff --git a/src/test/java/com/uber/cadence/internal/common/InternalUtilsTest.java b/src/test/java/com/uber/cadence/internal/common/InternalUtilsTest.java index 23ecb652c..eb6250adf 100644 --- a/src/test/java/com/uber/cadence/internal/common/InternalUtilsTest.java +++ b/src/test/java/com/uber/cadence/internal/common/InternalUtilsTest.java @@ -17,23 +17,14 @@ package com.uber.cadence.internal.common; -import static com.uber.cadence.EventType.WorkflowExecutionStarted; import static junit.framework.TestCase.assertEquals; -import static org.junit.Assert.assertNotNull; -import com.google.common.collect.Lists; -import com.googlecode.junittoolbox.MultithreadingTester; -import com.googlecode.junittoolbox.RunnableAssert; import com.uber.cadence.*; import com.uber.cadence.converter.DataConverterException; import com.uber.cadence.workflow.WorkflowUtils; import java.io.FileOutputStream; -import java.time.LocalDateTime; -import java.time.ZoneOffset; import java.util.HashMap; -import java.util.List; import java.util.Map; -import junit.framework.TestCase; import org.junit.Test; public class InternalUtilsTest { @@ -56,101 +47,4 @@ public void testConvertMapToSearchAttributesException() throws Throwable { attr.put("InvalidValue", new FileOutputStream("dummy")); InternalUtils.convertMapToSearchAttributes(attr); } - - @Test - public void testSerialization_History() { - - RunnableAssert r = - new RunnableAssert("history_serialization") { - @Override - public void run() { - HistoryEvent event = - new HistoryEvent() - .setEventId(1) - .setVersion(1) - .setEventType(WorkflowExecutionStarted) - .setTimestamp(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)) - .setWorkflowExecutionStartedEventAttributes( - new WorkflowExecutionStartedEventAttributes() - .setAttempt(1) - .setFirstExecutionRunId("test")); - - List historyEvents = Lists.newArrayList(event); - History history = new History().setEvents(historyEvents); - DataBlob blob = InternalUtils.SerializeFromHistoryToBlobData(history); - assertNotNull(blob); - - try { - History result = - InternalUtils.DeserializeFromBlobDataToHistory( - Lists.newArrayList(blob), HistoryEventFilterType.ALL_EVENT); - assertNotNull(result); - assertEquals(1, result.events.size()); - assertEquals(event.getEventId(), result.events.get(0).getEventId()); - assertEquals(event.getVersion(), result.events.get(0).getVersion()); - assertEquals(event.getEventType(), result.events.get(0).getEventType()); - assertEquals(event.getTimestamp(), result.events.get(0).getTimestamp()); - assertEquals( - event.getWorkflowExecutionStartedEventAttributes(), - result.events.get(0).getWorkflowExecutionStartedEventAttributes()); - } catch (Exception e) { - TestCase.fail("Received unexpected error during deserialization"); - } - } - }; - - try { - new MultithreadingTester().add(r).numThreads(50).numRoundsPerThread(10).run(); - } catch (Exception e) { - TestCase.fail("Received unexpected error during concurrent deserialization"); - } - } - - @Test - public void testSerialization_HistoryEvent() { - - RunnableAssert r = - new RunnableAssert("history_event_serialization") { - @Override - public void run() { - HistoryEvent event = - new HistoryEvent() - .setEventId(1) - .setVersion(1) - .setEventType(WorkflowExecutionStarted) - .setTimestamp(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC)) - .setWorkflowExecutionStartedEventAttributes( - new WorkflowExecutionStartedEventAttributes() - .setAttempt(1) - .setFirstExecutionRunId("test")); - - List historyEvents = Lists.newArrayList(event); - List blobList = - InternalUtils.SerializeFromHistoryEventToBlobData(historyEvents); - assertEquals(1, blobList.size()); - - try { - List result = - InternalUtils.DeserializeFromBlobDataToHistoryEvents(blobList); - assertNotNull(result); - assertEquals(1, result.size()); - assertEquals(event.getEventId(), result.get(0).getEventId()); - assertEquals(event.getVersion(), result.get(0).getVersion()); - assertEquals(event.getEventType(), result.get(0).getEventType()); - assertEquals(event.getTimestamp(), result.get(0).getTimestamp()); - assertEquals( - event.getWorkflowExecutionStartedEventAttributes(), - result.get(0).getWorkflowExecutionStartedEventAttributes()); - } catch (Exception e) { - TestCase.fail("Received unexpected error during deserialization"); - } - } - }; - - try { - new MultithreadingTester().add(r).numThreads(50).numRoundsPerThread(10).run(); - } catch (Exception e) { - TestCase.fail("Received unexpected error during concurrent deserialization"); - } - } } diff --git a/src/test/java/com/uber/cadence/internal/shadowing/ReplayWorkflowActivityTest.java b/src/test/java/com/uber/cadence/internal/shadowing/ReplayWorkflowActivityTest.java index 4e1df82c3..ed17dc8fd 100644 --- a/src/test/java/com/uber/cadence/internal/shadowing/ReplayWorkflowActivityTest.java +++ b/src/test/java/com/uber/cadence/internal/shadowing/ReplayWorkflowActivityTest.java @@ -20,9 +20,7 @@ import static com.uber.cadence.EventType.DecisionTaskStarted; import static com.uber.cadence.EventType.TimerStarted; import static com.uber.cadence.EventType.WorkflowExecutionStarted; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -42,7 +40,6 @@ import com.uber.cadence.WorkflowType; import com.uber.cadence.common.WorkflowExecutionHistory; import com.uber.cadence.converter.JsonDataConverter; -import com.uber.cadence.internal.common.InternalUtils; import com.uber.cadence.internal.testing.WorkflowTestingTest; import com.uber.cadence.serviceclient.IWorkflowService; import com.uber.cadence.testing.TestActivityEnvironment; @@ -144,15 +141,22 @@ public void testGetFullHistory_DecodedHistory_ExpectedSuccessResponse() throws E } @Test - public void testGetFullHistory_RawHistory_ExpectedSuccessResponse() throws Exception { + public void testGetFullHistory_RawHistory_NotSupportedError() throws Exception { History history = new History().setEvents(Lists.newArrayList(historyEvents.get(0))); - DataBlob blob = InternalUtils.SerializeFromHistoryToBlobData(history); + DataBlob blob = new DataBlob().setData(new byte[] {1, 2, 3}); GetWorkflowExecutionHistoryResponse response = new GetWorkflowExecutionHistoryResponse().setRawHistory(Lists.newArrayList(blob)); when(mockServiceClient.GetWorkflowExecutionHistory(any())).thenReturn(response); - WorkflowExecutionHistory result = activity.getFullHistory(domain, execution); - assertEquals(1, result.getEvents().size()); + try { + WorkflowExecutionHistory result = activity.getFullHistory(domain, execution); + } catch (Exception e) { + assertEquals( + "Raw history is not supported. Please turn off frontend.sendRawWorkflowHistory feature flag in frontend service to recover", + e.getMessage()); + return; + } + fail("Expected exception not thrown"); } @Test(expected = Error.class) From 011776cb508121af4b03a3d44429ac8f401ba86e Mon Sep 17 00:00:00 2001 From: Shijie Sheng Date: Thu, 5 Jun 2025 09:28:58 -0700 Subject: [PATCH 2/3] remove Thrift dataconverter support --- .../cadence/converter/JsonDataConverter.java | 7 +- .../converter/TBaseTypeAdapterFactory.java | 105 -------------- .../converter/TEnumTypeAdapterFactory.java | 65 --------- .../converter/JsonDataConverterTest.java | 128 ------------------ 4 files changed, 2 insertions(+), 303 deletions(-) delete mode 100644 src/main/java/com/uber/cadence/converter/TBaseTypeAdapterFactory.java delete mode 100644 src/main/java/com/uber/cadence/converter/TEnumTypeAdapterFactory.java diff --git a/src/main/java/com/uber/cadence/converter/JsonDataConverter.java b/src/main/java/com/uber/cadence/converter/JsonDataConverter.java index aed0c91e5..e827feb1d 100644 --- a/src/main/java/com/uber/cadence/converter/JsonDataConverter.java +++ b/src/main/java/com/uber/cadence/converter/JsonDataConverter.java @@ -37,8 +37,7 @@ /** * Implements conversion through GSON JSON processor. To extend use {@link - * #JsonDataConverter(Function)} constructor. Thrift structures are converted using {@link - * TJSONProtocol}. When using thrift only one argument of a method is expected. + * #JsonDataConverter(Function)} constructor. * * @author fateev */ @@ -78,9 +77,7 @@ public JsonDataConverter(Function builderInterceptor) GsonBuilder gsonBuilder = new GsonBuilder() .serializeNulls() - .registerTypeAdapterFactory(new ThrowableTypeAdapterFactory()) - .registerTypeAdapterFactory(new TBaseTypeAdapterFactory(metricsScope)) - .registerTypeAdapterFactory(new TEnumTypeAdapterFactory()); + .registerTypeAdapterFactory(new ThrowableTypeAdapterFactory()); GsonBuilder intercepted = builderInterceptor.apply(gsonBuilder); gson = intercepted.create(); } diff --git a/src/main/java/com/uber/cadence/converter/TBaseTypeAdapterFactory.java b/src/main/java/com/uber/cadence/converter/TBaseTypeAdapterFactory.java deleted file mode 100644 index c2f4d2b5b..000000000 --- a/src/main/java/com/uber/cadence/converter/TBaseTypeAdapterFactory.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Modifications copyright (C) 2017 Uber Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not - * use this file except in compliance with the License. A copy of the License is - * located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.uber.cadence.converter; - -import com.google.gson.Gson; -import com.google.gson.TypeAdapter; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import com.uber.m3.tally.Scope; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import org.apache.thrift.TBase; -import org.apache.thrift.TDeserializer; -import org.apache.thrift.TException; -import org.apache.thrift.TSerializer; -import org.apache.thrift.protocol.TJSONProtocol; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Special handling of TBase message serialization and deserialization. This is to support for - * inline Thrift fields in Java class. - */ -public class TBaseTypeAdapterFactory implements TypeAdapterFactory { - - private static final Logger logger = LoggerFactory.getLogger(TBaseTypeAdapterFactory.class); - private final Scope metricsScope; - - public TBaseTypeAdapterFactory(Scope metricsScope) { - this.metricsScope = metricsScope; - } - - @Override - public TypeAdapter create(Gson gson, TypeToken typeToken) { - // this class only serializes 'TBase' and its subtypes - if (!TBase.class.isAssignableFrom(typeToken.getRawType())) { - return null; - } - TypeAdapter result = - new TypeAdapter() { - @Override - public void write(JsonWriter jsonWriter, T value) throws IOException { - if (metricsScope != null) { - metricsScope.counter("tbase_message_write").inc(1); - } - try { - String result = - newThriftSerializer().toString((TBase) value, StandardCharsets.UTF_8.name()); - jsonWriter.value(result); - logger.warn( - "TBase message will no longer be support in cadence-java-client V4, payload {}", - result); - } catch (TException e) { - throw new DataConverterException("Failed to serialize TBase", e); - } - } - - @Override - public T read(JsonReader jsonReader) throws IOException { - if (metricsScope != null) { - metricsScope.counter("tbase_message_read").inc(1); - } - String value = jsonReader.nextString(); - try { - logger.warn( - "TBase message will no longer be support in cadence-java-client V4, payload {}", - value); - @SuppressWarnings("unchecked") - T instance = (T) typeToken.getRawType().getConstructor().newInstance(); - newThriftDeserializer() - .deserialize((TBase) instance, value, StandardCharsets.UTF_8.name()); - return instance; - } catch (Exception e) { - throw new DataConverterException("Failed to deserialize TBase", e); - } - } - }.nullSafe(); - return result; - } - - private static TSerializer newThriftSerializer() { - return new TSerializer(new TJSONProtocol.Factory()); - } - - private static TDeserializer newThriftDeserializer() { - return new TDeserializer(new TJSONProtocol.Factory()); - } -} diff --git a/src/main/java/com/uber/cadence/converter/TEnumTypeAdapterFactory.java b/src/main/java/com/uber/cadence/converter/TEnumTypeAdapterFactory.java deleted file mode 100644 index 22e9d1859..000000000 --- a/src/main/java/com/uber/cadence/converter/TEnumTypeAdapterFactory.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Modifications copyright (C) 2017 Uber Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"). You may not - * use this file except in compliance with the License. A copy of the License is - * located at - * - * http://aws.amazon.com/apache2.0 - * - * or in the "license" file accompanying this file. This file is distributed on - * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either - * express or implied. See the License for the specific language governing - * permissions and limitations under the License. - */ - -package com.uber.cadence.converter; - -import com.google.gson.Gson; -import com.google.gson.TypeAdapter; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.lang.reflect.Method; -import org.apache.thrift.TEnum; - -/** - * Special handling of TEnum serialization and deserialization. This is to support for inline TEnum - * fields in Java class. The default gson serde serialize the TEnum with its String name - * representation, this adapter serialize the TEnum class with its int representation. - */ -public class TEnumTypeAdapterFactory implements TypeAdapterFactory { - - @Override - public TypeAdapter create(Gson gson, TypeToken typeToken) { - // this class only serializes 'TEnum' and its subtypes - if (!TEnum.class.isAssignableFrom(typeToken.getRawType())) { - return null; - } - TypeAdapter result = - new TypeAdapter() { - @Override - public void write(JsonWriter jsonWriter, T value) throws IOException { - jsonWriter.value(((TEnum) value).getValue()); - } - - @Override - public T read(JsonReader jsonReader) throws IOException { - int value = jsonReader.nextInt(); - try { - Method m = (typeToken.getRawType().getDeclaredMethod("findByValue", Integer.TYPE)); - @SuppressWarnings("unchecked") - T instance = (T) m.invoke(null, value); - return instance; - } catch (Exception e) { - throw new DataConverterException("Failed to deserilize TEnum", e); - } - } - }.nullSafe(); - return result; - } -} diff --git a/src/test/java/com/uber/cadence/converter/JsonDataConverterTest.java b/src/test/java/com/uber/cadence/converter/JsonDataConverterTest.java index 57862ddc1..7c7fcd74a 100644 --- a/src/test/java/com/uber/cadence/converter/JsonDataConverterTest.java +++ b/src/test/java/com/uber/cadence/converter/JsonDataConverterTest.java @@ -20,12 +20,6 @@ import static org.junit.Assert.*; import com.google.gson.JsonIOException; -import com.uber.cadence.EventType; -import com.uber.cadence.History; -import com.uber.cadence.HistoryEvent; -import com.uber.cadence.TaskList; -import com.uber.cadence.WorkflowExecutionStartedEventAttributes; -import com.uber.cadence.WorkflowType; import com.uber.cadence.activity.Activity; import java.io.File; import java.io.FileInputStream; @@ -33,10 +27,8 @@ import java.io.InputStream; import java.lang.reflect.Method; import java.lang.reflect.Type; -import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import java.util.UUID; import org.junit.Test; @@ -44,126 +36,6 @@ public class JsonDataConverterTest { private final DataConverter converter = JsonDataConverter.getInstance(); - static class TestData { - String val1; - // TBase value; - HistoryEvent val2; - // TEnum value; - EventType val3; - - public TestData(String val1, HistoryEvent val2, EventType val3) { - this.val1 = val1; - this.val2 = val2; - this.val3 = val3; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof TestData)) return false; - TestData testData = (TestData) o; - return Objects.equals(val1, testData.val1) - && Objects.equals(val2, testData.val2) - && val3 == testData.val3; - } - - @Override - public int hashCode() { - - return Objects.hash(val1, val2, val3); - } - } - - @Test - public void testThrift() { - List events = new ArrayList<>(); - WorkflowExecutionStartedEventAttributes started = - new WorkflowExecutionStartedEventAttributes() - .setExecutionStartToCloseTimeoutSeconds(11) - .setIdentity("testIdentity") - .setInput("input".getBytes(StandardCharsets.UTF_8)) - .setWorkflowType(new WorkflowType().setName("workflowType1")) - .setTaskList(new TaskList().setName("taskList1")); - events.add( - new HistoryEvent() - .setTimestamp(1234567) - .setEventId(321) - .setWorkflowExecutionStartedEventAttributes(started)); - History history = new History().setEvents(events); - byte[] converted = converter.toData(history); - History fromConverted = converter.fromData(converted, History.class, History.class); - assertEquals(new String(converted, StandardCharsets.UTF_8), history, fromConverted); - } - - @Test - public void testThriftArray() { - List events = new ArrayList<>(); - WorkflowExecutionStartedEventAttributes started = - new WorkflowExecutionStartedEventAttributes() - .setExecutionStartToCloseTimeoutSeconds(11) - .setIdentity("testIdentity") - .setInput("input".getBytes(StandardCharsets.UTF_8)) - .setWorkflowType(new WorkflowType().setName("workflowType1")) - .setTaskList(new TaskList().setName("taskList1")); - events.add( - new HistoryEvent() - .setTimestamp(1234567) - .setEventId(321) - .setWorkflowExecutionStartedEventAttributes(started)); - History history = new History().setEvents(events); - byte[] converted = converter.toData("abc", history); - Object[] fromConverted = converter.fromDataArray(converted, String.class, History.class); - assertEquals(new String(converted, StandardCharsets.UTF_8), "abc", fromConverted[0]); - assertEquals(new String(converted, StandardCharsets.UTF_8), history, fromConverted[1]); - } - - @Test - public void testThriftFieldsInPOJO() { - WorkflowExecutionStartedEventAttributes started = - new WorkflowExecutionStartedEventAttributes() - .setExecutionStartToCloseTimeoutSeconds(11) - .setIdentity("testIdentity") - .setInput("input".getBytes(StandardCharsets.UTF_8)) - .setWorkflowType(new WorkflowType().setName("workflowType1")) - .setTaskList(new TaskList().setName("taskList1")); - - HistoryEvent historyEvent = - new HistoryEvent() - .setTimestamp(1234567) - .setEventId(321) - .setWorkflowExecutionStartedEventAttributes(started); - - TestData testData = new TestData("test-thrift", historyEvent, EventType.ActivityTaskCompleted); - - byte[] converted = converter.toData(testData); - TestData fromConverted = converter.fromData(converted, TestData.class, TestData.class); - assertEquals(new String(converted, StandardCharsets.UTF_8), testData, fromConverted); - } - - @Test - public void testThriftFieldsInPOJOArray() { - WorkflowExecutionStartedEventAttributes started = - new WorkflowExecutionStartedEventAttributes() - .setExecutionStartToCloseTimeoutSeconds(11) - .setIdentity("testIdentity") - .setInput("input".getBytes(StandardCharsets.UTF_8)) - .setWorkflowType(new WorkflowType().setName("workflowType1")) - .setTaskList(new TaskList().setName("taskList1")); - - HistoryEvent historyEvent = - new HistoryEvent() - .setTimestamp(1234567) - .setEventId(321) - .setWorkflowExecutionStartedEventAttributes(started); - - TestData testData = new TestData("test-thrift", historyEvent, EventType.ActivityTaskCompleted); - - byte[] converted = converter.toData("abc", testData); - Object[] fromConverted = converter.fromDataArray(converted, String.class, TestData.class); - assertEquals(new String(converted, StandardCharsets.UTF_8), "abc", fromConverted[0]); - assertEquals(new String(converted, StandardCharsets.UTF_8), testData, fromConverted[1]); - } - public static void foo(List arg) {} @Test From 46535e313d8e9bf07b8c65566c9d12778a0d2ca7 Mon Sep 17 00:00:00 2001 From: Shijie Sheng Date: Thu, 5 Jun 2025 10:26:57 -0700 Subject: [PATCH 3/3] lint --- src/main/java/com/uber/cadence/converter/JsonDataConverter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/uber/cadence/converter/JsonDataConverter.java b/src/main/java/com/uber/cadence/converter/JsonDataConverter.java index e827feb1d..26ff1a615 100644 --- a/src/main/java/com/uber/cadence/converter/JsonDataConverter.java +++ b/src/main/java/com/uber/cadence/converter/JsonDataConverter.java @@ -33,7 +33,6 @@ import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.util.function.Function; -import org.apache.thrift.protocol.TJSONProtocol; /** * Implements conversion through GSON JSON processor. To extend use {@link