diff --git a/maestro-engine/src/main/java/com/netflix/maestro/engine/eval/MaestroParamExtension.java b/maestro-engine/src/main/java/com/netflix/maestro/engine/eval/MaestroParamExtension.java index 723dc0a3..af2f3bda 100644 --- a/maestro-engine/src/main/java/com/netflix/maestro/engine/eval/MaestroParamExtension.java +++ b/maestro-engine/src/main/java/com/netflix/maestro/engine/eval/MaestroParamExtension.java @@ -535,6 +535,8 @@ private Object fromStep(String fieldName) { stepInstanceAttributes.getType(), stepInstanceAttributes.getSubType()); case Constants.STEP_ERROR_RETRIES_PARAM: return stepInstanceAttributes.getStepRetry().getErrorRetries(); + case Constants.STEP_STATUS_PARAM: + return stepInstanceAttributes.getStatus().name(); default: throw new MaestroValidationException( "Invalid field name [%s] for getFromStep call", fieldName); diff --git a/maestro-engine/src/main/java/com/netflix/maestro/engine/eval/StepInstanceAttributes.java b/maestro-engine/src/main/java/com/netflix/maestro/engine/eval/StepInstanceAttributes.java index 6aaab3b2..9b7e0282 100644 --- a/maestro-engine/src/main/java/com/netflix/maestro/engine/eval/StepInstanceAttributes.java +++ b/maestro-engine/src/main/java/com/netflix/maestro/engine/eval/StepInstanceAttributes.java @@ -35,6 +35,7 @@ class StepInstanceAttributes { private final String stepInstanceUuid; private final StepInstance.StepRetry stepRetry; private final SignalDependencies signalDependencies; + private final StepInstance.Status status; static StepInstanceAttributes from(StepRuntimeSummary summary) { return StepInstanceAttributes.builder() @@ -46,6 +47,7 @@ static StepInstanceAttributes from(StepRuntimeSummary summary) { .stepInstanceUuid(summary.getStepInstanceUuid()) .stepRetry(summary.getStepRetry()) .signalDependencies(summary.getSignalDependencies()) + .status(summary.getRuntimeState().getStatus()) .build(); } } diff --git a/maestro-engine/src/test/java/com/netflix/maestro/engine/eval/MaestroParamExtensionTest.java b/maestro-engine/src/test/java/com/netflix/maestro/engine/eval/MaestroParamExtensionTest.java index 9f993a14..4164e134 100644 --- a/maestro-engine/src/test/java/com/netflix/maestro/engine/eval/MaestroParamExtensionTest.java +++ b/maestro-engine/src/test/java/com/netflix/maestro/engine/eval/MaestroParamExtensionTest.java @@ -35,6 +35,7 @@ import com.netflix.maestro.models.initiator.SignalInitiator; import com.netflix.maestro.models.initiator.SubworkflowInitiator; import com.netflix.maestro.models.instance.StepInstance; +import com.netflix.maestro.models.instance.StepRuntimeState; import com.netflix.maestro.models.parameter.LongParameter; import com.netflix.maestro.models.parameter.MapParameter; import com.netflix.maestro.models.parameter.ParamType; @@ -397,6 +398,29 @@ public void testGetFromCurrentStep() { assertEquals( StepType.NOTEBOOK.toString(), paramExtension.getFromStep(Constants.STEP_TYPE_INFO_PARAM)); assertEquals(0L, paramExtension.getFromStep(Constants.STEP_ERROR_RETRIES_PARAM)); + assertEquals( + StepInstance.Status.NOT_CREATED.name(), + paramExtension.getFromStep(Constants.STEP_STATUS_PARAM)); + } + + @Test + public void testGetStatusFromCurrentStep() { + StepRuntimeState runtimeState = new StepRuntimeState(); + runtimeState.setStatus(StepInstance.Status.COMPLETED_WITH_ERROR); + StepRuntimeSummary summary = + StepRuntimeSummary.builder() + .stepId("step-123") + .type(StepType.NOTEBOOK) + .stepRetry(StepInstance.StepRetry.from(null)) + .runtimeState(runtimeState) + .build(); + when(instanceWrapper.isWorkflowParam()).thenReturn(false); + when(instanceWrapper.getStepInstanceAttributes()) + .thenReturn(StepInstanceAttributes.from(summary)); + + assertEquals( + StepInstance.Status.COMPLETED_WITH_ERROR.name(), + paramExtension.getFromStep(Constants.STEP_STATUS_PARAM)); } @Test diff --git a/netflix-sel/docs/lang-guide/class-function.md b/netflix-sel/docs/lang-guide/class-function.md index 3ce7cc87..a1b4ca30 100644 --- a/netflix-sel/docs/lang-guide/class-function.md +++ b/netflix-sel/docs/lang-guide/class-function.md @@ -185,6 +185,18 @@ return params.getFromStep('step1', 'MAESTRO_STEP_STATUS'); // returns the sta return params.getFromStep('step1', 'MAESTRO_STEP_END_TIME'); // returns the end time of upstream step1. ``` +* `Object getFromStep(String)` + +Returns a field of the current step instead of an upstream one. Useful in a step transition condition, +which is evaluated in the context of the step it is attached to, to branch on how that step ended. +```sel +return params.getFromStep('MAESTRO_STEP_STATUS'); // returns the status of the current step. + +return params.getFromStep('MAESTRO_STEP_STATUS') == 'COMPLETED_WITH_ERROR'; // branch taken only when the current step failed. + +return params.getFromStep('step_id'); // also supports step_id, step_instance_id, step_instance_uuid, step_attempt_id, step_type_info and MAESTRO_STEP_ERROR_RETRIES. +``` + * `Object getFromSignal(String, String)` ```sel return params.getFromSignal('signal1', 'param1'); // returns parameter param1's value from signal1. Use it to get param from the signal triggers.