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