io.cloudslang.lang.runtime.steps.ExecutableExecutionData.java Source code

Java tutorial

Introduction

Here is the source code for io.cloudslang.lang.runtime.steps.ExecutableExecutionData.java

Source

/*******************************************************************************
 * (c) Copyright 2016 Hewlett-Packard Development Company, L.P.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Apache License v2.0 which accompany this distribution.
 *
 * The Apache License is available at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 *******************************************************************************/
package io.cloudslang.lang.runtime.steps;

import com.hp.oo.sdk.content.annotations.Param;
import io.cloudslang.lang.entities.ExecutableType;
import io.cloudslang.lang.entities.ScoreLangConstants;
import io.cloudslang.lang.entities.bindings.Input;
import io.cloudslang.lang.entities.bindings.Output;
import io.cloudslang.lang.entities.bindings.Result;
import io.cloudslang.lang.entities.bindings.values.Value;
import io.cloudslang.lang.entities.utils.MapUtils;
import io.cloudslang.lang.runtime.bindings.InputsBinding;
import io.cloudslang.lang.runtime.bindings.OutputsBinding;
import io.cloudslang.lang.runtime.bindings.ResultsBinding;
import io.cloudslang.lang.runtime.env.Context;
import io.cloudslang.lang.runtime.env.ParentFlowData;
import io.cloudslang.lang.runtime.env.ReturnValues;
import io.cloudslang.lang.runtime.env.RunEnvironment;
import io.cloudslang.lang.runtime.events.LanguageEventData;
import io.cloudslang.score.api.execution.ExecutionParametersConsts;
import io.cloudslang.score.lang.ExecutionRuntimeServices;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.tuple.Pair;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import static io.cloudslang.score.api.execution.ExecutionParametersConsts.EXECUTION_RUNTIME_SERVICES;

/**
 * User: stoneo
 * Date: 02/11/2014
 * Time: 10:24
 */
@Component
public class ExecutableExecutionData extends AbstractExecutionData {

    public static final String ACTION_RETURN_VALUES_KEY = "actionReturnValues";

    @Autowired
    private ResultsBinding resultsBinding;

    @Autowired
    private InputsBinding inputsBinding;

    @Autowired
    private OutputsBinding outputsBinding;

    private static final Logger logger = Logger.getLogger(ExecutableExecutionData.class);

    public void startExecutable(@Param(ScoreLangConstants.EXECUTABLE_INPUTS_KEY) List<Input> executableInputs,
            @Param(ScoreLangConstants.RUN_ENV) RunEnvironment runEnv,
            @Param(ScoreLangConstants.USER_INPUTS_KEY) Map<String, ? extends Value> userInputs,
            @Param(EXECUTION_RUNTIME_SERVICES) ExecutionRuntimeServices executionRuntimeServices,
            @Param(ScoreLangConstants.NODE_NAME_KEY) String nodeName,
            @Param(ScoreLangConstants.NEXT_STEP_ID_KEY) Long nextStepId,
            @Param(ScoreLangConstants.EXECUTABLE_TYPE) ExecutableType executableType) {
        try {
            Map<String, Value> callArguments = runEnv.removeCallArguments();

            if (userInputs != null) {
                callArguments.putAll(userInputs);
            }
            LanguageEventData.StepType stepType = LanguageEventData.convertExecutableType(executableType);
            sendStartBindingInputsEvent(executableInputs, runEnv, executionRuntimeServices,
                    "Pre Input binding for " + stepType, stepType, nodeName, callArguments);

            Map<String, Value> boundInputValues = inputsBinding.bindInputs(executableInputs, callArguments,
                    runEnv.getSystemProperties());

            Map<String, Value> actionArguments = new HashMap<>();

            actionArguments.putAll(boundInputValues);

            //done with the user inputs, don't want it to be available in next startExecutable steps..
            if (userInputs != null) {
                userInputs.clear();
            }

            updateCallArgumentsAndPushContextToStack(runEnv, new Context(boundInputValues), actionArguments);

            sendEndBindingInputsEvent(executableInputs, boundInputValues, runEnv, executionRuntimeServices,
                    "Post Input binding for " + stepType, stepType, nodeName, callArguments);

            executionRuntimeServices.setShouldCheckGroup();

            // put the next step position for the navigation
            runEnv.putNextStepPosition(nextStepId);
            runEnv.getExecutionPath().down();
        } catch (RuntimeException e) {
            logger.error("There was an error running the start executable execution step of: \'" + nodeName
                    + "\'.\n\tError is: " + e.getMessage());
            throw new RuntimeException("Error running: \'" + nodeName + "\'.\n\t " + e.getMessage(), e);
        }
    }

