1313
1414import static io .iworkflow .core .StateMovement .RESERVED_STATE_ID_PREFIX ;
1515import static io .iworkflow .core .WorkflowState .shouldSkipWaitUntil ;
16- import static io .iworkflow .core .WorkflowStateOptionsExtension .deepCopyStateOptions ;
1716
1817public class StateMovementMapper {
1918
@@ -31,10 +30,10 @@ public static StateMovement toGenerated(final io.iworkflow.core.StateMovement st
3130 // Try to get the overrode stateOptions, if it's null, get the stateOptions from stateDef
3231 WorkflowStateOptions stateOptions ;
3332 if (stateMovement .getStateOptionsOverride ().isPresent ()) {
34- // Always deep copy the state options so we don't modify the original
35- stateOptions = deepCopyStateOptions (stateMovement .getStateOptionsOverride ().get ());
33+ stateOptions =
34+ toIdlWorkflowStateOptionsWithValidation (stateMovement .getStateOptionsOverride ().get (), stateMovement . getStateId ());
3635 } else {
37- stateOptions = StateMovementMapper . validateAndGetStateOptionsCopy (stateDef );
36+ stateOptions = toIdlWorkflowStateOptionsWithValidation (stateDef );
3837 }
3938
4039 if (shouldSkipWaitUntil (stateDef .getWorkflowState ())) {
@@ -66,7 +65,7 @@ public static void autoFillFailureProceedingStateOptions(WorkflowStateOptions st
6665 // fill the state options for the proceeding state
6766 String proceedStateId = stateOptions .getExecuteApiFailureProceedStateId ();
6867 final StateDef proceedStatDef = registry .getWorkflowState (workflowType , proceedStateId );
69- WorkflowStateOptions proceedStateOptions = StateMovementMapper . validateAndGetStateOptionsCopy (proceedStatDef );
68+ WorkflowStateOptions proceedStateOptions = toIdlWorkflowStateOptionsWithValidation (proceedStatDef );
7069 if (proceedStateOptions != null &&
7170 proceedStateOptions .getExecuteApiFailurePolicy () == ExecuteApiFailurePolicy .PROCEED_TO_CONFIGURED_STATE ) {
7271 throw new WorkflowDefinitionException ("nested failure handling is not supported. You cannot set a failure proceeding state on top of another failure proceeding state." );
@@ -84,35 +83,100 @@ public static void autoFillFailureProceedingStateOptions(WorkflowStateOptions st
8483 }
8584 }
8685
87- public static WorkflowStateOptions validateAndGetStateOptionsCopy (final StateDef stateDef ){
88- final WorkflowState state = stateDef .getWorkflowState ();
89- // Always deep copy the state options so we don't modify the original
90- WorkflowStateOptions stateOptions = deepCopyStateOptions (state .getStateOptions ());
91- if (stateOptions == null ){
92- return null ;
93- }
94- if (stateOptions .getExecuteApiFailurePolicy () == ExecuteApiFailurePolicy .PROCEED_TO_CONFIGURED_STATE ){
86+ /**
87+ * Validates if the required fields are present when the {@link WorkflowStateOptions} is configured to proceed on Execute
88+ * API Failure.
89+ * @param stateOptions the state options to validate.
90+ * @param stateId the unique ID of the state
91+ */
92+ private static void validateExecuteApiFailurePolicy (WorkflowStateOptions stateOptions , String stateId ) {
93+ // Validate required fields if Execute failure policy is configured to proceed
94+ if (stateOptions .getExecuteApiFailurePolicy () == ExecuteApiFailurePolicy .PROCEED_TO_CONFIGURED_STATE ) {
9595 // retry policy must be set
96- if (stateOptions .getExecuteApiRetryPolicy () == null ){
97- throw new WorkflowDefinitionException ("RetryPolicy must be set for the execute " + state . getStateId () );
96+ if (stateOptions .getExecuteApiRetryPolicy () == null ) {
97+ throw new WorkflowDefinitionException ("RetryPolicy must be set for the execute " + stateId );
9898 }
9999 final RetryPolicy policy = stateOptions .getExecuteApiRetryPolicy ();
100100 // either maximumAttempts or maximumAttemptsDurationSeconds must be set and greater than zero
101- if (policy .getMaximumAttempts () == null && policy .getMaximumAttemptsDurationSeconds () == null ){
102- throw new WorkflowDefinitionException ("Either maximumAttempts or maximumAttemptsDurationSeconds must be set for the execute " +state .getStateId ());
101+ if (policy .getMaximumAttempts () == null && policy .getMaximumAttemptsDurationSeconds () == null ) {
102+ throw new WorkflowDefinitionException (
103+ "Either maximumAttempts or maximumAttemptsDurationSeconds must be set for the execute " + stateId );
103104 }
104105 }
105- if (stateOptions .getWaitUntilApiFailurePolicy () == WaitUntilApiFailurePolicy .FAIL_WORKFLOW_ON_FAILURE ){
106+ }
107+
108+ /**
109+ * Validates if the required fields are present when the {@link WorkflowStateOptions} is configured to proceed on WaitUntil
110+ * API Failure.
111+ * @param stateOptions the state options to validate.
112+ * @param stateId the unique ID of the state
113+ */
114+ private static void validateWaitUntilApiFailurePolicy (WorkflowStateOptions stateOptions , String stateId ) {
115+ // Validate required fields if Wait Until failure policy is configured to proceed
116+ if (stateOptions .getWaitUntilApiFailurePolicy () == WaitUntilApiFailurePolicy .PROCEED_ON_FAILURE ) {
106117 // retry policy must be set
107- if (stateOptions .getWaitUntilApiRetryPolicy () == null ){
108- throw new WorkflowDefinitionException ("RetryPolicy must be set for the waitUntil " + state . getStateId () );
118+ if (stateOptions .getWaitUntilApiRetryPolicy () == null ) {
119+ throw new WorkflowDefinitionException ("RetryPolicy must be set for the waitUntil " + stateId );
109120 }
110121 final RetryPolicy policy = stateOptions .getWaitUntilApiRetryPolicy ();
111122 // either maximumAttempts or maximumAttemptsDurationSeconds must be set and greater than zero
112- if (policy .getMaximumAttempts () == null && policy .getMaximumAttemptsDurationSeconds () == null ){
113- throw new WorkflowDefinitionException ("Either maximumAttempts or maximumAttemptsDurationSeconds must be set for the waitUntil " +state .getStateId ());
123+ if (policy .getMaximumAttempts () == null && policy .getMaximumAttemptsDurationSeconds () == null ) {
124+ throw new WorkflowDefinitionException (
125+ "Either maximumAttempts or maximumAttemptsDurationSeconds must be set for the waitUntil " + stateId );
114126 }
115127 }
116- return stateOptions ;
128+ }
129+
130+ public static WorkflowStateOptions toIdlWorkflowStateOptionsWithValidation (final StateDef stateDef ) {
131+ final WorkflowState state = stateDef .getWorkflowState ();
132+ if (state .getStateOptions () == null ) {
133+ return null ;
134+ }
135+
136+ return toIdlWorkflowStateOptionsWithValidation (state .getStateOptions (), state .getStateId ());
137+ }
138+
139+ public static WorkflowStateOptions toIdlWorkflowStateOptionsWithValidation (
140+ io .iworkflow .core .WorkflowStateOptions stateOptions ,
141+ String stateId ) {
142+ if (stateOptions == null ) {
143+ return null ;
144+ }
145+
146+ // Guarantee workflow state options copy is not holding references to the original by cloning object
147+ stateOptions = stateOptions .clone ();
148+
149+ final WorkflowStateOptions idlWorkflowStateOptions = new WorkflowStateOptions ();
150+
151+ idlWorkflowStateOptions .setSearchAttributesLoadingPolicy (stateOptions .getSearchAttributesLoadingPolicy ());
152+ idlWorkflowStateOptions .setWaitUntilApiSearchAttributesLoadingPolicy (stateOptions .getWaitUntilApiSearchAttributesLoadingPolicy ());
153+ idlWorkflowStateOptions .setExecuteApiSearchAttributesLoadingPolicy (stateOptions .getExecuteApiSearchAttributesLoadingPolicy ());
154+ idlWorkflowStateOptions .setDataAttributesLoadingPolicy (stateOptions .getDataAttributesLoadingPolicy ());
155+ idlWorkflowStateOptions .setWaitUntilApiDataAttributesLoadingPolicy (stateOptions .getWaitUntilApiDataAttributesLoadingPolicy ());
156+ idlWorkflowStateOptions .setExecuteApiDataAttributesLoadingPolicy (stateOptions .getExecuteApiDataAttributesLoadingPolicy ());
157+ idlWorkflowStateOptions .setWaitUntilApiTimeoutSeconds (stateOptions .getWaitUntilApiTimeoutSeconds ());
158+ idlWorkflowStateOptions .setExecuteApiTimeoutSeconds (stateOptions .getExecuteApiTimeoutSeconds ());
159+ idlWorkflowStateOptions .setWaitUntilApiRetryPolicy (stateOptions .getWaitUntilApiRetryPolicy ());
160+ idlWorkflowStateOptions .setExecuteApiRetryPolicy (stateOptions .getExecuteApiRetryPolicy ());
161+ if (stateOptions .getProceedToExecuteWhenWaitUntilRetryExhausted () != null ) {
162+ idlWorkflowStateOptions .setWaitUntilApiFailurePolicy (Boolean .TRUE .equals (stateOptions .getProceedToExecuteWhenWaitUntilRetryExhausted ())
163+ ? WaitUntilApiFailurePolicy .PROCEED_ON_FAILURE
164+ : WaitUntilApiFailurePolicy .FAIL_WORKFLOW_ON_FAILURE );
165+ }
166+ if (stateOptions .getProceedToStateWhenExecuteRetryExhausted () != null ) {
167+ idlWorkflowStateOptions .setExecuteApiFailurePolicy (ExecuteApiFailurePolicy .PROCEED_TO_CONFIGURED_STATE );
168+ idlWorkflowStateOptions .setExecuteApiFailureProceedStateId (stateOptions .getProceedToStateWhenExecuteRetryExhausted ()
169+ .getSimpleName ());
170+ }
171+ if (stateOptions .getProceedToStateWhenExecuteRetryExhaustedStateOptions () != null ) {
172+ idlWorkflowStateOptions .setExecuteApiFailureProceedStateOptions (toIdlWorkflowStateOptionsWithValidation (
173+ stateOptions .getProceedToStateWhenExecuteRetryExhaustedStateOptions (),
174+ stateId ));
175+ }
176+
177+ validateExecuteApiFailurePolicy (idlWorkflowStateOptions , stateId );
178+ validateWaitUntilApiFailurePolicy (idlWorkflowStateOptions , stateId );
179+
180+ return idlWorkflowStateOptions ;
117181 }
118182}
0 commit comments