/******************************************************************************* * (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.env; import com.google.common.base.Function; import com.google.common.collect.Collections2; import com.hp.oo.sdk.content.plugin.SerializableSessionObject; import io.cloudslang.lang.entities.SystemProperty; import io.cloudslang.lang.entities.bindings.values.SensitiveValue; import io.cloudslang.lang.entities.bindings.values.Value; import java.io.Serializable; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang3.Validate; /** * User: stoneo * Date: 20/10/2014 * Time: 10:28 */ public class RunEnvironment implements Serializable { // Call arguments for the current step private Map<String, Value> callArguments; // Return values from the current step private ReturnValues returnValues; // The position of the next step private Long nextStepPosition; // Stack holding the contexts of the parent scopes private ContextStack contextStack; // Stack of the parent flow's data (for the sub-flow use-case) private ParentFlowStack parentFlowStack; private ExecutionPath executionPath; private final Set<SystemProperty> systemProperties; // Map holding serializable data that is common for the entire run // This is data that should be shared between different actions with the ability to change the data private Map<String, SerializableSessionObject> serializableDataMap; public RunEnvironment(Set<SystemProperty> systemProperties) { Validate.notNull(systemProperties, "system properties cannot be null"); contextStack = new ContextStack(); parentFlowStack = new ParentFlowStack(); callArguments = new HashMap<>(); executionPath = new ExecutionPath(); serializableDataMap = new HashMap<>(); this.systemProperties = systemProperties; } public RunEnvironment() { this(new HashSet<SystemProperty>()); } public ContextStack getStack() { return contextStack; } public ParentFlowStack getParentFlowStack() { return parentFlowStack; } public Map<String, Value> removeCallArguments() { Map<String, Value> callArgumentsValues = callArguments; callArguments = new HashMap<>(); return callArgumentsValues; } public void putCallArguments(Map<String, Value> callArguments) { this.callArguments.putAll(callArguments); } public ReturnValues removeReturnValues() { ReturnValues values = returnValues; returnValues = null; return values; } public void putReturnValues(ReturnValues returnValues) { this.returnValues = returnValues; } public Long removeNextStepPosition() { Long nextStep = nextStepPosition; nextStepPosition = null; return nextStep; } public void putNextStepPosition(Long nextStepPosition) { this.nextStepPosition = nextStepPosition; } public ExecutionPath getExecutionPath() { return this.executionPath; } public Set<SystemProperty> getSystemProperties() { return systemProperties; } public Map<String, SerializableSessionObject> getSerializableDataMap() { return serializableDataMap; } public void resetStacks() { contextStack = new ContextStack(); parentFlowStack = new ParentFlowStack(); } public boolean containsSensitiveData() { return containsSensitiveCallArgument() || containsSensitiveReturnValues() || containsSensitiveSystemProperties() || containsSensitiveContexts(); } private boolean containsSensitiveData(Collection<Value> data) { if (data != null) { for (Value value : data) { if (value.isSensitive()) { return true; } } } return false; } public void decryptSensitiveData() { for (Value value : prepareValuesForEncryptDecrypt()) { if (value.isSensitive()) { ((SensitiveValue) value).decrypt(); } } } public void encryptSensitiveData() { for (Value value : prepareValuesForEncryptDecrypt()) { if (value.isSensitive()) { ((SensitiveValue) value).encrypt(); } } } private boolean containsSensitiveCallArgument() { return callArguments != null && containsSensitiveData(callArguments.values()); } private boolean containsSensitiveReturnValues() { return (returnValues != null) && (returnValues.getOutputs() != null) && containsSensitiveData(returnValues.getOutputs().values()); } private boolean containsSensitiveSystemProperties() { return (systemProperties != null) && containsSensitiveData(Collections2.transform(systemProperties, new Function<SystemProperty, Value>() { @Override public Value apply(SystemProperty systemProperty) { return systemProperty.getValue(); } })); } private boolean containsSensitiveContexts() { boolean hasSensitive = false; ContextStack tempStack = new ContextStack(); Context context; while (!hasSensitive && (context = contextStack.popContext()) != null) { hasSensitive = containsSensitiveData(context.getImmutableViewOfLanguageVariables().values()); hasSensitive = hasSensitive || containsSensitiveData(context.getImmutableViewOfVariables().values()); tempStack.pushContext(context); } while ((context = tempStack.popContext()) != null) { contextStack.pushContext(context); } return hasSensitive; } private List<Value> prepareValuesForEncryptDecrypt() { List<Value> valuesToCheck = new LinkedList<>(); if (callArguments != null) { valuesToCheck.addAll(callArguments.values()); } if ((returnValues != null) && (returnValues.getOutputs() != null)) { valuesToCheck.addAll(returnValues.getOutputs().values()); } if (systemProperties != null) { valuesToCheck.addAll(Collections2.transform(systemProperties, new Function<SystemProperty, Value>() { @Override public Value apply(SystemProperty systemProperty) { return systemProperty.getValue(); } })); } ContextStack tempStack = new ContextStack(); Context context; while ((context = contextStack.popContext()) != null) { valuesToCheck.addAll(context.getImmutableViewOfLanguageVariables().values()); valuesToCheck.addAll(context.getImmutableViewOfVariables().values()); tempStack.pushContext(context); } while ((context = tempStack.popContext()) != null) { contextStack.pushContext(context); } return valuesToCheck; } }