    /**
     * This method is executed by the finishExecutable execution step of an operation or flow
     *
     * @param runEnv                   the run environment object
     * @param executableOutputs        the operation outputs data
     * @param executableResults        the operation results data
     * @param executionRuntimeServices services supplied by score engine for handling the execution
     */
    public void finishExecutable(@Param(ScoreLangConstants.RUN_ENV) RunEnvironment runEnv,
            @Param(ScoreLangConstants.EXECUTABLE_OUTPUTS_KEY) List<Output> executableOutputs,
            @Param(ScoreLangConstants.EXECUTABLE_RESULTS_KEY) List<Result> executableResults,
            @Param(EXECUTION_RUNTIME_SERVICES) ExecutionRuntimeServices executionRuntimeServices,
            @Param(ScoreLangConstants.NODE_NAME_KEY) String nodeName,
            @Param(ScoreLangConstants.EXECUTABLE_TYPE) ExecutableType executableType) {
        try {
            runEnv.getExecutionPath().up();
            Context operationContext = runEnv.getStack().popContext();
            Map<String, Value> operationVariables = operationContext == null ? null
                    : operationContext.getImmutableViewOfVariables();

            ReturnValues actionReturnValues = buildReturnValues(runEnv, executableType);
            LanguageEventData.StepType stepType = LanguageEventData.convertExecutableType(executableType);
            fireEvent(executionRuntimeServices, runEnv, ScoreLangConstants.EVENT_OUTPUT_START,
                    "Output binding started", stepType, nodeName, operationVariables,
                    Pair.of(ScoreLangConstants.EXECUTABLE_OUTPUTS_KEY, (Serializable) executableOutputs),
                    Pair.of(ScoreLangConstants.EXECUTABLE_RESULTS_KEY, (Serializable) executableResults),
                    Pair.of(ACTION_RETURN_VALUES_KEY,
                            executableType == ExecutableType.OPERATION
                                    ? new ReturnValues(new HashMap<String, Value>(), actionReturnValues.getResult())
                                    : actionReturnValues));

            // Resolving the result of the operation/flow
            String result = resultsBinding.resolveResult(operationVariables, actionReturnValues.getOutputs(),
                    runEnv.getSystemProperties(), executableResults, actionReturnValues.getResult());

            Map<String, Value> outputsBindingContext = MapUtils.mergeMaps(operationVariables,
                    actionReturnValues.getOutputs());
            Map<String, Value> operationReturnOutputs = outputsBinding.bindOutputs(outputsBindingContext,
                    runEnv.getSystemProperties(), executableOutputs);

            ReturnValues returnValues = new ReturnValues(operationReturnOutputs, result);
            runEnv.putReturnValues(returnValues);
            fireEvent(executionRuntimeServices, runEnv, ScoreLangConstants.EVENT_OUTPUT_END,
                    "Output binding finished", stepType, nodeName, operationVariables,
                    Pair.of(LanguageEventData.OUTPUTS, (Serializable) operationReturnOutputs),
                    Pair.of(LanguageEventData.RESULT, returnValues.getResult()));

            // If we have parent flow data on the stack, we pop it and request the score engine to switch
            // to the parent execution plan id once it can, and we set the next position that was stored there
            // for the use of the navigation
            if (!runEnv.getParentFlowStack().isEmpty()) {
                handleNavigationToParent(runEnv, executionRuntimeServices);
            } else {
                fireEvent(executionRuntimeServices, runEnv, ScoreLangConstants.EVENT_EXECUTION_FINISHED,
                        "Execution finished running", stepType, nodeName, operationVariables,
                        Pair.of(LanguageEventData.RESULT, returnValues.getResult()),
                        Pair.of(LanguageEventData.OUTPUTS, (Serializable) operationReturnOutputs));
            }
        } catch (RuntimeException e) {
            logger.error("There was an error running the finish executable execution step of: \'" + nodeName
                    + "\'.\n\tError is: " + e.getMessage());
            throw new RuntimeException("Error running: \'" + nodeName + "\'.\n\t" + e.getMessage(), e);
        }
    }

    private void handleNavigationToParent(RunEnvironment runEnv,
            ExecutionRuntimeServices executionRuntimeServices) {
        ParentFlowData parentFlowData = runEnv.getParentFlowStack().popParentFlowData();
        executionRuntimeServices.requestToChangeExecutionPlan(parentFlowData.getRunningExecutionPlanId());
        runEnv.putNextStepPosition(parentFlowData.getPosition());
    }

    private ReturnValues buildReturnValues(RunEnvironment runEnvironment, ExecutableType executableType) {
        ReturnValues returnValues = runEnvironment.removeReturnValues();
        switch (executableType) {
        case DECISION:
            returnValues = new ReturnValues(Collections.<String, Value>emptyMap(), null);
            break;
        case FLOW:
            break;
        case OPERATION:
            break;
        default:
            throw new RuntimeException("Unrecognized type: " + executableType);
        }
        return returnValues;
    }

}