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
7 changes: 7 additions & 0 deletions temporal-sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ dependencies {
if (!JavaVersion.current().isJava8()) {
implementation 'javax.annotation:javax.annotation-api:1.3.2'
}
// compileOnly and testImplementation because this dependency is needed only to work with json format of history
// which shouldn't be needed for any production usage of temporal-sdk.
// It's useful only for unit tests and debugging.
// For these use-cases Temporal users can add this dep in the classpath temporary or permanently themselves.
compileOnly group: 'com.jayway.jsonpath', name: 'json-path', version: '2.6.0'
testImplementation group: 'com.jayway.jsonpath', name: 'json-path', version: '2.6.0'

testImplementation project(':temporal-testing-junit4')
testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: "${logbackVersion}"
testImplementation group: 'junit', name: 'junit', version: '4.13.2'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* Copyright (C) 2020 Temporal Technologies, Inc. All Rights Reserved.
*
* 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 io.temporal.internal.common;

import com.google.common.base.CaseFormat;
import com.jayway.jsonpath.DocumentContext;
import com.jayway.jsonpath.JsonPath;

/**
* Helper methods supporting transformation of History's "Proto Json" compatible format, which is
* supported by {@link com.google.protobuf.util.JsonFormat} to the format of Temporal history
* supported by tctl and back.
*
* @see <a
* href="https://github.com/temporalio/gogo-protobuf/commit/b38fb010909b8f81e2e600dc6f04925fc71d6a5e">
* Related commit to Go Proto module</>
*/
class HistoryJsonUtils {
private static final JsonPath EVENT_TYPE_PATH = JsonPath.compile("$.events.*.eventType");
private static final JsonPath TASK_QUEUE_KIND_PATH =
JsonPath.compile("$.events.*.*.taskQueue.kind");
private static final String EVENT_TYPE_PREFIX = "EVENT_TYPE_";
private static final String TASK_QUEUE_KIND_PREFIX = "TASK_QUEUE_KIND_";

public static String protoJsonToHistoryFormatJson(String protoJson) {
DocumentContext parsed = JsonPath.parse(protoJson);
parsed.map(
EVENT_TYPE_PATH,
(currentValue, configuration) ->
enumProtoToHistory((String) currentValue, EVENT_TYPE_PREFIX));
parsed.map(
TASK_QUEUE_KIND_PATH,
(currentValue, configuration) ->
enumProtoToHistory((String) currentValue, TASK_QUEUE_KIND_PREFIX));
return parsed.jsonString();
}

public static String historyFormatJsonToProtoJson(String historyFormatJson) {
DocumentContext parsed = JsonPath.parse(historyFormatJson);
parsed.map(
EVENT_TYPE_PATH,
(currentValue, configuration) ->
enumHistoryToProto((String) currentValue, EVENT_TYPE_PREFIX));
parsed.map(
TASK_QUEUE_KIND_PATH,
(currentValue, configuration) ->
enumHistoryToProto((String) currentValue, TASK_QUEUE_KIND_PREFIX));
return parsed.jsonString();
}

private static String enumProtoToHistory(String protoEnumValue, String prefix) {
if (!protoEnumValue.startsWith(prefix)) {
throw new IllegalArgumentException("protoEnumValue should start with " + prefix + " prefix");
}
protoEnumValue = protoEnumValue.substring(prefix.length());
return screamingCaseEventTypeToCamelCase(protoEnumValue);
}

private static String enumHistoryToProto(String historyEnumValue, String prefix) {
return prefix + camelCaseToScreamingCase(historyEnumValue);
}

// https://github.com/temporalio/gogo-protobuf/commit/b38fb010909b8f81e2e600dc6f04925fc71d6a5e
private static String camelCaseToScreamingCase(String camel) {
return CaseFormat.UPPER_CAMEL.converterTo(CaseFormat.UPPER_UNDERSCORE).convert(camel);
}

// https://github.com/temporalio/gogo-protobuf/commit/b38fb010909b8f81e2e600dc6f04925fc71d6a5e
private static String screamingCaseEventTypeToCamelCase(String screaming) {
return CaseFormat.UPPER_UNDERSCORE.converterTo(CaseFormat.UPPER_CAMEL).convert(screaming);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ public WorkflowExecutionHistory(History history) {
}

public static WorkflowExecutionHistory fromJson(String serialized) {
String protoJson = HistoryJsonUtils.historyFormatJsonToProtoJson(serialized);

JsonFormat.Parser parser = JsonFormat.parser();
History.Builder historyBuilder = History.newBuilder();
try {
parser.merge(serialized, historyBuilder);
parser.merge(protoJson, historyBuilder);
} catch (InvalidProtocolBufferException e) {
throw new DataConverterException(e);
}
Expand All @@ -68,16 +70,13 @@ private static void checkHistory(History history) {
public String toJson() {
JsonFormat.Printer printer = JsonFormat.printer();
try {
return printer.print(history);
String protoJson = printer.print(history);
return HistoryJsonUtils.protoJsonToHistoryFormatJson(protoJson);
} catch (InvalidProtocolBufferException e) {
throw new DataConverterException(e);
}
}

public String toPrettyPrintedJson() {
return toJson();
}

public WorkflowExecution getWorkflowExecution() {
return WorkflowExecution.newBuilder()
.setWorkflowId("workflow_id_in_replay")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"events": [{
"eventId": "1",
"eventTime": "2020-07-14T15:04:02Z",
"eventType": "EVENT_TYPE_WORKFLOW_EXECUTION_STARTED",
"eventType": "WorkflowExecutionStarted",
"version": "-24",
"taskId": "1051005",
"workflowExecutionStartedEventAttributes": {
Expand All @@ -11,7 +11,7 @@
},
"taskQueue": {
"name": "WorkflowTest-testAsyncActivityRetry-61724a56-8299-42ec-a98d-f180000e8784",
"kind": "TASK_QUEUE_KIND_NORMAL"
"kind": "Normal"
},
"input": {
"payloads": [{
Expand All @@ -32,7 +32,7 @@
}, {
"eventId": "2",
"eventTime": "2020-07-14T15:04:02Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_SCHEDULED",
"eventType": "WorkflowTaskScheduled",
"version": "-24",
"taskId": "1051006",
"workflowTaskScheduledEventAttributes": {
Expand All @@ -44,7 +44,7 @@
}, {
"eventId": "3",
"eventTime": "2020-07-14T15:04:02Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_STARTED",
"eventType": "WorkflowTaskStarted",
"version": "-24",
"taskId": "1051011",
"workflowTaskStartedEventAttributes": {
Expand All @@ -55,7 +55,7 @@
}, {
"eventId": "4",
"eventTime": "2020-07-14T15:04:02Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_COMPLETED",
"eventType": "WorkflowTaskCompleted",
"version": "-24",
"taskId": "1051014",
"workflowTaskCompletedEventAttributes": {
Expand All @@ -66,7 +66,7 @@
}, {
"eventId": "5",
"eventTime": "2020-07-14T15:04:02Z",
"eventType": "EVENT_TYPE_ACTIVITY_TASK_SCHEDULED",
"eventType": "ActivityTaskScheduled",
"version": "-24",
"taskId": "1051015",
"activityTaskScheduledEventAttributes": {
Expand All @@ -92,7 +92,7 @@
}, {
"eventId": "6",
"eventTime": "2020-07-14T15:04:04Z",
"eventType": "EVENT_TYPE_ACTIVITY_TASK_STARTED",
"eventType": "ActivityTaskStarted",
"version": "-24",
"taskId": "1051026",
"activityTaskStartedEventAttributes": {
Expand All @@ -112,7 +112,7 @@
}, {
"eventId": "7",
"eventTime": "2020-07-14T15:04:04Z",
"eventType": "EVENT_TYPE_ACTIVITY_TASK_FAILED",
"eventType": "ActivityTaskFailed",
"version": "-24",
"taskId": "1051027",
"activityTaskFailedEventAttributes": {
Expand All @@ -132,7 +132,7 @@
}, {
"eventId": "8",
"eventTime": "2020-07-14T15:04:04Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_SCHEDULED",
"eventType": "WorkflowTaskScheduled",
"version": "-24",
"taskId": "1051030",
"workflowTaskScheduledEventAttributes": {
Expand All @@ -144,7 +144,7 @@
}, {
"eventId": "9",
"eventTime": "2020-07-14T15:04:04Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_STARTED",
"eventType": "WorkflowTaskStarted",
"version": "-24",
"taskId": "1051034",
"workflowTaskStartedEventAttributes": {
Expand All @@ -155,7 +155,7 @@
}, {
"eventId": "10",
"eventTime": "2020-07-14T15:04:04Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_COMPLETED",
"eventType": "WorkflowTaskCompleted",
"version": "-24",
"taskId": "1051037",
"workflowTaskCompletedEventAttributes": {
Expand All @@ -166,7 +166,7 @@
}, {
"eventId": "11",
"eventTime": "2020-07-14T15:04:04Z",
"eventType": "EVENT_TYPE_WORKFLOW_EXECUTION_FAILED",
"eventType": "WorkflowExecutionFailed",
"version": "-24",
"taskId": "1051038",
"workflowExecutionFailedEventAttributes": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"events": [{
"eventId": "1",
"eventTime": "2020-07-14T15:05:35Z",
"eventType": "EVENT_TYPE_WORKFLOW_EXECUTION_STARTED",
"eventType": "WorkflowExecutionStarted",
"version": "-24",
"taskId": "1051760",
"workflowExecutionStartedEventAttributes": {
Expand All @@ -11,7 +11,7 @@
},
"taskQueue": {
"name": "WorkflowTest-testChildWorkflowRetry-c5c598cd-05d6-4790-b43e-ebf149aee65b",
"kind": "TASK_QUEUE_KIND_NORMAL"
"kind": "Normal"
},
"input": {
"payloads": [{
Expand All @@ -32,7 +32,7 @@
}, {
"eventId": "2",
"eventTime": "2020-07-14T15:05:35Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_SCHEDULED",
"eventType": "WorkflowTaskScheduled",
"version": "-24",
"taskId": "1051761",
"workflowTaskScheduledEventAttributes": {
Expand All @@ -44,7 +44,7 @@
}, {
"eventId": "3",
"eventTime": "2020-07-14T15:05:35Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_STARTED",
"eventType": "WorkflowTaskStarted",
"version": "-24",
"taskId": "1051766",
"workflowTaskStartedEventAttributes": {
Expand All @@ -55,7 +55,7 @@
}, {
"eventId": "4",
"eventTime": "2020-07-14T15:05:35Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_COMPLETED",
"eventType": "WorkflowTaskCompleted",
"version": "-24",
"taskId": "1051769",
"workflowTaskCompletedEventAttributes": {
Expand All @@ -66,7 +66,7 @@
}, {
"eventId": "5",
"eventTime": "2020-07-14T15:05:35Z",
"eventType": "EVENT_TYPE_START_CHILD_WORKFLOW_EXECUTION_INITIATED",
"eventType": "StartChildWorkflowExecutionInitiated",
"version": "-24",
"taskId": "1051770",
"startChildWorkflowExecutionInitiatedEventAttributes": {
Expand Down Expand Up @@ -106,7 +106,7 @@
}, {
"eventId": "6",
"eventTime": "2020-07-14T15:05:35Z",
"eventType": "EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_STARTED",
"eventType": "ChildWorkflowExecutionStarted",
"version": "-24",
"taskId": "1051773",
"childWorkflowExecutionStartedEventAttributes": {
Expand All @@ -122,7 +122,7 @@
}, {
"eventId": "7",
"eventTime": "2020-07-14T15:05:35Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_SCHEDULED",
"eventType": "WorkflowTaskScheduled",
"version": "-24",
"taskId": "1051775",
"workflowTaskScheduledEventAttributes": {
Expand All @@ -134,7 +134,7 @@
}, {
"eventId": "8",
"eventTime": "2020-07-14T15:05:35Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_STARTED",
"eventType": "WorkflowTaskStarted",
"version": "-24",
"taskId": "1051779",
"workflowTaskStartedEventAttributes": {
Expand All @@ -145,7 +145,7 @@
}, {
"eventId": "9",
"eventTime": "2020-07-14T15:05:35Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_COMPLETED",
"eventType": "WorkflowTaskCompleted",
"version": "-24",
"taskId": "1051782",
"workflowTaskCompletedEventAttributes": {
Expand All @@ -156,7 +156,7 @@
}, {
"eventId": "10",
"eventTime": "2020-07-14T15:05:37Z",
"eventType": "EVENT_TYPE_CHILD_WORKFLOW_EXECUTION_FAILED",
"eventType": "ChildWorkflowExecutionFailed",
"version": "-24",
"taskId": "1051784",
"childWorkflowExecutionFailedEventAttributes": {
Expand All @@ -182,7 +182,7 @@
}, {
"eventId": "11",
"eventTime": "2020-07-14T15:05:37Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_SCHEDULED",
"eventType": "WorkflowTaskScheduled",
"version": "-24",
"taskId": "1051786",
"workflowTaskScheduledEventAttributes": {
Expand All @@ -194,7 +194,7 @@
}, {
"eventId": "12",
"eventTime": "2020-07-14T15:05:37Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_STARTED",
"eventType": "WorkflowTaskStarted",
"version": "-24",
"taskId": "1051790",
"workflowTaskStartedEventAttributes": {
Expand All @@ -205,7 +205,7 @@
}, {
"eventId": "13",
"eventTime": "2020-07-14T15:05:37Z",
"eventType": "EVENT_TYPE_WORKFLOW_TASK_COMPLETED",
"eventType": "WorkflowTaskCompleted",
"version": "-24",
"taskId": "1051793",
"workflowTaskCompletedEventAttributes": {
Expand All @@ -216,7 +216,7 @@
}, {
"eventId": "14",
"eventTime": "2020-07-14T15:05:37Z",
"eventType": "EVENT_TYPE_WORKFLOW_EXECUTION_FAILED",
"eventType": "WorkflowExecutionFailed",
"version": "-24",
"taskId": "1051794",
"workflowExecutionFailedEventAttributes": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ public static void regenerateHistoryForReplay(
GetWorkflowExecutionHistoryResponse response =
service.blockingStub().getWorkflowExecutionHistory(request);
WorkflowExecutionHistory history = new WorkflowExecutionHistory(response.getHistory());
String json = history.toPrettyPrintedJson();
String json = history.toJson();
String projectPath = System.getProperty("user.dir");
String resourceFile = projectPath + "/src/test/resources/" + fileName + ".json";
File file = new File(resourceFile);
Expand Down