private void throwEventOutputEnd( RunEnvironment runEnv, ExecutionRuntimeServices executionRuntimeServices, String nodeName, Serializable publishValues, Long nextPosition, ReturnValues returnValues) { fireEvent( executionRuntimeServices, runEnv, ScoreLangConstants.EVENT_OUTPUT_END, "Output binding finished", LanguageEventData.StepType.TASK, nodeName, Pair.of(LanguageEventData.OUTPUTS, publishValues), Pair.of(LanguageEventData.RESULT, returnValues.getResult()), Pair.of(LanguageEventData.NEXT_STEP_POSITION, nextPosition)); }
private boolean shouldBreakLoop(List<String> breakOn, ReturnValues executableReturnValues) { return breakOn.contains(executableReturnValues.getResult()); }
public void endTask( @Param(ScoreLangConstants.RUN_ENV) RunEnvironment runEnv, @Param(ScoreLangConstants.TASK_PUBLISH_KEY) List<Output> taskPublishValues, @Param(ScoreLangConstants.TASK_NAVIGATION_KEY) Map<String, ResultNavigation> taskNavigationValues, @Param(EXECUTION_RUNTIME_SERVICES) ExecutionRuntimeServices executionRuntimeServices, @Param(ScoreLangConstants.PREVIOUS_STEP_ID_KEY) Long previousStepId, @Param(ScoreLangConstants.BREAK_LOOP_KEY) List<String> breakOn, @Param(ScoreLangConstants.NODE_NAME_KEY) String nodeName, @Param(ScoreLangConstants.ASYNC_LOOP_KEY) boolean async_loop) { try { Context flowContext = runEnv.getStack().popContext(); Map<String, Serializable> flowVariables = flowContext.getImmutableViewOfVariables(); ReturnValues executableReturnValues = runEnv.removeReturnValues(); fireEvent( executionRuntimeServices, runEnv, ScoreLangConstants.EVENT_OUTPUT_START, "Output binding started", LanguageEventData.StepType.TASK, nodeName, Pair.of(ScoreLangConstants.TASK_PUBLISH_KEY, (Serializable) taskPublishValues), Pair.of(ScoreLangConstants.TASK_NAVIGATION_KEY, (Serializable) taskNavigationValues), Pair.of("operationReturnValues", executableReturnValues)); Map<String, Serializable> publishValues = outputsBinding.bindOutputs( flowVariables, executableReturnValues.getOutputs(), taskPublishValues); flowContext.putVariables(publishValues); // loops Map<String, Serializable> langVariables = flowContext.getLangVariables(); if (langVariables.containsKey(LoopCondition.LOOP_CONDITION_KEY)) { LoopCondition loopCondition = (LoopCondition) langVariables.get(LoopCondition.LOOP_CONDITION_KEY); if (!shouldBreakLoop(breakOn, executableReturnValues) && loopCondition.hasMore()) { runEnv.putNextStepPosition(previousStepId); runEnv.getStack().pushContext(flowContext); throwEventOutputEnd( runEnv, executionRuntimeServices, nodeName, (Serializable) publishValues, previousStepId, new ReturnValues(publishValues, executableReturnValues.getResult())); runEnv.getExecutionPath().forward(); return; } else { flowContext.getLangVariables().remove(LoopCondition.LOOP_CONDITION_KEY); } } // todo: hook // if this is an end task method from a branch then next step position should ne null (end the // flow) // and result should be the one from the executable (navigation is handled in join branches // step) Long nextPosition = null; String executableResult = executableReturnValues.getResult(); String presetResult = executableResult; if (!async_loop) { // set the position of the next step - for the use of the navigation // find in the navigation values the correct next step position, according to the operation // result, and set it ResultNavigation navigation = taskNavigationValues.get(executableResult); if (navigation == null) { // should always have the executable response mapped to a navigation by the task, if not, // it is an error throw new RuntimeException( "Task: " + nodeName + " has no matching navigation for the executable result: " + executableReturnValues.getResult()); } nextPosition = navigation.getNextStepId(); presetResult = navigation.getPresetResult(); } runEnv.putNextStepPosition(nextPosition); HashMap<String, Serializable> outputs = new HashMap<>(flowVariables); ReturnValues returnValues = new ReturnValues(outputs, presetResult != null ? presetResult : executableResult); runEnv.putReturnValues(returnValues); throwEventOutputEnd( runEnv, executionRuntimeServices, nodeName, (Serializable) publishValues, nextPosition, returnValues); runEnv.getStack().pushContext(flowContext); runEnv.getExecutionPath().forward(); } catch (RuntimeException e) { logger.error( "There was an error running the end task execution step of: \'" + nodeName + "\'. Error is: " + e.getMessage()); throw new RuntimeException("Error running: \'" + nodeName + "\': " + e.getMessage(), e); } }