diff --git a/src/main/java/com/uber/cadence/internal/compatibility/thrift/TypeMapper.java b/src/main/java/com/uber/cadence/internal/compatibility/thrift/TypeMapper.java index af696f16f..be2d34855 100644 --- a/src/main/java/com/uber/cadence/internal/compatibility/thrift/TypeMapper.java +++ b/src/main/java/com/uber/cadence/internal/compatibility/thrift/TypeMapper.java @@ -54,6 +54,7 @@ import com.uber.cadence.SupportedClientVersions; import com.uber.cadence.TaskIDBlock; import com.uber.cadence.TaskList; +import com.uber.cadence.TaskListMetadata; import com.uber.cadence.TaskListPartitionMetadata; import com.uber.cadence.TaskListStatus; import com.uber.cadence.WorkflowExecution; @@ -374,6 +375,7 @@ static WorkflowExecutionInfo workflowExecutionInfo( res.setCloseTime(timeToUnixNano(t.getCloseTime())); res.setCloseStatus(workflowExecutionCloseStatus(t.getCloseStatus())); res.setHistoryLength(t.getHistoryLength()); + res.setParentDomainName(parentDomainName(t.getParentExecutionInfo())); res.setParentDomainId(parentDomainId(t.getParentExecutionInfo())); res.setParentExecution(parentWorkflowExecution(t.getParentExecutionInfo())); res.setExecutionTime(timeToUnixNano(t.getExecutionTime())); @@ -527,6 +529,15 @@ static DescribeDomainResponse describeDomainResponseDomain(com.uber.cadence.api. return res; } + static TaskListMetadata taskListMetadata(com.uber.cadence.api.v1.TaskListMetadata t) { + if (t == null) { + return null; + } + TaskListMetadata res = new TaskListMetadata(); + res.setMaxTasksPerSecond(t.getMaxTasksPerSecond().getValue()); + return res; + } + static TaskListPartitionMetadata taskListPartitionMetadata( com.uber.cadence.api.v1.TaskListPartitionMetadata t) { if (t == null || t == com.uber.cadence.api.v1.TaskListPartitionMetadata.getDefaultInstance()) { @@ -552,8 +563,8 @@ static List pollerInfoArray(List return null; } List v = new ArrayList<>(); - for (int i = 0; i < t.size(); i++) { - v.add(pollerInfo(t.get(i))); + for (com.uber.cadence.api.v1.PollerInfo pollerInfo : t) { + v.add(pollerInfo(pollerInfo)); } return v; } @@ -563,8 +574,8 @@ static List resetPointInfoArray(List v = new ArrayList<>(); - for (int i = 0; i < t.size(); i++) { - v.add(resetPointInfo(t.get(i))); + for (com.uber.cadence.api.v1.ResetPointInfo resetPointInfo : t) { + v.add(resetPointInfo(resetPointInfo)); } return v; } @@ -575,8 +586,8 @@ static List pendingActivityInfoArray( return null; } List v = new ArrayList<>(); - for (int i = 0; i < t.size(); i++) { - v.add(pendingActivityInfo(t.get(i))); + for (com.uber.cadence.api.v1.PendingActivityInfo pendingActivityInfo : t) { + v.add(pendingActivityInfo(pendingActivityInfo)); } return v; } @@ -587,8 +598,8 @@ static List pendingChildExecutionInfoArray( return null; } List v = new ArrayList<>(); - for (int i = 0; i < t.size(); i++) { - v.add(pendingChildExecutionInfo(t.get(i))); + for (com.uber.cadence.api.v1.PendingChildExecutionInfo pendingChildExecutionInfo : t) { + v.add(pendingChildExecutionInfo(pendingChildExecutionInfo)); } return v; } @@ -610,8 +621,8 @@ static List dataBlobArray(List t) { return null; } List v = new ArrayList<>(); - for (int i = 0; i < t.size(); i++) { - v.add(dataBlob(t.get(i))); + for (com.uber.cadence.api.v1.DataBlob dataBlob : t) { + v.add(dataBlob(dataBlob)); } return v; } @@ -622,8 +633,8 @@ static List workflowExecutionInfoArray( return null; } List v = new ArrayList<>(); - for (int i = 0; i < t.size(); i++) { - v.add(workflowExecutionInfo(t.get(i))); + for (com.uber.cadence.api.v1.WorkflowExecutionInfo workflowExecutionInfo : t) { + v.add(workflowExecutionInfo(workflowExecutionInfo)); } return v; } @@ -634,8 +645,8 @@ static List describeDomainResponseArray( return null; } List v = new ArrayList<>(); - for (int i = 0; i < t.size(); i++) { - v.add(describeDomainResponseDomain(t.get(i))); + for (com.uber.cadence.api.v1.Domain domain : t) { + v.add(describeDomainResponseDomain(domain)); } return v; } @@ -646,8 +657,8 @@ static List taskListPartitionMetadataArray( return null; } List v = new ArrayList<>(); - for (int i = 0; i < t.size(); i++) { - v.add(taskListPartitionMetadata(t.get(i))); + for (com.uber.cadence.api.v1.TaskListPartitionMetadata taskListPartitionMetadata : t) { + v.add(taskListPartitionMetadata(taskListPartitionMetadata)); } return v; } diff --git a/src/test/java/com/uber/cadence/internal/compatibility/ProtoObjects.java b/src/test/java/com/uber/cadence/internal/compatibility/ProtoObjects.java index 08b5d668d..4e23f7ba0 100644 --- a/src/test/java/com/uber/cadence/internal/compatibility/ProtoObjects.java +++ b/src/test/java/com/uber/cadence/internal/compatibility/ProtoObjects.java @@ -48,6 +48,11 @@ public final class ProtoObjects { public static final String WORKFLOW_ID = "workflowId"; public static final WorkflowExecution WORKFLOW_EXECUTION = WorkflowExecution.newBuilder().setWorkflowId("workflowId").setRunId("runId").build(); + public static final WorkflowExecution EXTERNAL_WORKFLOW_EXECUTION = + WorkflowExecution.newBuilder() + .setWorkflowId("externalWorkflowId") + .setRunId("externalRunId") + .build(); public static final WorkflowExecution PARENT_WORKFLOW_EXECUTION = WorkflowExecution.newBuilder() .setWorkflowId("parentWorkflowId") @@ -123,6 +128,7 @@ public final class ProtoObjects { .setHistoryLength(3) .setParentExecutionInfo( ParentExecutionInfo.newBuilder() + .setDomainName("parentDomainName") .setDomainId("parentDomainId") .setWorkflowExecution(PARENT_WORKFLOW_EXECUTION) .setInitiatedId(1) @@ -711,6 +717,12 @@ public final class ProtoObjects { .setIdentity("identity") .build(); + public static final ExternalExecutionInfo EXTERNAL_WORKFLOW_EXECUTION_INFO = + ExternalExecutionInfo.newBuilder() + .setInitiatedId(1) + .setWorkflowExecution(EXTERNAL_WORKFLOW_EXECUTION) + .build(); + public static final WorkflowExecutionCancelRequestedEventAttributes WORKFLOW_EXECUTION_CANCEL_REQUESTED_EVENT_ATTRIBUTES = WorkflowExecutionCancelRequestedEventAttributes.newBuilder() diff --git a/src/test/java/com/uber/cadence/internal/compatibility/ThriftObjects.java b/src/test/java/com/uber/cadence/internal/compatibility/ThriftObjects.java index 2c157ec87..f52a3a866 100644 --- a/src/test/java/com/uber/cadence/internal/compatibility/ThriftObjects.java +++ b/src/test/java/com/uber/cadence/internal/compatibility/ThriftObjects.java @@ -50,6 +50,10 @@ public final class ThriftObjects { public static final String PARENT_RUN_ID = "parentRunId"; public static final WorkflowExecution PARENT_WORKFLOW_EXECUTION = new WorkflowExecution().setWorkflowId(PARENT_WORkFLOW_ID).setRunId(PARENT_RUN_ID); + public static final String EXTERNAL_WORKFLOW_ID = "externalWorkflowId"; + public static final String EXTERNAL_RUN_ID = "externalRunId"; + public static final WorkflowExecution EXTERNAL_WORKFLOW_EXECUTION = + new WorkflowExecution().setWorkflowId(EXTERNAL_WORKFLOW_ID).setRunId(EXTERNAL_RUN_ID); public static final StickyExecutionAttributes STICKY_EXECUTION_ATTRIBUTES = new StickyExecutionAttributes() .setWorkerTaskList(TASK_LIST) @@ -101,6 +105,7 @@ public final class ThriftObjects { .setCloseTime(2) .setCloseStatus(WorkflowExecutionCloseStatus.FAILED) .setHistoryLength(3) + .setParentDomainName("parentDomainName") .setParentDomainId("parentDomainId") .setParentExecution(PARENT_WORKFLOW_EXECUTION) .setExecutionTime(4) diff --git a/src/test/java/com/uber/cadence/internal/compatibility/thrift/TypeMapperTest.java b/src/test/java/com/uber/cadence/internal/compatibility/thrift/TypeMapperTest.java new file mode 100644 index 000000000..8b27ecda9 --- /dev/null +++ b/src/test/java/com/uber/cadence/internal/compatibility/thrift/TypeMapperTest.java @@ -0,0 +1,218 @@ +/* + * 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.internal.compatibility.thrift; + +import static com.uber.cadence.internal.compatibility.thrift.Helpers.byteStringToArray; +import static org.junit.Assert.*; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.uber.cadence.internal.compatibility.ProtoObjects; +import com.uber.cadence.internal.compatibility.ThriftObjects; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public class TypeMapperTest { + + @Parameterized.Parameter(0) + public String testName; + + @Parameterized.Parameter(1) + public T from; + + @Parameterized.Parameter(2) + public P to; + + @Parameterized.Parameter(3) + public Function via; + + @Test + public void testMapper() { + P actual = via.apply(from); + if (actual instanceof byte[] && to instanceof byte[]) { + // Handle the byte[] comparison + assertArrayEquals((byte[]) to, (byte[]) actual); + } else { + // Handle all other types + assertEquals(to, actual); + } + } + + @Test + public void testHandlesNull() { + P actual = via.apply(null); + + if (actual instanceof List) { + assertTrue( + "Mapper functions returning a list should return an empty list", + ((List) actual).isEmpty()); + } else if (actual instanceof Map) { + assertTrue( + "Mapper functions returning a map should return an empty map", + ((Map) actual).isEmpty()); + } else if (actual instanceof Long) { + assertEquals("For long we expect -1", -1L, actual); + } else { + assertNull("Mapper functions should accept null, returning null", actual); + } + } + + @Parameterized.Parameters(name = "{0}") + public static Iterable cases() { + return Arrays.asList( + testCase( + ProtoObjects.BAD_BINARY_INFO, ThriftObjects.BAD_BINARY_INFO, TypeMapper::badBinaryInfo), + testCase(ProtoObjects.FAILURE, "reason", TypeMapper::failureReason), + testCase(ProtoObjects.DATA_BLOB, ThriftObjects.DATA_BLOB, TypeMapper::dataBlob), + testCase( + ProtoObjects.EXTERNAL_WORKFLOW_EXECUTION_INFO, + ThriftObjects.EXTERNAL_WORKFLOW_EXECUTION, + TypeMapper::externalWorkflowExecution), + testCase( + ProtoObjects.FAILURE, + byteStringToArray(ProtoObjects.FAILURE.getDetails()), + TypeMapper::failureDetails), + testCase(ProtoObjects.ACTIVITY_TYPE, ThriftObjects.ACTIVITY_TYPE, TypeMapper::activityType), + testCase(ProtoObjects.WORKFLOW_TYPE, ThriftObjects.WORKFLOW_TYPE, TypeMapper::workflowType), + testCase(ProtoObjects.RESET_POINTS, ThriftObjects.RESET_POINTS, TypeMapper::resetPoints), + testCase( + ProtoObjects.RESET_POINT_INFO, + ThriftObjects.RESET_POINT_INFO, + TypeMapper::resetPointInfo), + testCase(ProtoObjects.POLLER_INFO, ThriftObjects.POLLER_INFO, TypeMapper::pollerInfo), + testCase( + Collections.singletonList(ProtoObjects.POLLER_INFO), + Collections.singletonList(ThriftObjects.POLLER_INFO), + TypeMapper::pollerInfoArray), + testCase( + ProtoObjects.SUPPORTED_CLIENT_VERSIONS, + ThriftObjects.SUPPORTED_CLIENT_VERSIONS, + TypeMapper::supportedClientVersions), + testCase( + ProtoObjects.TASK_LIST_STATUS, + ThriftObjects.TASK_LIST_STATUS, + TypeMapper::taskListStatus), + testCase( + ProtoObjects.WORKFLOW_EXECUTION, + ThriftObjects.WORKFLOW_EXECUTION, + TypeMapper::workflowExecution), + testCase(ProtoObjects.WORKFLOW_EXECUTION, "workflowId", TypeMapper::workflowId), + testCase(ProtoObjects.WORKFLOW_EXECUTION, "runId", TypeMapper::runId), + testCase( + ProtoObjects.WORKFLOW_EXECUTION_INFO, + ThriftObjects.WORKFLOW_EXECUTION_INFO, + TypeMapper::workflowExecutionInfo), + testCase( + Collections.singletonList(ProtoObjects.WORKFLOW_EXECUTION_INFO), + Collections.singletonList(ThriftObjects.WORKFLOW_EXECUTION_INFO), + TypeMapper::workflowExecutionInfoArray), + testCase( + ProtoObjects.INDEXED_VALUES, + ThriftObjects.INDEXED_VALUES, + TypeMapper::indexedValueTypeMap), + testCase( + ProtoObjects.WORKFLOW_EXECUTION_INFO.getParentExecutionInfo(), + "parentDomainId", + TypeMapper::parentDomainId), + testCase( + ProtoObjects.WORKFLOW_EXECUTION_INFO.getParentExecutionInfo(), + "parentDomainName", + TypeMapper::parentDomainName), + testCase( + ProtoObjects.WORKFLOW_EXECUTION_INFO.getParentExecutionInfo(), + 1L, + TypeMapper::parentInitiatedId), + testCase( + ProtoObjects.WORKFLOW_EXECUTION_INFO.getParentExecutionInfo(), + ThriftObjects.PARENT_WORKFLOW_EXECUTION, + TypeMapper::parentWorkflowExecution), + testCase( + Collections.singletonList(ProtoObjects.PENDING_CHILD_EXECUTION_INFO), + Collections.singletonList(ThriftObjects.PENDING_CHILD_EXECUTION_INFO), + TypeMapper::pendingChildExecutionInfoArray), + testCase( + Collections.singletonList(ProtoObjects.PENDING_ACTIVITY_INFO), + Collections.singletonList(ThriftObjects.PENDING_ACTIVITY_INFO), + TypeMapper::pendingActivityInfoArray), + testCase( + Collections.singletonList(ProtoObjects.RESET_POINT_INFO), + Collections.singletonList(ThriftObjects.RESET_POINT_INFO), + TypeMapper::resetPointInfoArray), + testCase(ProtoObjects.TASK_LIST, ThriftObjects.TASK_LIST, TypeMapper::taskList), + testCase( + ProtoObjects.TASK_LIST_METADATA, + ThriftObjects.TASK_LIST_METADATA, + TypeMapper::taskListMetadata), + testCase(ProtoObjects.RETRY_POLICY, ThriftObjects.RETRY_POLICY, TypeMapper::retryPolicy), + testCase(ProtoObjects.HEADER, ThriftObjects.HEADER, TypeMapper::header), + testCase(ProtoObjects.MEMO, ThriftObjects.MEMO, TypeMapper::memo), + testCase( + ProtoObjects.SEARCH_ATTRIBUTES, + ThriftObjects.SEARCH_ATTRIBUTES, + TypeMapper::searchAttributes), + testCase(ProtoObjects.BAD_BINARIES, ThriftObjects.BAD_BINARIES, TypeMapper::badBinaries), + testCase( + ProtoObjects.CLUSTER_REPLICATION_CONFIGURATION, + ThriftObjects.CLUSTER_REPLICATION_CONFIGURATION, + TypeMapper::clusterReplicationConfiguration), + testCase( + ProtoObjects.WORKFLOW_QUERY, ThriftObjects.WORKFLOW_QUERY, TypeMapper::workflowQuery), + testCase( + ImmutableMap.of("key", ProtoObjects.BAD_BINARY_INFO), + ImmutableMap.of("key", ThriftObjects.BAD_BINARY_INFO), + TypeMapper::badBinaryInfoMap), + testCase( + ImmutableList.of(ProtoObjects.CLUSTER_REPLICATION_CONFIGURATION), + ImmutableList.of(ThriftObjects.CLUSTER_REPLICATION_CONFIGURATION), + TypeMapper::clusterReplicationConfigurationArray), + testCase( + ImmutableMap.of("key", ProtoObjects.WORKFLOW_QUERY), + ImmutableMap.of("key", ThriftObjects.WORKFLOW_QUERY), + TypeMapper::workflowQueryMap), + testCase( + ImmutableMap.of("key", ProtoObjects.ACTIVITY_LOCAL_DISPATCH_INFO), + ImmutableMap.of("key", ThriftObjects.ACTIVITY_LOCAL_DISPATCH_INFO), + TypeMapper::activityLocalDispatchInfoMap), + testCase( + Collections.singletonList(ProtoObjects.DATA_BLOB), + Collections.singletonList(ThriftObjects.DATA_BLOB), + TypeMapper::dataBlobArray), + testCase( + ProtoObjects.DOMAIN, + ThriftObjects.DESCRIBE_DOMAIN_RESPONSE, + TypeMapper::describeDomainResponseDomain), + testCase( + Collections.singletonList(ProtoObjects.DOMAIN), + Collections.singletonList(ThriftObjects.DESCRIBE_DOMAIN_RESPONSE), + TypeMapper::describeDomainResponseArray), + testCase( + Collections.singletonList(ProtoObjects.TASK_LIST_PARTITION_METADATA), + Collections.singletonList(ThriftObjects.TASK_LIST_PARTITION_METADATA), + TypeMapper::taskListPartitionMetadataArray)); + } + + private static Object[] testCase(T from, P to, Function via) { + return new Object[] {from.getClass().getSimpleName(), from, to, via}; + } +}