X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=it%2Fotf.git;a=blobdiff_plain;f=otf-camunda%2Fsrc%2Fmain%2Fjava%2Forg%2Foran%2Fotf%2Fcamunda%2Fworkflow%2Futility%2FWorkflowUtility.java;fp=otf-camunda%2Fsrc%2Fmain%2Fjava%2Forg%2Foran%2Fotf%2Fcamunda%2Fworkflow%2Futility%2FWorkflowUtility.java;h=608470e737deb1939e5d71fcbdd8fe192a20cfa8;hp=0000000000000000000000000000000000000000;hb=14f6f95c84a4a1fa8774190db4a03fd0214ec55f;hpb=f49bd1efeaaddd4891c1f329b18d8cfb28b3e75b diff --git a/otf-camunda/src/main/java/org/oran/otf/camunda/workflow/utility/WorkflowUtility.java b/otf-camunda/src/main/java/org/oran/otf/camunda/workflow/utility/WorkflowUtility.java new file mode 100644 index 0000000..608470e --- /dev/null +++ b/otf-camunda/src/main/java/org/oran/otf/camunda/workflow/utility/WorkflowUtility.java @@ -0,0 +1,291 @@ +/* Copyright (c) 2019 AT&T Intellectual Property. # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +##############################################################################*/ + + +package org.oran.otf.camunda.workflow.utility; + +import static org.camunda.spin.Spin.JSON; + +import org.oran.otf.camunda.exception.TestExecutionException; +import org.oran.otf.camunda.model.ExecutionConstants; +import org.oran.otf.camunda.model.ExecutionConstants.ExecutionVariable; +import org.oran.otf.common.model.TestExecution; +import org.oran.otf.common.model.local.ParallelFlowInput; +import org.oran.otf.common.utility.Utility; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.bson.types.ObjectId; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.camunda.spin.json.SpinJsonNode; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class WorkflowUtility { + + private static Logger logger = LoggerFactory.getLogger(WorkflowUtility.class); + @Autowired + private RsaEncryptDecrypt rsaUtility; + + public boolean verifyTestExecutionChecksum( + DelegateExecution execution, TestExecution testExecution) { + try { + byte[] enc = (byte[]) execution.getVariable(ExecutionVariable.TEST_EXECUTION); + + String test = ""; // testExecution.createTestDescription(); + String dec = new String(rsaUtility.decrypt(enc)); + if (!dec.equals(test)) { + return false; + // throw new TestExecutionException("Modification Error: User modified platform data"); + } + } catch (Exception e) { + logger.error( + execution.getCurrentActivityId() + + ": Failed to decrypt test execution. May have been tampered with.\n" + + e.getMessage()); + return false; + } + return true; + } + + public T getExecutionVariable(Map variables, String key, Class type) { + Object obj = variables.get(key); + if (obj == null) { + logger.error(String.format("Failed to get variable because the key %s does not exist.", key)); + } + // return spin json nodes as maps + if (obj instanceof SpinJsonNode) { + SpinJsonNode node = (SpinJsonNode) obj; + if (!node.isObject()) { + throw new TestExecutionException( + "Unable to retrieve variable as type Map from the execution. Variable was set to SpinJsonNode"); + } + Map map = (Map) node.mapTo(HashMap.class); + } + + return type.isInstance(obj) ? type.cast(obj) : null; + } + +// public boolean hasPermission(User user, TestInstance testInstance) { +// // Groups that the user holds a membership in. +// List userGroups = user.getGroups(); +// // The groupId associated with the test instance. +// ObjectId targetGroupId = testInstance.getGroupId(); +// // Check if any of the groups has access to the test instance. +// UserGroup targetGroup = +// userGroups.stream() +// .filter(userGroup -> userGroup.getGroupId().equals(targetGroupId)) +// .findAny() +// .orElse(null); +// +// return targetGroup != null; +// } + + public TestExecution getTestExecution(Map variables, String logPrefix) + throws TestExecutionException { + // Get the current test execution object. + TestExecution testExecution = + this.getExecutionVariable(variables, ExecutionVariable.TEST_EXECUTION, TestExecution.class); + // Perform a null-check to ensure it is available. It's critical to throw an exception if it + // is not available since the object is essential for results. + if (testExecution == null) { + logger.error(logPrefix + " Test execution is null."); + throw new TestExecutionException("The test execution was not found."); + } + return testExecution; + } + + public Map getTestData(Map variables, String logPrefix) + throws TestExecutionException { + // Get vthInput from the Camunda execution variable map. + @SuppressWarnings({"unchecked"}) + Map testData = + (Map) + this.getExecutionVariable(variables, ExecutionVariable.TEST_DATA, Map.class); + + if (testData == null) { + throw new TestExecutionException( + "Unable to retrieve testData as type Map from the execution."); + } + return testData; + } + + public Object getTestDataByActivity( + Map variables, String currentActivityId, String logPrefix) + throws TestExecutionException, NullPointerException { + // Get vthInput from the Camunda execution variable map. + @SuppressWarnings({"unchecked"}) + Map testData = + (Map) + this.getExecutionVariable(variables, ExecutionVariable.TEST_DATA, Map.class); + + if (testData == null) { + throw new TestExecutionException( + "Unable to retrieve testData as type Map from the execution."); + } + Object activityParameters = testData.get(currentActivityId); + if (activityParameters == null) { + throw new NullPointerException( + logPrefix + + String.format( + "A testData parameter was not found for the activityId, %s.", currentActivityId)); + } + return activityParameters; + } + + + public Map getPfloInputByActivity( + Map variables, String currentActivityId, String logPrefix) + throws TestExecutionException, NullPointerException { + // Get vthInput from the Camunda execution variable map. + @SuppressWarnings({"unchecked"}) + Map pfloInput = + (Map) + this.getExecutionVariable(variables, ExecutionVariable.PFLO_INPUT, Map.class); + + if (pfloInput == null) { + throw new TestExecutionException( + "Unable to retrieve testData as type Map from the execution."); + } + Map activityParameters = + (Map) pfloInput.get(currentActivityId); + if (activityParameters == null) { + throw new NullPointerException( + logPrefix + + String.format( + "A plfoInput parameter was not found for the activityId, %s.", + currentActivityId)); + } + return activityParameters; + } + + public List> getVthInput( + Map variables, String currentActivityId, String logPrefix) + throws TestExecutionException, NullPointerException, IllegalArgumentException { + // Get vthInput from the Camunda execution variable map. + @SuppressWarnings({"unchecked"}) + Map vthInput = + (Map) + this.getExecutionVariable(variables, ExecutionVariable.VTH_INPUT, Map.class); + + if (vthInput == null) { + throw new TestExecutionException( + "Unable to retrieve vthInput as type Map from the execution."); + } + + // Get the current activityId to use as a key to retrieve the vthInput for this task. + // vthInput is expected to be a JSON array of size [1, inf) + Object oActivityParameters = vthInput.get(currentActivityId); + // Throw an exception if no parameters were found for this activity. + if (oActivityParameters == null) { + throw new NullPointerException( + logPrefix + + String.format( + "A vthInput parameter was not found for the activityId, %s.", currentActivityId)); + } + + List> lActivityParameters; + // Legacy hack + try { + @SuppressWarnings("unchecked") + Map mActivityParameters = new HashMap<>(); + mActivityParameters.put("method", "post"); + mActivityParameters.put("payload", Utility.toMap(oActivityParameters)); + Map headers = new HashMap<>(); + headers.put("Content-Type", "application/json"); + mActivityParameters.put("headers", headers); + lActivityParameters = new ArrayList(); + lActivityParameters.add(mActivityParameters); + } catch (Exception e) { + try { + // Try to convert the parameters to an array of "vthInput(s)" + lActivityParameters = (List>) Utility.toList(oActivityParameters); + } catch (Exception ee) { + throw new IllegalArgumentException( + String.format("Unable to parse the value for vthInput[%s].", currentActivityId)); + } + } + return lActivityParameters; + } + + public String getTestResult(Map variables, String logPrefix) { + String testResult = + this.getExecutionVariable(variables, ExecutionVariable.TEST_RESULT, String.class); + // Set the test result to UNKNOWN + if (testResult == null) { + logger.debug( + logPrefix + + "Unable to retrieve test result as primitive type String. Setting result to unknown."); + testResult = ExecutionConstants.TestResult.UNKNOWN; + } + return testResult; + } + + public String getTestResultMessage(Map variables, String logPrefix) { + String testResultMessage = + this.getExecutionVariable(variables, ExecutionVariable.TEST_RESULT_MESSAGE, String.class); + // Set the test result to UNKNOWN + if (testResultMessage == null) { + testResultMessage = ""; +// logger.debug( +// logPrefix +// + "Unable to retrieve test result message as primitive type String. Setting message to empty string."); +// testResultMessage = ""; + } + return testResultMessage; + } + + public Map getTestDetails(Map variables, String logPrefix) + throws TestExecutionException { + // Get test details as a String because it can be saved as one of many "JSON" types. Then try + // to convert it to a generic map. + String testDetailsString = + this.getExecutionVariable(variables, ExecutionVariable.TEST_DETAILS, String.class); + if (testDetailsString != null) { + // Use Spin to map the string to a Map. + @SuppressWarnings({"unchecked"}) + Map mTestDetails; + try { + mTestDetails = JSON(testDetailsString).mapTo(HashMap.class); + } catch (Exception e) { + logger.error( + "Unable to convert testDetails to a map.\nError: " + + e.getMessage() + + "\ntestDetails: " + + testDetailsString); + mTestDetails = new HashMap<>(); + } + return mTestDetails; + } + + // get testDetails as a map. + @SuppressWarnings({"unchecked"}) + Map testDetails = + (Map) + this.getExecutionVariable(variables, ExecutionVariable.TEST_DETAILS, Map.class); + + if (testDetails == null) { + logger.debug( + logPrefix + + "Unable to retrieve test details as primitive type String. Setting to an empty JSON."); + testDetails = new HashMap<>(); + } + return testDetails; + } +}