예제 #1
0
 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));
 }
예제 #2
0
 private boolean shouldBreakLoop(List<String> breakOn, ReturnValues executableReturnValues) {
   return breakOn.contains(executableReturnValues.getResult());
 }
예제 #3
0
  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);
    }
  }