From 1d77cea133094504c6cda81ecac95b947823c995 Mon Sep 17 00:00:00 2001 From: Tim Li Date: Tue, 12 Aug 2025 08:24:27 -0700 Subject: [PATCH 1/4] Implement BufferOne CronoverlapPolicy --- .../uber/cadence/client/WorkflowOptions.java | 29 +- .../StartWorkflowExecutionParameters.java | 16 + .../compatibility/proto/DecisionMapper.java | 2 + .../compatibility/proto/RequestMapper.java | 1 + .../GenericWorkflowClientExternalImpl.java | 2 + ...StartChildWorkflowExecutionParameters.java | 51 +++- .../internal/sync/SyncDecisionContext.java | 1 + .../workflow/ChildWorkflowOptions.java | 23 ++ .../cadence/client/WorkflowOptionsTest.java | 97 +++++++ .../StartWorkflowExecutionParametersTest.java | 110 +++++++ ...tChildWorkflowExecutionParametersTest.java | 274 ++++++++++++++++++ 11 files changed, 599 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/uber/cadence/client/WorkflowOptions.java b/src/main/java/com/uber/cadence/client/WorkflowOptions.java index 42260a4a7..eeb2594cd 100644 --- a/src/main/java/com/uber/cadence/client/WorkflowOptions.java +++ b/src/main/java/com/uber/cadence/client/WorkflowOptions.java @@ -64,6 +64,7 @@ public static WorkflowOptions merge( .setRetryOptions(RetryOptions.merge(methodRetry, o.getRetryOptions())) .setCronSchedule(OptionsUtils.merge(cronAnnotation, o.getCronSchedule(), String.class)) .setMemo(o.getMemo()) + .setCronOverlapPolicy(o.cronOverlapPolicy) .setSearchAttributes(o.getSearchAttributes()) .setContextPropagators(o.getContextPropagators()) .setDelayStart(o.delayStart) @@ -86,6 +87,8 @@ public static final class Builder { private String cronSchedule; + private int cronOverlapPolicy; + private Map memo; private Map searchAttributes; @@ -107,6 +110,7 @@ public Builder(WorkflowOptions o) { this.taskList = o.taskList; this.retryOptions = o.retryOptions; this.cronSchedule = o.cronSchedule; + this.cronOverlapPolicy = o.cronOverlapPolicy; this.memo = o.memo; this.searchAttributes = o.searchAttributes; this.contextPropagators = o.contextPropagators; @@ -194,6 +198,11 @@ public Builder setCronSchedule(String cronSchedule) { return this; } + public Builder setCronOverlapPolicy(int cronOverlapPolicy) { + this.cronOverlapPolicy = cronOverlapPolicy; + return this; + } + /** * Specifies additional non-indexed information in result of list workflow. The type of value * can be any object that are serializable by {@link com.uber.cadence.converter.DataConverter} @@ -235,7 +244,8 @@ public WorkflowOptions build() { memo, searchAttributes, contextPropagators, - delayStart); + delayStart, + cronOverlapPolicy); } /** @@ -290,7 +300,8 @@ public WorkflowOptions validateBuildWithDefaults() { memo, searchAttributes, contextPropagators, - delayStart); + delayStart, + cronOverlapPolicy); } } @@ -308,6 +319,8 @@ public WorkflowOptions validateBuildWithDefaults() { private String cronSchedule; + private int cronOverlapPolicy; + private Map memo; private Map searchAttributes; @@ -327,7 +340,8 @@ private WorkflowOptions( Map memo, Map searchAttributes, List contextPropagators, - Duration delayStart) { + Duration delayStart, + int cronOverlapPolicy) { this.workflowId = workflowId; this.workflowIdReusePolicy = workflowIdReusePolicy; this.executionStartToCloseTimeout = executionStartToCloseTimeout; @@ -339,6 +353,7 @@ private WorkflowOptions( this.searchAttributes = searchAttributes; this.contextPropagators = contextPropagators; this.delayStart = delayStart; + this.cronOverlapPolicy = cronOverlapPolicy; } public String getWorkflowId() { @@ -369,6 +384,10 @@ public String getCronSchedule() { return cronSchedule; } + public int getCronOverlapPolicy() { + return cronOverlapPolicy; + } + public Map getMemo() { return memo; } @@ -397,6 +416,7 @@ public boolean equals(Object o) { && Objects.equals(taskList, that.taskList) && Objects.equals(retryOptions, that.retryOptions) && Objects.equals(cronSchedule, that.cronSchedule) + && cronOverlapPolicy == that.cronOverlapPolicy && Objects.equals(memo, that.memo) && Objects.equals(searchAttributes, that.searchAttributes) && Objects.equals(contextPropagators, that.contextPropagators) @@ -413,6 +433,7 @@ public int hashCode() { taskList, retryOptions, cronSchedule, + cronOverlapPolicy, memo, searchAttributes, contextPropagators, @@ -439,6 +460,8 @@ public String toString() { + ", cronSchedule='" + cronSchedule + '\'' + + ", cronOverlapPolicy=" + + cronOverlapPolicy + ", memo='" + memo + '\'' diff --git a/src/main/java/com/uber/cadence/internal/common/StartWorkflowExecutionParameters.java b/src/main/java/com/uber/cadence/internal/common/StartWorkflowExecutionParameters.java index 9171c2740..766a545f8 100644 --- a/src/main/java/com/uber/cadence/internal/common/StartWorkflowExecutionParameters.java +++ b/src/main/java/com/uber/cadence/internal/common/StartWorkflowExecutionParameters.java @@ -56,6 +56,8 @@ public final class StartWorkflowExecutionParameters { private Duration delayStart; + private int cronOverlapPolicy; + /** * Returns the value of the WorkflowId property for this object. * @@ -317,6 +319,14 @@ public Duration getDelayStart() { return delayStart; } + public int getCronOverlapPolicy() { + return cronOverlapPolicy; + } + + public void setCronOverlapPolicy(int cronOverlapPolicy) { + this.cronOverlapPolicy = cronOverlapPolicy; + } + public StartWorkflowExecutionParameters withRetryParameters(RetryParameters retryParameters) { this.retryParameters = retryParameters; return this; @@ -352,6 +362,7 @@ public static StartWorkflowExecutionParameters fromWorkflowOptions(WorkflowOptio if (options.getCronSchedule() != null) { parameters.setCronSchedule(options.getCronSchedule()); } + parameters.setCronOverlapPolicy(options.getCronOverlapPolicy()); return parameters; } @@ -386,6 +397,8 @@ public String toString() { + ", cronSchedule='" + cronSchedule + '\'' + + ", cronOverlapPolicy=" + + cronOverlapPolicy + ", memo='" + memo + '\'' @@ -413,6 +426,7 @@ public boolean equals(Object o) { && workflowIdReusePolicy == that.workflowIdReusePolicy && Objects.equals(retryParameters, that.retryParameters) && Objects.equals(cronSchedule, that.cronSchedule) + && cronOverlapPolicy == that.cronOverlapPolicy && Objects.equals(memo, that.memo) && Objects.equals(searchAttributes, that.searchAttributes) && Objects.equals(context, that.context) @@ -431,6 +445,7 @@ public int hashCode() { workflowIdReusePolicy, retryParameters, cronSchedule, + cronOverlapPolicy, memo, searchAttributes, context, @@ -452,6 +467,7 @@ public StartWorkflowExecutionParameters copy() { result.setRetryParameters(retryParameters.copy()); } result.setCronSchedule(cronSchedule); + result.setCronOverlapPolicy(cronOverlapPolicy); result.setMemo(memo); result.setSearchAttributes(searchAttributes); result.setContext(context); diff --git a/src/main/java/com/uber/cadence/internal/compatibility/proto/DecisionMapper.java b/src/main/java/com/uber/cadence/internal/compatibility/proto/DecisionMapper.java index a3d5e5ca5..fabd5849b 100644 --- a/src/main/java/com/uber/cadence/internal/compatibility/proto/DecisionMapper.java +++ b/src/main/java/com/uber/cadence/internal/compatibility/proto/DecisionMapper.java @@ -194,6 +194,7 @@ static Decision decision(com.uber.cadence.Decision d) { if (attr.getCronSchedule() != null) { builder.setCronSchedule(attr.getCronSchedule()); } + // cronOverlapPolicy not mapped in proto path yet decision.setContinueAsNewWorkflowExecutionDecisionAttributes(builder); } break; @@ -226,6 +227,7 @@ static Decision decision(com.uber.cadence.Decision d) { if (attr.getCronSchedule() != null) { builder.setCronSchedule(attr.getCronSchedule()); } + // cronOverlapPolicy not mapped in proto path yet decision.setStartChildWorkflowExecutionDecisionAttributes(builder); } break; diff --git a/src/main/java/com/uber/cadence/internal/compatibility/proto/RequestMapper.java b/src/main/java/com/uber/cadence/internal/compatibility/proto/RequestMapper.java index c07d67361..0584ae896 100644 --- a/src/main/java/com/uber/cadence/internal/compatibility/proto/RequestMapper.java +++ b/src/main/java/com/uber/cadence/internal/compatibility/proto/RequestMapper.java @@ -545,6 +545,7 @@ public static StartWorkflowExecutionRequest startWorkflowExecutionRequest( if (t.getCronSchedule() != null) { request.setCronSchedule(t.getCronSchedule()); } + // cronOverlapPolicy not mapped in proto path yet if (t.getIdentity() != null) { request.setIdentity(t.getIdentity()); } diff --git a/src/main/java/com/uber/cadence/internal/external/GenericWorkflowClientExternalImpl.java b/src/main/java/com/uber/cadence/internal/external/GenericWorkflowClientExternalImpl.java index ef96cacda..6cc160db1 100644 --- a/src/main/java/com/uber/cadence/internal/external/GenericWorkflowClientExternalImpl.java +++ b/src/main/java/com/uber/cadence/internal/external/GenericWorkflowClientExternalImpl.java @@ -275,6 +275,7 @@ private StartWorkflowExecutionRequest getStartRequest( if (!Strings.isNullOrEmpty(startParameters.getCronSchedule())) { request.setCronSchedule(startParameters.getCronSchedule()); } + // cronOverlapPolicy not supported in thrift request yet request.setMemo(toMemoThrift(startParameters.getMemo())); request.setSearchAttributes(toSearchAttributesThrift(startParameters.getSearchAttributes())); request.setHeader(toHeaderThrift(startParameters.getContext())); @@ -504,6 +505,7 @@ private SignalWithStartWorkflowExecutionRequest createSignalWithStartRequest( if (!Strings.isNullOrEmpty(startParameters.getCronSchedule())) { request.setCronSchedule(startParameters.getCronSchedule()); } + // cronOverlapPolicy not supported in thrift request yet if (startParameters.getDelayStart() != null) { request.setDelayStartSeconds((int) startParameters.getDelayStart().getSeconds()); } diff --git a/src/main/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParameters.java b/src/main/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParameters.java index 5758ff905..9146c4491 100644 --- a/src/main/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParameters.java +++ b/src/main/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParameters.java @@ -51,6 +51,8 @@ public static final class Builder { private String cronSchedule; + private int cronOverlapPolicy; + private Map memo; private Map searchAttributes; @@ -115,6 +117,11 @@ public Builder setCronSchedule(String cronSchedule) { return this; } + public Builder setCronOverlapPolicy(int cronOverlapPolicy) { + this.cronOverlapPolicy = cronOverlapPolicy; + return this; + } + public Builder setMemo(Map memo) { this.memo = memo; return this; @@ -148,6 +155,7 @@ public StartChildWorkflowExecutionParameters build() { workflowIdReusePolicy, retryParameters, cronSchedule, + cronOverlapPolicy, memo, searchAttributes, context, @@ -177,6 +185,8 @@ public StartChildWorkflowExecutionParameters build() { private final String cronSchedule; + private final int cronOverlapPolicy; + private Map memo; private Map searchAttributes; @@ -197,6 +207,7 @@ private StartChildWorkflowExecutionParameters( WorkflowIdReusePolicy workflowIdReusePolicy, RetryParameters retryParameters, String cronSchedule, + int cronOverlapPolicy, Map memo, Map searchAttributes, Map context, @@ -212,6 +223,7 @@ private StartChildWorkflowExecutionParameters( this.workflowIdReusePolicy = workflowIdReusePolicy; this.retryParameters = retryParameters; this.cronSchedule = cronSchedule; + this.cronOverlapPolicy = cronOverlapPolicy; this.memo = memo; this.searchAttributes = searchAttributes; this.context = context; @@ -262,6 +274,10 @@ public String getCronSchedule() { return cronSchedule; } + public int getCronOverlapPolicy() { + return cronOverlapPolicy; + } + public Map getMemo() { return memo; } @@ -278,6 +294,28 @@ public ParentClosePolicy getParentClosePolicy() { return parentClosePolicy; } + public StartChildWorkflowExecutionParameters copy() { + StartChildWorkflowExecutionParameters result = + new StartChildWorkflowExecutionParameters( + domain, + input, + control, + executionStartToCloseTimeoutSeconds, + taskList, + taskStartToCloseTimeoutSeconds, + workflowId, + workflowType, + workflowIdReusePolicy, + retryParameters, + cronSchedule, + cronOverlapPolicy, + memo, + searchAttributes, + context, + parentClosePolicy); + return result; + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -286,18 +324,19 @@ public boolean equals(Object o) { return executionStartToCloseTimeoutSeconds == that.executionStartToCloseTimeoutSeconds && taskStartToCloseTimeoutSeconds == that.taskStartToCloseTimeoutSeconds && Objects.equals(domain, that.domain) - && Objects.equals(control, that.control) && Arrays.equals(input, that.input) + && Objects.equals(control, that.control) && Objects.equals(taskList, that.taskList) && Objects.equals(workflowId, that.workflowId) && Objects.equals(workflowType, that.workflowType) && workflowIdReusePolicy == that.workflowIdReusePolicy && Objects.equals(retryParameters, that.retryParameters) && Objects.equals(cronSchedule, that.cronSchedule) + && cronOverlapPolicy == that.cronOverlapPolicy && Objects.equals(memo, that.memo) && Objects.equals(searchAttributes, that.searchAttributes) && Objects.equals(context, that.context) - && Objects.equals(parentClosePolicy, that.parentClosePolicy); + && parentClosePolicy == that.parentClosePolicy; } @Override @@ -314,6 +353,7 @@ public int hashCode() { workflowIdReusePolicy, retryParameters, cronSchedule, + cronOverlapPolicy, memo, searchAttributes, context, @@ -349,13 +389,16 @@ public String toString() { + workflowIdReusePolicy + ", retryParameters=" + retryParameters - + ", cronSchedule=" + + ", cronSchedule='" + cronSchedule + + '\'' + + ", cronOverlapPolicy=" + + cronOverlapPolicy + ", memo=" + memo + ", searchAttributes=" + searchAttributes - + ", context='" + + ", context=" + context + ", parentClosePolicy=" + parentClosePolicy diff --git a/src/main/java/com/uber/cadence/internal/sync/SyncDecisionContext.java b/src/main/java/com/uber/cadence/internal/sync/SyncDecisionContext.java index c204ff22a..f6d5b9585 100644 --- a/src/main/java/com/uber/cadence/internal/sync/SyncDecisionContext.java +++ b/src/main/java/com/uber/cadence/internal/sync/SyncDecisionContext.java @@ -460,6 +460,7 @@ private Promise executeChildWorkflowOnce( .setWorkflowIdReusePolicy(options.getWorkflowIdReusePolicy()) .setRetryParameters(retryParameters) .setCronSchedule(options.getCronSchedule()) + .setCronOverlapPolicy(options.getCronOverlapPolicy()) .setMemo(options.getMemo()) .setSearchAttributes(options.getSearchAttributes()) .setContext(extractContextsAndConvertToBytes(propagators)) diff --git a/src/main/java/com/uber/cadence/workflow/ChildWorkflowOptions.java b/src/main/java/com/uber/cadence/workflow/ChildWorkflowOptions.java index 53e09a6d9..d19d4ea1f 100644 --- a/src/main/java/com/uber/cadence/workflow/ChildWorkflowOptions.java +++ b/src/main/java/com/uber/cadence/workflow/ChildWorkflowOptions.java @@ -56,6 +56,7 @@ public static ChildWorkflowOptions merge( .setTaskList(OptionsUtils.merge(a.taskList(), o.getTaskList(), String.class)) .setRetryOptions(RetryOptions.merge(r, o.getRetryOptions())) .setCronSchedule(OptionsUtils.merge(cronAnnotation, o.getCronSchedule(), String.class)) + .setCronOverlapPolicy(o.getCronOverlapPolicy()) .setParentClosePolicy(o.getParentClosePolicy()) .setMemo(o.getMemo()) .setSearchAttributes(o.getSearchAttributes()) @@ -81,6 +82,8 @@ public static final class Builder { private String cronSchedule; + private int cronOverlapPolicy; + private ParentClosePolicy parentClosePolicy; private Map memo; @@ -103,6 +106,7 @@ public Builder(ChildWorkflowOptions source) { this.taskList = source.getTaskList(); this.retryOptions = source.getRetryOptions(); this.cronSchedule = source.getCronSchedule(); + this.cronOverlapPolicy = source.getCronOverlapPolicy(); this.parentClosePolicy = source.getParentClosePolicy(); this.memo = source.getMemo(); this.searchAttributes = source.getSearchAttributes(); @@ -199,6 +203,11 @@ public Builder setCronSchedule(String cronSchedule) { return this; } + public Builder setCronOverlapPolicy(int cronOverlapPolicy) { + this.cronOverlapPolicy = cronOverlapPolicy; + return this; + } + /** Specifies how this workflow reacts to the death of the parent workflow. */ public Builder setParentClosePolicy(ParentClosePolicy parentClosePolicy) { this.parentClosePolicy = parentClosePolicy; @@ -233,6 +242,7 @@ public ChildWorkflowOptions build() { taskList, retryOptions, cronSchedule, + cronOverlapPolicy, parentClosePolicy, memo, searchAttributes, @@ -249,6 +259,7 @@ public ChildWorkflowOptions validateAndBuildWithDefaults() { taskList, retryOptions, cronSchedule, + cronOverlapPolicy, parentClosePolicy, memo, searchAttributes, @@ -272,6 +283,8 @@ public ChildWorkflowOptions validateAndBuildWithDefaults() { private final String cronSchedule; + private final int cronOverlapPolicy; + private final ParentClosePolicy parentClosePolicy; private final Map memo; @@ -289,6 +302,7 @@ private ChildWorkflowOptions( String taskList, RetryOptions retryOptions, String cronSchedule, + int cronOverlapPolicy, ParentClosePolicy parentClosePolicy, Map memo, Map searchAttributes, @@ -301,6 +315,7 @@ private ChildWorkflowOptions( this.taskList = taskList; this.retryOptions = retryOptions; this.cronSchedule = cronSchedule; + this.cronOverlapPolicy = cronOverlapPolicy; this.parentClosePolicy = parentClosePolicy; this.memo = memo; this.searchAttributes = searchAttributes; @@ -339,6 +354,10 @@ public String getCronSchedule() { return cronSchedule; } + public int getCronOverlapPolicy() { + return cronOverlapPolicy; + } + public ParentClosePolicy getParentClosePolicy() { return parentClosePolicy; } @@ -369,6 +388,7 @@ public boolean equals(Object o) { && Objects.equals(taskList, that.taskList) && Objects.equals(retryOptions, that.retryOptions) && Objects.equals(cronSchedule, that.cronSchedule) + && cronOverlapPolicy == that.cronOverlapPolicy && Objects.equals(parentClosePolicy, that.parentClosePolicy) && Objects.equals(memo, that.memo) && Objects.equals(searchAttributes, that.searchAttributes) @@ -386,6 +406,7 @@ public int hashCode() { taskList, retryOptions, cronSchedule, + cronOverlapPolicy, parentClosePolicy, memo, searchAttributes, @@ -414,6 +435,8 @@ public String toString() { + retryOptions + ", cronSchedule=" + cronSchedule + + ", cronOverlapPolicy=" + + cronOverlapPolicy + ", parentClosePolicy=" + parentClosePolicy + ", memo='" diff --git a/src/test/java/com/uber/cadence/client/WorkflowOptionsTest.java b/src/test/java/com/uber/cadence/client/WorkflowOptionsTest.java index 050a307b8..ffc6de675 100644 --- a/src/test/java/com/uber/cadence/client/WorkflowOptionsTest.java +++ b/src/test/java/com/uber/cadence/client/WorkflowOptionsTest.java @@ -17,6 +17,10 @@ package com.uber.cadence.client; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; + import com.uber.cadence.WorkflowIdReusePolicy; import com.uber.cadence.common.CronSchedule; import com.uber.cadence.common.MethodRetry; @@ -44,6 +48,7 @@ public void testOnlyOptionsAndEmptyAnnotationsPresent() throws NoSuchMethodExcep .setExecutionStartToCloseTimeout(Duration.ofSeconds(321)) .setTaskStartToCloseTimeout(Duration.ofSeconds(13)) .setWorkflowIdReusePolicy(WorkflowIdReusePolicy.RejectDuplicate) + .setCronOverlapPolicy(2) .setMemo(getTestMemo()) .setSearchAttributes(getTestSearchAttributes()) .build(); @@ -52,6 +57,7 @@ public void testOnlyOptionsAndEmptyAnnotationsPresent() throws NoSuchMethodExcep .getMethod("defaultWorkflowOptions") .getAnnotation(WorkflowMethod.class); Assert.assertEquals(o, WorkflowOptions.merge(a, null, null, o)); + Assert.assertEquals(2, o.getCronOverlapPolicy()); } @WorkflowMethod( @@ -192,6 +198,97 @@ public void testInvalidCronScheduleAnnotation() throws NoSuchMethodException { Assert.fail("invalid cron schedule not caught"); } + @Test + public void testCronOverlapPolicy() { + WorkflowOptions options = + new WorkflowOptions.Builder() + .setTaskList("test-task-list") + .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) + .setCronOverlapPolicy(2) + .build(); + + assertEquals(2, options.getCronOverlapPolicy()); + } + + @Test + public void testCronOverlapPolicyInMerge() { + WorkflowOptions base = + new WorkflowOptions.Builder() + .setTaskList("test-task-list") + .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) + .setCronOverlapPolicy(1) + .build(); + + WorkflowOptions override = + new WorkflowOptions.Builder() + .setTaskList("test-task-list") + .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) + .setCronOverlapPolicy(3) + .build(); + + WorkflowOptions merged = WorkflowOptions.merge(null, null, null, override); + assertEquals(3, merged.getCronOverlapPolicy()); + + WorkflowOptions mergedWithBase = WorkflowOptions.merge(null, null, null, base); + assertEquals(1, mergedWithBase.getCronOverlapPolicy()); + } + + @Test + public void testCronOverlapPolicyEqualsAndHashCode() { + WorkflowOptions options1 = + new WorkflowOptions.Builder() + .setTaskList("test-task-list") + .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) + .setCronOverlapPolicy(2) + .build(); + + WorkflowOptions options2 = + new WorkflowOptions.Builder() + .setTaskList("test-task-list") + .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) + .setCronOverlapPolicy(2) + .build(); + + WorkflowOptions options3 = + new WorkflowOptions.Builder() + .setTaskList("test-task-list") + .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) + .setCronOverlapPolicy(3) + .build(); + + assertEquals(options1, options2); + assertNotEquals(options1, options3); + assertEquals(options1.hashCode(), options2.hashCode()); + assertNotEquals(options1.hashCode(), options3.hashCode()); + } + + @Test + public void testCronOverlapPolicyToString() { + WorkflowOptions options = + new WorkflowOptions.Builder() + .setTaskList("test-task-list") + .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) + .setCronOverlapPolicy(2) + .build(); + + String toString = options.toString(); + assertTrue(toString.contains("cronOverlapPolicy=2")); + } + + @Test + public void testCronOverlapPolicyCopy() { + WorkflowOptions original = + new WorkflowOptions.Builder() + .setTaskList("test-task-list") + .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) + .setCronOverlapPolicy(2) + .build(); + + WorkflowOptions copy = new WorkflowOptions.Builder(original).build(); + assertEquals(original.getCronOverlapPolicy(), copy.getCronOverlapPolicy()); + assertEquals(original, copy); + } + private Map getTestMemo() { Map memo = new HashMap<>(); memo.put("testKey", "testObject"); diff --git a/src/test/java/com/uber/cadence/internal/common/StartWorkflowExecutionParametersTest.java b/src/test/java/com/uber/cadence/internal/common/StartWorkflowExecutionParametersTest.java index fd675f850..ba667b8df 100644 --- a/src/test/java/com/uber/cadence/internal/common/StartWorkflowExecutionParametersTest.java +++ b/src/test/java/com/uber/cadence/internal/common/StartWorkflowExecutionParametersTest.java @@ -18,6 +18,8 @@ import static org.junit.Assert.*; import com.uber.cadence.WorkflowType; +import com.uber.cadence.client.WorkflowOptions; +import java.time.Duration; import org.junit.Before; import org.junit.Test; @@ -64,6 +66,7 @@ public void testToString() { + "maximumAttempts=0, " + "nonRetriableErrorReasons=null, expirationIntervalInSeconds=0}, " + "cronSchedule='* * * * *', " + + "cronOverlapPolicy=0, " + "memo='null', searchAttributes='null, context='null, delayStart='null'}"; assertEquals(expectedString, params1.toString()); @@ -124,5 +127,112 @@ public void testCopy() { params1.getRetryParameters().getExpirationIntervalInSeconds(), copy.getRetryParameters().getExpirationIntervalInSeconds()); assertEquals(params1.getCronSchedule(), copy.getCronSchedule()); + assertEquals(params1.getCronOverlapPolicy(), copy.getCronOverlapPolicy()); + } + + @Test + public void testCronOverlapPolicyField() { + StartWorkflowExecutionParameters params = new StartWorkflowExecutionParameters(); + params.setCronOverlapPolicy(2); + assertEquals(2, params.getCronOverlapPolicy()); + } + + @Test + public void testCronOverlapPolicyInEqualsAndHashCode() { + StartWorkflowExecutionParameters params1 = new StartWorkflowExecutionParameters(); + params1.setWorkflowId("workflow123"); + params1.setWorkflowType(new WorkflowType().setName("sampleWorkflow")); + params1.setTaskList("taskList1"); + params1.setInput(new byte[] {1, 2, 3}); + params1.setExecutionStartToCloseTimeoutSeconds(60); + params1.setTaskStartToCloseTimeoutSeconds(30); + params1.setCronOverlapPolicy(2); + + StartWorkflowExecutionParameters params2 = new StartWorkflowExecutionParameters(); + params2.setWorkflowId("workflow123"); + params2.setWorkflowType(new WorkflowType().setName("sampleWorkflow")); + params2.setTaskList("taskList1"); + params2.setInput(new byte[] {1, 2, 3}); + params2.setExecutionStartToCloseTimeoutSeconds(60); + params2.setTaskStartToCloseTimeoutSeconds(30); + params2.setCronOverlapPolicy(2); + + StartWorkflowExecutionParameters params3 = new StartWorkflowExecutionParameters(); + params3.setWorkflowId("workflow123"); + params3.setWorkflowType(new WorkflowType().setName("sampleWorkflow")); + params3.setTaskList("taskList1"); + params3.setInput(new byte[] {1, 2, 3}); + params3.setExecutionStartToCloseTimeoutSeconds(60); + params3.setTaskStartToCloseTimeoutSeconds(30); + params3.setCronOverlapPolicy(3); + + assertEquals(params1, params2); + assertNotEquals(params1, params3); + assertEquals(params1.hashCode(), params2.hashCode()); + assertNotEquals(params1.hashCode(), params3.hashCode()); + } + + @Test + public void testCronOverlapPolicyInToString() { + StartWorkflowExecutionParameters params = new StartWorkflowExecutionParameters(); + params.setWorkflowId("workflow123"); + params.setWorkflowType(new WorkflowType().setName("sampleWorkflow")); + params.setTaskList("taskList1"); + params.setInput(new byte[] {1, 2, 3}); + params.setExecutionStartToCloseTimeoutSeconds(60); + params.setTaskStartToCloseTimeoutSeconds(30); + params.setCronOverlapPolicy(2); + + String toString = params.toString(); + assertTrue(toString.contains("cronOverlapPolicy=2")); + } + + @Test + public void testCronOverlapPolicyInCopy() { + StartWorkflowExecutionParameters original = new StartWorkflowExecutionParameters(); + original.setWorkflowId("workflow123"); + original.setWorkflowType(new WorkflowType().setName("sampleWorkflow")); + original.setTaskList("taskList1"); + original.setInput(new byte[] {1, 2, 3}); + original.setExecutionStartToCloseTimeoutSeconds(60); + original.setTaskStartToCloseTimeoutSeconds(30); + original.setCronOverlapPolicy(2); + + StartWorkflowExecutionParameters copy = original.copy(); + assertEquals(original.getCronOverlapPolicy(), copy.getCronOverlapPolicy()); + assertEquals(original, copy); + } + + @Test + public void testFromWorkflowOptionsWithCronOverlapPolicy() { + WorkflowOptions options = + new WorkflowOptions.Builder() + .setTaskList("test-task-list") + .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) + .setCronOverlapPolicy(2) + .build(); + + StartWorkflowExecutionParameters params = + StartWorkflowExecutionParameters.fromWorkflowOptions(options); + assertEquals(2, params.getCronOverlapPolicy()); + } + + @Test + public void testFromWorkflowOptionsWithoutCronOverlapPolicy() { + WorkflowOptions options = + new WorkflowOptions.Builder() + .setTaskList("test-task-list") + .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) + .build(); + + StartWorkflowExecutionParameters params = + StartWorkflowExecutionParameters.fromWorkflowOptions(options); + assertEquals(0, params.getCronOverlapPolicy()); // default value + } + + @Test + public void testCronOverlapPolicyDefaultValue() { + StartWorkflowExecutionParameters params = new StartWorkflowExecutionParameters(); + assertEquals(0, params.getCronOverlapPolicy()); // should default to 0 } } diff --git a/src/test/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParametersTest.java b/src/test/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParametersTest.java index 6e0b36248..9b6c3994e 100644 --- a/src/test/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParametersTest.java +++ b/src/test/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParametersTest.java @@ -17,6 +17,7 @@ import static junit.framework.TestCase.assertEquals; import static junit.framework.TestCase.assertNotNull; import static junit.framework.TestCase.assertTrue; +import static org.junit.Assert.assertNotEquals; import com.uber.cadence.ParentClosePolicy; import com.uber.cadence.WorkflowIdReusePolicy; @@ -41,6 +42,7 @@ public void testBuilderAndGetters() { WorkflowIdReusePolicy reusePolicy = WorkflowIdReusePolicy.AllowDuplicate; RetryParameters retryParameters = new RetryParameters(); String cronSchedule = "* * * * *"; + int cronOverlapPolicy = 2; Map memo = new HashMap<>(); memo.put("key1", "value1"); Map searchAttributes = new HashMap<>(); @@ -62,6 +64,7 @@ public void testBuilderAndGetters() { .setWorkflowIdReusePolicy(reusePolicy) .setRetryParameters(retryParameters) .setCronSchedule(cronSchedule) + .setCronOverlapPolicy(cronOverlapPolicy) .setMemo(memo) .setSearchAttributes(searchAttributes) .setContext(context) @@ -78,6 +81,7 @@ public void testBuilderAndGetters() { assertEquals(reusePolicy, parameters.getWorkflowIdReusePolicy()); assertEquals(retryParameters, parameters.getRetryParameters()); assertEquals(cronSchedule, parameters.getCronSchedule()); + assertEquals(cronOverlapPolicy, parameters.getCronOverlapPolicy()); assertEquals(memo, parameters.getMemo()); assertEquals(searchAttributes, parameters.getSearchAttributes()); assertEquals(context, parameters.getContext()); @@ -172,4 +176,274 @@ public void testToString() { assertTrue(parameters.toString().contains("testControl")); assertTrue(parameters.toString().contains("1000")); } + + @Test + public void testCronOverlapPolicyField() { + String domain = "testDomain"; + String control = "testControl"; + long executionTimeout = 1000L; + byte[] input = {1, 2, 3}; + String taskList = "testTaskList"; + long taskTimeout = 2000L; + String workflowId = "testWorkflowId"; + WorkflowType workflowType = new WorkflowType().setName("testWorkflowType"); + WorkflowIdReusePolicy reusePolicy = WorkflowIdReusePolicy.AllowDuplicate; + RetryParameters retryParameters = new RetryParameters(); + String cronSchedule = "* * * * *"; + int cronOverlapPolicy = 2; + Map memo = new HashMap<>(); + memo.put("key1", "value1"); + Map searchAttributes = new HashMap<>(); + searchAttributes.put("key2", "value2"); + Map context = new HashMap<>(); + context.put("key3", new byte[] {4, 5, 6}); + ParentClosePolicy parentClosePolicy = ParentClosePolicy.TERMINATE; + + StartChildWorkflowExecutionParameters parameters = + new StartChildWorkflowExecutionParameters.Builder() + .setDomain(domain) + .setControl(control) + .setExecutionStartToCloseTimeoutSeconds(executionTimeout) + .setInput(input) + .setTaskList(taskList) + .setTaskStartToCloseTimeoutSeconds(taskTimeout) + .setWorkflowId(workflowId) + .setWorkflowType(workflowType) + .setWorkflowIdReusePolicy(reusePolicy) + .setRetryParameters(retryParameters) + .setCronSchedule(cronSchedule) + .setCronOverlapPolicy(cronOverlapPolicy) + .setMemo(memo) + .setSearchAttributes(searchAttributes) + .setContext(context) + .setParentClosePolicy(parentClosePolicy) + .build(); + + assertEquals(cronOverlapPolicy, parameters.getCronOverlapPolicy()); + } + + @Test + public void testCronOverlapPolicyInEqualsAndHashCode() { + String domain = "testDomain"; + String control = "testControl"; + long executionTimeout = 1000L; + byte[] input = {1, 2, 3}; + String taskList = "testTaskList"; + long taskTimeout = 2000L; + String workflowId = "testWorkflowId"; + WorkflowType workflowType = new WorkflowType().setName("testWorkflowType"); + WorkflowIdReusePolicy reusePolicy = WorkflowIdReusePolicy.AllowDuplicate; + RetryParameters retryParameters = new RetryParameters(); + String cronSchedule = "* * * * *"; + int cronOverlapPolicy = 2; + Map memo = new HashMap<>(); + memo.put("key1", "value1"); + Map searchAttributes = new HashMap<>(); + searchAttributes.put("key2", "value2"); + Map context = new HashMap<>(); + context.put("key3", new byte[] {4, 5, 6}); + ParentClosePolicy parentClosePolicy = ParentClosePolicy.TERMINATE; + + StartChildWorkflowExecutionParameters params1 = + new StartChildWorkflowExecutionParameters.Builder() + .setDomain(domain) + .setControl(control) + .setExecutionStartToCloseTimeoutSeconds(executionTimeout) + .setInput(input) + .setTaskList(taskList) + .setTaskStartToCloseTimeoutSeconds(taskTimeout) + .setWorkflowId(workflowId) + .setWorkflowType(workflowType) + .setWorkflowIdReusePolicy(reusePolicy) + .setRetryParameters(retryParameters) + .setCronSchedule(cronSchedule) + .setCronOverlapPolicy(2) + .setMemo(memo) + .setSearchAttributes(searchAttributes) + .setContext(context) + .setParentClosePolicy(parentClosePolicy) + .build(); + + StartChildWorkflowExecutionParameters params2 = + new StartChildWorkflowExecutionParameters.Builder() + .setDomain(domain) + .setControl(control) + .setExecutionStartToCloseTimeoutSeconds(executionTimeout) + .setInput(input) + .setTaskList(taskList) + .setTaskStartToCloseTimeoutSeconds(taskTimeout) + .setWorkflowId(workflowId) + .setWorkflowType(workflowType) + .setWorkflowIdReusePolicy(reusePolicy) + .setRetryParameters(retryParameters) + .setCronSchedule(cronSchedule) + .setCronOverlapPolicy(2) + .setMemo(memo) + .setSearchAttributes(searchAttributes) + .setContext(context) + .setParentClosePolicy(parentClosePolicy) + .build(); + + StartChildWorkflowExecutionParameters params3 = + new StartChildWorkflowExecutionParameters.Builder() + .setDomain(domain) + .setControl(control) + .setExecutionStartToCloseTimeoutSeconds(executionTimeout) + .setInput(input) + .setTaskList(taskList) + .setTaskStartToCloseTimeoutSeconds(taskTimeout) + .setWorkflowId(workflowId) + .setWorkflowType(workflowType) + .setWorkflowIdReusePolicy(reusePolicy) + .setRetryParameters(retryParameters) + .setCronSchedule(cronSchedule) + .setCronOverlapPolicy(3) + .setMemo(memo) + .setSearchAttributes(searchAttributes) + .setContext(context) + .setParentClosePolicy(parentClosePolicy) + .build(); + + assertEquals(params1, params2); + assertNotEquals(params1, params3); + assertEquals(params1.hashCode(), params2.hashCode()); + assertNotEquals(params1.hashCode(), params3.hashCode()); + } + + @Test + public void testCronOverlapPolicyInToString() { + String domain = "testDomain"; + String control = "testControl"; + long executionTimeout = 1000L; + byte[] input = {1, 2, 3}; + String taskList = "testTaskList"; + long taskTimeout = 2000L; + String workflowId = "testWorkflowId"; + WorkflowType workflowType = new WorkflowType().setName("testWorkflowType"); + WorkflowIdReusePolicy reusePolicy = WorkflowIdReusePolicy.AllowDuplicate; + RetryParameters retryParameters = new RetryParameters(); + String cronSchedule = "* * * * *"; + int cronOverlapPolicy = 2; + Map memo = new HashMap<>(); + memo.put("key1", "value1"); + Map searchAttributes = new HashMap<>(); + searchAttributes.put("key2", "value2"); + Map context = new HashMap<>(); + context.put("key3", new byte[] {4, 5, 6}); + ParentClosePolicy parentClosePolicy = ParentClosePolicy.TERMINATE; + + StartChildWorkflowExecutionParameters parameters = + new StartChildWorkflowExecutionParameters.Builder() + .setDomain(domain) + .setControl(control) + .setExecutionStartToCloseTimeoutSeconds(executionTimeout) + .setInput(input) + .setTaskList(taskList) + .setTaskStartToCloseTimeoutSeconds(taskTimeout) + .setWorkflowId(workflowId) + .setWorkflowType(workflowType) + .setWorkflowIdReusePolicy(reusePolicy) + .setRetryParameters(retryParameters) + .setCronSchedule(cronSchedule) + .setCronOverlapPolicy(cronOverlapPolicy) + .setMemo(memo) + .setSearchAttributes(searchAttributes) + .setContext(context) + .setParentClosePolicy(parentClosePolicy) + .build(); + + String toString = parameters.toString(); + assertTrue(toString.contains("cronOverlapPolicy=" + cronOverlapPolicy)); + } + + @Test + public void testCronOverlapPolicyInCopy() { + String domain = "testDomain"; + String control = "testControl"; + long executionTimeout = 1000L; + byte[] input = {1, 2, 3}; + String taskList = "testTaskList"; + long taskTimeout = 2000L; + String workflowId = "testWorkflowId"; + WorkflowType workflowType = new WorkflowType().setName("testWorkflowType"); + WorkflowIdReusePolicy reusePolicy = WorkflowIdReusePolicy.AllowDuplicate; + RetryParameters retryParameters = new RetryParameters(); + String cronSchedule = "* * * * *"; + int cronOverlapPolicy = 2; + Map memo = new HashMap<>(); + memo.put("key1", "value1"); + Map searchAttributes = new HashMap<>(); + searchAttributes.put("key2", "value2"); + Map context = new HashMap<>(); + context.put("key3", new byte[] {4, 5, 6}); + ParentClosePolicy parentClosePolicy = ParentClosePolicy.TERMINATE; + + StartChildWorkflowExecutionParameters original = + new StartChildWorkflowExecutionParameters.Builder() + .setDomain(domain) + .setControl(control) + .setExecutionStartToCloseTimeoutSeconds(executionTimeout) + .setInput(input) + .setTaskList(taskList) + .setTaskStartToCloseTimeoutSeconds(taskTimeout) + .setWorkflowId(workflowId) + .setWorkflowType(workflowType) + .setWorkflowIdReusePolicy(reusePolicy) + .setRetryParameters(retryParameters) + .setCronSchedule(cronSchedule) + .setCronOverlapPolicy(cronOverlapPolicy) + .setMemo(memo) + .setSearchAttributes(searchAttributes) + .setContext(context) + .setParentClosePolicy(parentClosePolicy) + .build(); + + StartChildWorkflowExecutionParameters copy = original.copy(); + assertEquals(original.getCronOverlapPolicy(), copy.getCronOverlapPolicy()); + assertEquals(original, copy); + } + + @Test + public void testCronOverlapPolicyDefaultValue() { + String domain = "testDomain"; + String control = "testControl"; + long executionTimeout = 1000L; + byte[] input = {1, 2, 3}; + String taskList = "testTaskList"; + long taskTimeout = 2000L; + String workflowId = "testWorkflowId"; + WorkflowType workflowType = new WorkflowType().setName("testWorkflowType"); + WorkflowIdReusePolicy reusePolicy = WorkflowIdReusePolicy.AllowDuplicate; + RetryParameters retryParameters = new RetryParameters(); + String cronSchedule = "* * * * *"; + int cronOverlapPolicy = 2; + Map memo = new HashMap<>(); + memo.put("key1", "value1"); + Map searchAttributes = new HashMap<>(); + searchAttributes.put("key2", "value2"); + Map context = new HashMap<>(); + context.put("key3", new byte[] {4, 5, 6}); + ParentClosePolicy parentClosePolicy = ParentClosePolicy.TERMINATE; + + StartChildWorkflowExecutionParameters parameters = + new StartChildWorkflowExecutionParameters.Builder() + .setDomain(domain) + .setControl(control) + .setExecutionStartToCloseTimeoutSeconds(executionTimeout) + .setInput(input) + .setTaskList(taskList) + .setTaskStartToCloseTimeoutSeconds(taskTimeout) + .setWorkflowId(workflowId) + .setWorkflowType(workflowType) + .setWorkflowIdReusePolicy(reusePolicy) + .setRetryParameters(retryParameters) + .setCronSchedule(cronSchedule) + .setMemo(memo) + .setSearchAttributes(searchAttributes) + .setContext(context) + .setParentClosePolicy(parentClosePolicy) + .build(); + + assertEquals(0, parameters.getCronOverlapPolicy()); // should default to 0 + } } From 46edfe6fec9ec93e9c0d9d964461a78b209060ae Mon Sep 17 00:00:00 2001 From: Tim Li Date: Tue, 12 Aug 2025 09:06:47 -0700 Subject: [PATCH 2/4] remove excess comment --- .../cadence/internal/compatibility/proto/DecisionMapper.java | 2 -- .../cadence/internal/compatibility/proto/RequestMapper.java | 1 - .../internal/external/GenericWorkflowClientExternalImpl.java | 2 -- 3 files changed, 5 deletions(-) diff --git a/src/main/java/com/uber/cadence/internal/compatibility/proto/DecisionMapper.java b/src/main/java/com/uber/cadence/internal/compatibility/proto/DecisionMapper.java index fabd5849b..a3d5e5ca5 100644 --- a/src/main/java/com/uber/cadence/internal/compatibility/proto/DecisionMapper.java +++ b/src/main/java/com/uber/cadence/internal/compatibility/proto/DecisionMapper.java @@ -194,7 +194,6 @@ static Decision decision(com.uber.cadence.Decision d) { if (attr.getCronSchedule() != null) { builder.setCronSchedule(attr.getCronSchedule()); } - // cronOverlapPolicy not mapped in proto path yet decision.setContinueAsNewWorkflowExecutionDecisionAttributes(builder); } break; @@ -227,7 +226,6 @@ static Decision decision(com.uber.cadence.Decision d) { if (attr.getCronSchedule() != null) { builder.setCronSchedule(attr.getCronSchedule()); } - // cronOverlapPolicy not mapped in proto path yet decision.setStartChildWorkflowExecutionDecisionAttributes(builder); } break; diff --git a/src/main/java/com/uber/cadence/internal/compatibility/proto/RequestMapper.java b/src/main/java/com/uber/cadence/internal/compatibility/proto/RequestMapper.java index 0584ae896..c07d67361 100644 --- a/src/main/java/com/uber/cadence/internal/compatibility/proto/RequestMapper.java +++ b/src/main/java/com/uber/cadence/internal/compatibility/proto/RequestMapper.java @@ -545,7 +545,6 @@ public static StartWorkflowExecutionRequest startWorkflowExecutionRequest( if (t.getCronSchedule() != null) { request.setCronSchedule(t.getCronSchedule()); } - // cronOverlapPolicy not mapped in proto path yet if (t.getIdentity() != null) { request.setIdentity(t.getIdentity()); } diff --git a/src/main/java/com/uber/cadence/internal/external/GenericWorkflowClientExternalImpl.java b/src/main/java/com/uber/cadence/internal/external/GenericWorkflowClientExternalImpl.java index 6cc160db1..ef96cacda 100644 --- a/src/main/java/com/uber/cadence/internal/external/GenericWorkflowClientExternalImpl.java +++ b/src/main/java/com/uber/cadence/internal/external/GenericWorkflowClientExternalImpl.java @@ -275,7 +275,6 @@ private StartWorkflowExecutionRequest getStartRequest( if (!Strings.isNullOrEmpty(startParameters.getCronSchedule())) { request.setCronSchedule(startParameters.getCronSchedule()); } - // cronOverlapPolicy not supported in thrift request yet request.setMemo(toMemoThrift(startParameters.getMemo())); request.setSearchAttributes(toSearchAttributesThrift(startParameters.getSearchAttributes())); request.setHeader(toHeaderThrift(startParameters.getContext())); @@ -505,7 +504,6 @@ private SignalWithStartWorkflowExecutionRequest createSignalWithStartRequest( if (!Strings.isNullOrEmpty(startParameters.getCronSchedule())) { request.setCronSchedule(startParameters.getCronSchedule()); } - // cronOverlapPolicy not supported in thrift request yet if (startParameters.getDelayStart() != null) { request.setDelayStartSeconds((int) startParameters.getDelayStart().getSeconds()); } From de06cd959bd371d67d2367689d5eddb799921d21 Mon Sep 17 00:00:00 2001 From: Tim Li Date: Thu, 14 Aug 2025 13:24:25 -0700 Subject: [PATCH 3/4] increment idl to latest pointer --- src/main/idls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/idls b/src/main/idls index f5ac3a987..0e56e5790 160000 --- a/src/main/idls +++ b/src/main/idls @@ -1 +1 @@ -Subproject commit f5ac3a987dcaf996cf44c72064195faf76c381f3 +Subproject commit 0e56e57909d9fa738eaa8d7a9561ea16acdf51e4 From e3269cb2c7965884bc76f70b6e693c92b8ebdab6 Mon Sep 17 00:00:00 2001 From: Tim Li Date: Thu, 14 Aug 2025 13:45:22 -0700 Subject: [PATCH 4/4] fix idl merge issues --- .../uber/cadence/client/WorkflowOptions.java | 13 +++++---- .../StartWorkflowExecutionParameters.java | 13 +++++++-- ...StartChildWorkflowExecutionParameters.java | 11 +++---- .../workflow/ChildWorkflowOptions.java | 11 +++---- .../cadence/client/WorkflowOptionsTest.java | 29 ++++++++++--------- .../StartWorkflowExecutionParametersTest.java | 27 ++++++++--------- ...tChildWorkflowExecutionParametersTest.java | 21 +++++++------- 7 files changed, 69 insertions(+), 56 deletions(-) diff --git a/src/main/java/com/uber/cadence/client/WorkflowOptions.java b/src/main/java/com/uber/cadence/client/WorkflowOptions.java index eeb2594cd..73e0c6b4e 100644 --- a/src/main/java/com/uber/cadence/client/WorkflowOptions.java +++ b/src/main/java/com/uber/cadence/client/WorkflowOptions.java @@ -25,6 +25,7 @@ import com.cronutils.model.definition.CronDefinitionBuilder; import com.cronutils.parser.CronParser; import com.google.common.base.Strings; +import com.uber.cadence.CronOverlapPolicy; import com.uber.cadence.WorkflowIdReusePolicy; import com.uber.cadence.common.CronSchedule; import com.uber.cadence.common.MethodRetry; @@ -64,7 +65,7 @@ public static WorkflowOptions merge( .setRetryOptions(RetryOptions.merge(methodRetry, o.getRetryOptions())) .setCronSchedule(OptionsUtils.merge(cronAnnotation, o.getCronSchedule(), String.class)) .setMemo(o.getMemo()) - .setCronOverlapPolicy(o.cronOverlapPolicy) + .setCronOverlapPolicy(o.getCronOverlapPolicy()) .setSearchAttributes(o.getSearchAttributes()) .setContextPropagators(o.getContextPropagators()) .setDelayStart(o.delayStart) @@ -87,7 +88,7 @@ public static final class Builder { private String cronSchedule; - private int cronOverlapPolicy; + private CronOverlapPolicy cronOverlapPolicy; private Map memo; @@ -198,7 +199,7 @@ public Builder setCronSchedule(String cronSchedule) { return this; } - public Builder setCronOverlapPolicy(int cronOverlapPolicy) { + public Builder setCronOverlapPolicy(CronOverlapPolicy cronOverlapPolicy) { this.cronOverlapPolicy = cronOverlapPolicy; return this; } @@ -319,7 +320,7 @@ public WorkflowOptions validateBuildWithDefaults() { private String cronSchedule; - private int cronOverlapPolicy; + private CronOverlapPolicy cronOverlapPolicy; private Map memo; @@ -341,7 +342,7 @@ private WorkflowOptions( Map searchAttributes, List contextPropagators, Duration delayStart, - int cronOverlapPolicy) { + CronOverlapPolicy cronOverlapPolicy) { this.workflowId = workflowId; this.workflowIdReusePolicy = workflowIdReusePolicy; this.executionStartToCloseTimeout = executionStartToCloseTimeout; @@ -384,7 +385,7 @@ public String getCronSchedule() { return cronSchedule; } - public int getCronOverlapPolicy() { + public CronOverlapPolicy getCronOverlapPolicy() { return cronOverlapPolicy; } diff --git a/src/main/java/com/uber/cadence/internal/common/StartWorkflowExecutionParameters.java b/src/main/java/com/uber/cadence/internal/common/StartWorkflowExecutionParameters.java index 766a545f8..c057eb5cb 100644 --- a/src/main/java/com/uber/cadence/internal/common/StartWorkflowExecutionParameters.java +++ b/src/main/java/com/uber/cadence/internal/common/StartWorkflowExecutionParameters.java @@ -17,6 +17,7 @@ package com.uber.cadence.internal.common; +import com.uber.cadence.CronOverlapPolicy; import com.uber.cadence.WorkflowIdReusePolicy; import com.uber.cadence.WorkflowType; import com.uber.cadence.client.WorkflowOptions; @@ -56,7 +57,7 @@ public final class StartWorkflowExecutionParameters { private Duration delayStart; - private int cronOverlapPolicy; + private CronOverlapPolicy cronOverlapPolicy; /** * Returns the value of the WorkflowId property for this object. @@ -319,14 +320,20 @@ public Duration getDelayStart() { return delayStart; } - public int getCronOverlapPolicy() { + public CronOverlapPolicy getCronOverlapPolicy() { return cronOverlapPolicy; } - public void setCronOverlapPolicy(int cronOverlapPolicy) { + public void setCronOverlapPolicy(CronOverlapPolicy cronOverlapPolicy) { this.cronOverlapPolicy = cronOverlapPolicy; } + public StartWorkflowExecutionParameters withCronOverlapPolicy( + CronOverlapPolicy cronOverlapPolicy) { + this.cronOverlapPolicy = cronOverlapPolicy; + return this; + } + public StartWorkflowExecutionParameters withRetryParameters(RetryParameters retryParameters) { this.retryParameters = retryParameters; return this; diff --git a/src/main/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParameters.java b/src/main/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParameters.java index 9146c4491..48360c7b3 100644 --- a/src/main/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParameters.java +++ b/src/main/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParameters.java @@ -17,6 +17,7 @@ package com.uber.cadence.internal.replay; +import com.uber.cadence.CronOverlapPolicy; import com.uber.cadence.ParentClosePolicy; import com.uber.cadence.WorkflowIdReusePolicy; import com.uber.cadence.WorkflowType; @@ -51,7 +52,7 @@ public static final class Builder { private String cronSchedule; - private int cronOverlapPolicy; + private CronOverlapPolicy cronOverlapPolicy; private Map memo; @@ -117,7 +118,7 @@ public Builder setCronSchedule(String cronSchedule) { return this; } - public Builder setCronOverlapPolicy(int cronOverlapPolicy) { + public Builder setCronOverlapPolicy(CronOverlapPolicy cronOverlapPolicy) { this.cronOverlapPolicy = cronOverlapPolicy; return this; } @@ -185,7 +186,7 @@ public StartChildWorkflowExecutionParameters build() { private final String cronSchedule; - private final int cronOverlapPolicy; + private final CronOverlapPolicy cronOverlapPolicy; private Map memo; @@ -207,7 +208,7 @@ private StartChildWorkflowExecutionParameters( WorkflowIdReusePolicy workflowIdReusePolicy, RetryParameters retryParameters, String cronSchedule, - int cronOverlapPolicy, + CronOverlapPolicy cronOverlapPolicy, Map memo, Map searchAttributes, Map context, @@ -274,7 +275,7 @@ public String getCronSchedule() { return cronSchedule; } - public int getCronOverlapPolicy() { + public CronOverlapPolicy getCronOverlapPolicy() { return cronOverlapPolicy; } diff --git a/src/main/java/com/uber/cadence/workflow/ChildWorkflowOptions.java b/src/main/java/com/uber/cadence/workflow/ChildWorkflowOptions.java index d19d4ea1f..e82eb6f3d 100644 --- a/src/main/java/com/uber/cadence/workflow/ChildWorkflowOptions.java +++ b/src/main/java/com/uber/cadence/workflow/ChildWorkflowOptions.java @@ -19,6 +19,7 @@ import static com.uber.cadence.internal.common.OptionsUtils.roundUpToSeconds; +import com.uber.cadence.CronOverlapPolicy; import com.uber.cadence.ParentClosePolicy; import com.uber.cadence.WorkflowIdReusePolicy; import com.uber.cadence.common.CronSchedule; @@ -82,7 +83,7 @@ public static final class Builder { private String cronSchedule; - private int cronOverlapPolicy; + private CronOverlapPolicy cronOverlapPolicy; private ParentClosePolicy parentClosePolicy; @@ -203,7 +204,7 @@ public Builder setCronSchedule(String cronSchedule) { return this; } - public Builder setCronOverlapPolicy(int cronOverlapPolicy) { + public Builder setCronOverlapPolicy(CronOverlapPolicy cronOverlapPolicy) { this.cronOverlapPolicy = cronOverlapPolicy; return this; } @@ -283,7 +284,7 @@ public ChildWorkflowOptions validateAndBuildWithDefaults() { private final String cronSchedule; - private final int cronOverlapPolicy; + private final CronOverlapPolicy cronOverlapPolicy; private final ParentClosePolicy parentClosePolicy; @@ -302,7 +303,7 @@ private ChildWorkflowOptions( String taskList, RetryOptions retryOptions, String cronSchedule, - int cronOverlapPolicy, + CronOverlapPolicy cronOverlapPolicy, ParentClosePolicy parentClosePolicy, Map memo, Map searchAttributes, @@ -354,7 +355,7 @@ public String getCronSchedule() { return cronSchedule; } - public int getCronOverlapPolicy() { + public CronOverlapPolicy getCronOverlapPolicy() { return cronOverlapPolicy; } diff --git a/src/test/java/com/uber/cadence/client/WorkflowOptionsTest.java b/src/test/java/com/uber/cadence/client/WorkflowOptionsTest.java index ffc6de675..79cc6c665 100644 --- a/src/test/java/com/uber/cadence/client/WorkflowOptionsTest.java +++ b/src/test/java/com/uber/cadence/client/WorkflowOptionsTest.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; +import com.uber.cadence.CronOverlapPolicy; import com.uber.cadence.WorkflowIdReusePolicy; import com.uber.cadence.common.CronSchedule; import com.uber.cadence.common.MethodRetry; @@ -48,7 +49,7 @@ public void testOnlyOptionsAndEmptyAnnotationsPresent() throws NoSuchMethodExcep .setExecutionStartToCloseTimeout(Duration.ofSeconds(321)) .setTaskStartToCloseTimeout(Duration.ofSeconds(13)) .setWorkflowIdReusePolicy(WorkflowIdReusePolicy.RejectDuplicate) - .setCronOverlapPolicy(2) + .setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE) .setMemo(getTestMemo()) .setSearchAttributes(getTestSearchAttributes()) .build(); @@ -57,7 +58,7 @@ public void testOnlyOptionsAndEmptyAnnotationsPresent() throws NoSuchMethodExcep .getMethod("defaultWorkflowOptions") .getAnnotation(WorkflowMethod.class); Assert.assertEquals(o, WorkflowOptions.merge(a, null, null, o)); - Assert.assertEquals(2, o.getCronOverlapPolicy()); + Assert.assertEquals(CronOverlapPolicy.BUFFERONE, o.getCronOverlapPolicy()); } @WorkflowMethod( @@ -204,10 +205,10 @@ public void testCronOverlapPolicy() { new WorkflowOptions.Builder() .setTaskList("test-task-list") .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) - .setCronOverlapPolicy(2) + .setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE) .build(); - assertEquals(2, options.getCronOverlapPolicy()); + assertEquals(CronOverlapPolicy.BUFFERONE, options.getCronOverlapPolicy()); } @Test @@ -216,21 +217,21 @@ public void testCronOverlapPolicyInMerge() { new WorkflowOptions.Builder() .setTaskList("test-task-list") .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) - .setCronOverlapPolicy(1) + .setCronOverlapPolicy(CronOverlapPolicy.SKIPPED) .build(); WorkflowOptions override = new WorkflowOptions.Builder() .setTaskList("test-task-list") .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) - .setCronOverlapPolicy(3) + .setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE) .build(); WorkflowOptions merged = WorkflowOptions.merge(null, null, null, override); - assertEquals(3, merged.getCronOverlapPolicy()); + assertEquals(CronOverlapPolicy.BUFFERONE, merged.getCronOverlapPolicy()); WorkflowOptions mergedWithBase = WorkflowOptions.merge(null, null, null, base); - assertEquals(1, mergedWithBase.getCronOverlapPolicy()); + assertEquals(CronOverlapPolicy.SKIPPED, mergedWithBase.getCronOverlapPolicy()); } @Test @@ -239,21 +240,21 @@ public void testCronOverlapPolicyEqualsAndHashCode() { new WorkflowOptions.Builder() .setTaskList("test-task-list") .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) - .setCronOverlapPolicy(2) + .setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE) .build(); WorkflowOptions options2 = new WorkflowOptions.Builder() .setTaskList("test-task-list") .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) - .setCronOverlapPolicy(2) + .setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE) .build(); WorkflowOptions options3 = new WorkflowOptions.Builder() .setTaskList("test-task-list") .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) - .setCronOverlapPolicy(3) + .setCronOverlapPolicy(CronOverlapPolicy.SKIPPED) .build(); assertEquals(options1, options2); @@ -268,11 +269,11 @@ public void testCronOverlapPolicyToString() { new WorkflowOptions.Builder() .setTaskList("test-task-list") .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) - .setCronOverlapPolicy(2) + .setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE) .build(); String toString = options.toString(); - assertTrue(toString.contains("cronOverlapPolicy=2")); + assertTrue(toString.contains("cronOverlapPolicy=BUFFERONE")); } @Test @@ -281,7 +282,7 @@ public void testCronOverlapPolicyCopy() { new WorkflowOptions.Builder() .setTaskList("test-task-list") .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) - .setCronOverlapPolicy(2) + .setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE) .build(); WorkflowOptions copy = new WorkflowOptions.Builder(original).build(); diff --git a/src/test/java/com/uber/cadence/internal/common/StartWorkflowExecutionParametersTest.java b/src/test/java/com/uber/cadence/internal/common/StartWorkflowExecutionParametersTest.java index ba667b8df..2db423296 100644 --- a/src/test/java/com/uber/cadence/internal/common/StartWorkflowExecutionParametersTest.java +++ b/src/test/java/com/uber/cadence/internal/common/StartWorkflowExecutionParametersTest.java @@ -17,6 +17,7 @@ import static junit.framework.TestCase.assertEquals; import static org.junit.Assert.*; +import com.uber.cadence.CronOverlapPolicy; import com.uber.cadence.WorkflowType; import com.uber.cadence.client.WorkflowOptions; import java.time.Duration; @@ -66,7 +67,7 @@ public void testToString() { + "maximumAttempts=0, " + "nonRetriableErrorReasons=null, expirationIntervalInSeconds=0}, " + "cronSchedule='* * * * *', " - + "cronOverlapPolicy=0, " + + "cronOverlapPolicy=null, " + "memo='null', searchAttributes='null, context='null, delayStart='null'}"; assertEquals(expectedString, params1.toString()); @@ -133,8 +134,8 @@ public void testCopy() { @Test public void testCronOverlapPolicyField() { StartWorkflowExecutionParameters params = new StartWorkflowExecutionParameters(); - params.setCronOverlapPolicy(2); - assertEquals(2, params.getCronOverlapPolicy()); + params.setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE); + assertEquals(CronOverlapPolicy.BUFFERONE, params.getCronOverlapPolicy()); } @Test @@ -146,7 +147,7 @@ public void testCronOverlapPolicyInEqualsAndHashCode() { params1.setInput(new byte[] {1, 2, 3}); params1.setExecutionStartToCloseTimeoutSeconds(60); params1.setTaskStartToCloseTimeoutSeconds(30); - params1.setCronOverlapPolicy(2); + params1.setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE); StartWorkflowExecutionParameters params2 = new StartWorkflowExecutionParameters(); params2.setWorkflowId("workflow123"); @@ -155,7 +156,7 @@ public void testCronOverlapPolicyInEqualsAndHashCode() { params2.setInput(new byte[] {1, 2, 3}); params2.setExecutionStartToCloseTimeoutSeconds(60); params2.setTaskStartToCloseTimeoutSeconds(30); - params2.setCronOverlapPolicy(2); + params2.setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE); StartWorkflowExecutionParameters params3 = new StartWorkflowExecutionParameters(); params3.setWorkflowId("workflow123"); @@ -164,7 +165,7 @@ public void testCronOverlapPolicyInEqualsAndHashCode() { params3.setInput(new byte[] {1, 2, 3}); params3.setExecutionStartToCloseTimeoutSeconds(60); params3.setTaskStartToCloseTimeoutSeconds(30); - params3.setCronOverlapPolicy(3); + params3.setCronOverlapPolicy(CronOverlapPolicy.SKIPPED); assertEquals(params1, params2); assertNotEquals(params1, params3); @@ -181,10 +182,10 @@ public void testCronOverlapPolicyInToString() { params.setInput(new byte[] {1, 2, 3}); params.setExecutionStartToCloseTimeoutSeconds(60); params.setTaskStartToCloseTimeoutSeconds(30); - params.setCronOverlapPolicy(2); + params.setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE); String toString = params.toString(); - assertTrue(toString.contains("cronOverlapPolicy=2")); + assertTrue(toString.contains("cronOverlapPolicy=BUFFERONE")); } @Test @@ -196,7 +197,7 @@ public void testCronOverlapPolicyInCopy() { original.setInput(new byte[] {1, 2, 3}); original.setExecutionStartToCloseTimeoutSeconds(60); original.setTaskStartToCloseTimeoutSeconds(30); - original.setCronOverlapPolicy(2); + original.setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE); StartWorkflowExecutionParameters copy = original.copy(); assertEquals(original.getCronOverlapPolicy(), copy.getCronOverlapPolicy()); @@ -209,12 +210,12 @@ public void testFromWorkflowOptionsWithCronOverlapPolicy() { new WorkflowOptions.Builder() .setTaskList("test-task-list") .setExecutionStartToCloseTimeout(Duration.ofSeconds(10)) - .setCronOverlapPolicy(2) + .setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE) .build(); StartWorkflowExecutionParameters params = StartWorkflowExecutionParameters.fromWorkflowOptions(options); - assertEquals(2, params.getCronOverlapPolicy()); + assertEquals(CronOverlapPolicy.BUFFERONE, params.getCronOverlapPolicy()); } @Test @@ -227,12 +228,12 @@ public void testFromWorkflowOptionsWithoutCronOverlapPolicy() { StartWorkflowExecutionParameters params = StartWorkflowExecutionParameters.fromWorkflowOptions(options); - assertEquals(0, params.getCronOverlapPolicy()); // default value + assertEquals(null, params.getCronOverlapPolicy()); // default value } @Test public void testCronOverlapPolicyDefaultValue() { StartWorkflowExecutionParameters params = new StartWorkflowExecutionParameters(); - assertEquals(0, params.getCronOverlapPolicy()); // should default to 0 + assertEquals(null, params.getCronOverlapPolicy()); // should default to null } } diff --git a/src/test/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParametersTest.java b/src/test/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParametersTest.java index 9b6c3994e..bd6e87c2a 100644 --- a/src/test/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParametersTest.java +++ b/src/test/java/com/uber/cadence/internal/replay/StartChildWorkflowExecutionParametersTest.java @@ -19,6 +19,7 @@ import static junit.framework.TestCase.assertTrue; import static org.junit.Assert.assertNotEquals; +import com.uber.cadence.CronOverlapPolicy; import com.uber.cadence.ParentClosePolicy; import com.uber.cadence.WorkflowIdReusePolicy; import com.uber.cadence.WorkflowType; @@ -42,7 +43,7 @@ public void testBuilderAndGetters() { WorkflowIdReusePolicy reusePolicy = WorkflowIdReusePolicy.AllowDuplicate; RetryParameters retryParameters = new RetryParameters(); String cronSchedule = "* * * * *"; - int cronOverlapPolicy = 2; + CronOverlapPolicy cronOverlapPolicy = CronOverlapPolicy.BUFFERONE; Map memo = new HashMap<>(); memo.put("key1", "value1"); Map searchAttributes = new HashMap<>(); @@ -190,7 +191,7 @@ public void testCronOverlapPolicyField() { WorkflowIdReusePolicy reusePolicy = WorkflowIdReusePolicy.AllowDuplicate; RetryParameters retryParameters = new RetryParameters(); String cronSchedule = "* * * * *"; - int cronOverlapPolicy = 2; + CronOverlapPolicy cronOverlapPolicy = CronOverlapPolicy.BUFFERONE; Map memo = new HashMap<>(); memo.put("key1", "value1"); Map searchAttributes = new HashMap<>(); @@ -219,7 +220,7 @@ public void testCronOverlapPolicyField() { .setParentClosePolicy(parentClosePolicy) .build(); - assertEquals(cronOverlapPolicy, parameters.getCronOverlapPolicy()); + assertEquals(CronOverlapPolicy.BUFFERONE, parameters.getCronOverlapPolicy()); } @Test @@ -235,7 +236,7 @@ public void testCronOverlapPolicyInEqualsAndHashCode() { WorkflowIdReusePolicy reusePolicy = WorkflowIdReusePolicy.AllowDuplicate; RetryParameters retryParameters = new RetryParameters(); String cronSchedule = "* * * * *"; - int cronOverlapPolicy = 2; + CronOverlapPolicy cronOverlapPolicy = CronOverlapPolicy.BUFFERONE; Map memo = new HashMap<>(); memo.put("key1", "value1"); Map searchAttributes = new HashMap<>(); @@ -257,7 +258,7 @@ public void testCronOverlapPolicyInEqualsAndHashCode() { .setWorkflowIdReusePolicy(reusePolicy) .setRetryParameters(retryParameters) .setCronSchedule(cronSchedule) - .setCronOverlapPolicy(2) + .setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE) .setMemo(memo) .setSearchAttributes(searchAttributes) .setContext(context) @@ -277,7 +278,7 @@ public void testCronOverlapPolicyInEqualsAndHashCode() { .setWorkflowIdReusePolicy(reusePolicy) .setRetryParameters(retryParameters) .setCronSchedule(cronSchedule) - .setCronOverlapPolicy(2) + .setCronOverlapPolicy(CronOverlapPolicy.BUFFERONE) .setMemo(memo) .setSearchAttributes(searchAttributes) .setContext(context) @@ -297,7 +298,7 @@ public void testCronOverlapPolicyInEqualsAndHashCode() { .setWorkflowIdReusePolicy(reusePolicy) .setRetryParameters(retryParameters) .setCronSchedule(cronSchedule) - .setCronOverlapPolicy(3) + .setCronOverlapPolicy(CronOverlapPolicy.SKIPPED) .setMemo(memo) .setSearchAttributes(searchAttributes) .setContext(context) @@ -323,7 +324,7 @@ public void testCronOverlapPolicyInToString() { WorkflowIdReusePolicy reusePolicy = WorkflowIdReusePolicy.AllowDuplicate; RetryParameters retryParameters = new RetryParameters(); String cronSchedule = "* * * * *"; - int cronOverlapPolicy = 2; + CronOverlapPolicy cronOverlapPolicy = CronOverlapPolicy.BUFFERONE; Map memo = new HashMap<>(); memo.put("key1", "value1"); Map searchAttributes = new HashMap<>(); @@ -369,7 +370,7 @@ public void testCronOverlapPolicyInCopy() { WorkflowIdReusePolicy reusePolicy = WorkflowIdReusePolicy.AllowDuplicate; RetryParameters retryParameters = new RetryParameters(); String cronSchedule = "* * * * *"; - int cronOverlapPolicy = 2; + CronOverlapPolicy cronOverlapPolicy = CronOverlapPolicy.BUFFERONE; Map memo = new HashMap<>(); memo.put("key1", "value1"); Map searchAttributes = new HashMap<>(); @@ -416,7 +417,7 @@ public void testCronOverlapPolicyDefaultValue() { WorkflowIdReusePolicy reusePolicy = WorkflowIdReusePolicy.AllowDuplicate; RetryParameters retryParameters = new RetryParameters(); String cronSchedule = "* * * * *"; - int cronOverlapPolicy = 2; + CronOverlapPolicy cronOverlapPolicy = CronOverlapPolicy.BUFFERONE; Map memo = new HashMap<>(); memo.put("key1", "value1"); Map searchAttributes = new HashMap<>();