1 /* Copyright (c) 2019 AT&T Intellectual Property. #
\r
3 # Licensed under the Apache License, Version 2.0 (the "License"); #
\r
4 # you may not use this file except in compliance with the License. #
\r
5 # You may obtain a copy of the License at #
\r
7 # http://www.apache.org/licenses/LICENSE-2.0 #
\r
9 # Unless required by applicable law or agreed to in writing, software #
\r
10 # distributed under the License is distributed on an "AS IS" BASIS, #
\r
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
\r
12 # See the License for the specific language governing permissions and #
\r
13 # limitations under the License. #
\r
14 ##############################################################################*/
\r
17 package org.oran.otf.camunda.workflow.utility;
\r
19 import static org.camunda.spin.Spin.JSON;
\r
21 import org.oran.otf.camunda.exception.TestExecutionException;
\r
22 import org.oran.otf.camunda.model.ExecutionConstants;
\r
23 import org.oran.otf.camunda.model.ExecutionConstants.ExecutionVariable;
\r
24 import org.oran.otf.common.model.TestExecution;
\r
25 import org.oran.otf.common.model.local.ParallelFlowInput;
\r
26 import org.oran.otf.common.utility.Utility;
\r
27 import java.util.ArrayList;
\r
28 import java.util.HashMap;
\r
29 import java.util.List;
\r
30 import java.util.Map;
\r
31 import org.bson.types.ObjectId;
\r
32 import org.camunda.bpm.engine.delegate.DelegateExecution;
\r
33 import org.camunda.spin.json.SpinJsonNode;
\r
34 import org.slf4j.Logger;
\r
35 import org.slf4j.LoggerFactory;
\r
36 import org.springframework.beans.factory.annotation.Autowired;
\r
37 import org.springframework.stereotype.Service;
\r
40 public class WorkflowUtility {
\r
42 private static Logger logger = LoggerFactory.getLogger(WorkflowUtility.class);
\r
44 private RsaEncryptDecrypt rsaUtility;
\r
46 public boolean verifyTestExecutionChecksum(
\r
47 DelegateExecution execution, TestExecution testExecution) {
\r
49 byte[] enc = (byte[]) execution.getVariable(ExecutionVariable.TEST_EXECUTION);
\r
51 String test = ""; // testExecution.createTestDescription();
\r
52 String dec = new String(rsaUtility.decrypt(enc));
\r
53 if (!dec.equals(test)) {
\r
55 // throw new TestExecutionException("Modification Error: User modified platform data");
\r
57 } catch (Exception e) {
\r
59 execution.getCurrentActivityId()
\r
60 + ": Failed to decrypt test execution. May have been tampered with.\n"
\r
67 public <T> T getExecutionVariable(Map<String, Object> variables, String key, Class<T> type) {
\r
68 Object obj = variables.get(key);
\r
70 logger.error(String.format("Failed to get variable because the key %s does not exist.", key));
\r
72 // return spin json nodes as maps
\r
73 if (obj instanceof SpinJsonNode) {
\r
74 SpinJsonNode node = (SpinJsonNode) obj;
\r
75 if (!node.isObject()) {
\r
76 throw new TestExecutionException(
\r
77 "Unable to retrieve variable as type Map from the execution. Variable was set to SpinJsonNode");
\r
79 Map<String, Object> map = (Map<String, Object>) node.mapTo(HashMap.class);
\r
82 return type.isInstance(obj) ? type.cast(obj) : null;
\r
85 // public boolean hasPermission(User user, TestInstance testInstance) {
\r
86 // // Groups that the user holds a membership in.
\r
87 // List<UserGroup> userGroups = user.getGroups();
\r
88 // // The groupId associated with the test instance.
\r
89 // ObjectId targetGroupId = testInstance.getGroupId();
\r
90 // // Check if any of the groups has access to the test instance.
\r
91 // UserGroup targetGroup =
\r
92 // userGroups.stream()
\r
93 // .filter(userGroup -> userGroup.getGroupId().equals(targetGroupId))
\r
97 // return targetGroup != null;
\r
100 public TestExecution getTestExecution(Map<String, Object> variables, String logPrefix)
\r
101 throws TestExecutionException {
\r
102 // Get the current test execution object.
\r
103 TestExecution testExecution =
\r
104 this.getExecutionVariable(variables, ExecutionVariable.TEST_EXECUTION, TestExecution.class);
\r
105 // Perform a null-check to ensure it is available. It's critical to throw an exception if it
\r
106 // is not available since the object is essential for results.
\r
107 if (testExecution == null) {
\r
108 logger.error(logPrefix + " Test execution is null.");
\r
109 throw new TestExecutionException("The test execution was not found.");
\r
111 return testExecution;
\r
114 public Map<String, Object> getTestData(Map<String, Object> variables, String logPrefix)
\r
115 throws TestExecutionException {
\r
116 // Get vthInput from the Camunda execution variable map.
\r
117 @SuppressWarnings({"unchecked"})
\r
118 Map<String, Object> testData =
\r
119 (Map<String, Object>)
\r
120 this.getExecutionVariable(variables, ExecutionVariable.TEST_DATA, Map.class);
\r
122 if (testData == null) {
\r
123 throw new TestExecutionException(
\r
124 "Unable to retrieve testData as type Map from the execution.");
\r
129 public Object getTestDataByActivity(
\r
130 Map<String, Object> variables, String currentActivityId, String logPrefix)
\r
131 throws TestExecutionException, NullPointerException {
\r
132 // Get vthInput from the Camunda execution variable map.
\r
133 @SuppressWarnings({"unchecked"})
\r
134 Map<String, Object> testData =
\r
135 (Map<String, Object>)
\r
136 this.getExecutionVariable(variables, ExecutionVariable.TEST_DATA, Map.class);
\r
138 if (testData == null) {
\r
139 throw new TestExecutionException(
\r
140 "Unable to retrieve testData as type Map from the execution.");
\r
142 Object activityParameters = testData.get(currentActivityId);
\r
143 if (activityParameters == null) {
\r
144 throw new NullPointerException(
\r
147 "A testData parameter was not found for the activityId, %s.", currentActivityId));
\r
149 return activityParameters;
\r
153 public Map<String, ParallelFlowInput> getPfloInputByActivity(
\r
154 Map<String, Object> variables, String currentActivityId, String logPrefix)
\r
155 throws TestExecutionException, NullPointerException {
\r
156 // Get vthInput from the Camunda execution variable map.
\r
157 @SuppressWarnings({"unchecked"})
\r
158 Map<String, Object> pfloInput =
\r
159 (Map<String, Object>)
\r
160 this.getExecutionVariable(variables, ExecutionVariable.PFLO_INPUT, Map.class);
\r
162 if (pfloInput == null) {
\r
163 throw new TestExecutionException(
\r
164 "Unable to retrieve testData as type Map from the execution.");
\r
166 Map<String, ParallelFlowInput> activityParameters =
\r
167 (Map<String, ParallelFlowInput>) pfloInput.get(currentActivityId);
\r
168 if (activityParameters == null) {
\r
169 throw new NullPointerException(
\r
172 "A plfoInput parameter was not found for the activityId, %s.",
\r
173 currentActivityId));
\r
175 return activityParameters;
\r
178 public List<Map<String, Object>> getVthInput(
\r
179 Map<String, Object> variables, String currentActivityId, String logPrefix)
\r
180 throws TestExecutionException, NullPointerException, IllegalArgumentException {
\r
181 // Get vthInput from the Camunda execution variable map.
\r
182 @SuppressWarnings({"unchecked"})
\r
183 Map<String, Object> vthInput =
\r
184 (Map<String, Object>)
\r
185 this.getExecutionVariable(variables, ExecutionVariable.VTH_INPUT, Map.class);
\r
187 if (vthInput == null) {
\r
188 throw new TestExecutionException(
\r
189 "Unable to retrieve vthInput as type Map from the execution.");
\r
192 // Get the current activityId to use as a key to retrieve the vthInput for this task.
\r
193 // vthInput is expected to be a JSON array of size [1, inf)
\r
194 Object oActivityParameters = vthInput.get(currentActivityId);
\r
195 // Throw an exception if no parameters were found for this activity.
\r
196 if (oActivityParameters == null) {
\r
197 throw new NullPointerException(
\r
200 "A vthInput parameter was not found for the activityId, %s.", currentActivityId));
\r
203 List<Map<String, Object>> lActivityParameters;
\r
206 @SuppressWarnings("unchecked")
\r
207 Map<String, Object> mActivityParameters = new HashMap<>();
\r
208 mActivityParameters.put("method", "post");
\r
209 mActivityParameters.put("payload", Utility.toMap(oActivityParameters));
\r
210 Map<String, Object> headers = new HashMap<>();
\r
211 headers.put("Content-Type", "application/json");
\r
212 mActivityParameters.put("headers", headers);
\r
213 lActivityParameters = new ArrayList();
\r
214 lActivityParameters.add(mActivityParameters);
\r
215 } catch (Exception e) {
\r
217 // Try to convert the parameters to an array of "vthInput(s)"
\r
218 lActivityParameters = (List<Map<String, Object>>) Utility.toList(oActivityParameters);
\r
219 } catch (Exception ee) {
\r
220 throw new IllegalArgumentException(
\r
221 String.format("Unable to parse the value for vthInput[%s].", currentActivityId));
\r
224 return lActivityParameters;
\r
227 public String getTestResult(Map<String, Object> variables, String logPrefix) {
\r
228 String testResult =
\r
229 this.getExecutionVariable(variables, ExecutionVariable.TEST_RESULT, String.class);
\r
230 // Set the test result to UNKNOWN
\r
231 if (testResult == null) {
\r
234 + "Unable to retrieve test result as primitive type String. Setting result to unknown.");
\r
235 testResult = ExecutionConstants.TestResult.UNKNOWN;
\r
240 public String getTestResultMessage(Map<String, Object> variables, String logPrefix) {
\r
241 String testResultMessage =
\r
242 this.getExecutionVariable(variables, ExecutionVariable.TEST_RESULT_MESSAGE, String.class);
\r
243 // Set the test result to UNKNOWN
\r
244 if (testResultMessage == null) {
\r
245 testResultMessage = "";
\r
248 // + "Unable to retrieve test result message as primitive type String. Setting message to empty string.");
\r
249 // testResultMessage = "";
\r
251 return testResultMessage;
\r
254 public Map<String, Object> getTestDetails(Map<String, Object> variables, String logPrefix)
\r
255 throws TestExecutionException {
\r
256 // Get test details as a String because it can be saved as one of many "JSON" types. Then try
\r
257 // to convert it to a generic map.
\r
258 String testDetailsString =
\r
259 this.getExecutionVariable(variables, ExecutionVariable.TEST_DETAILS, String.class);
\r
260 if (testDetailsString != null) {
\r
261 // Use Spin to map the string to a Map.
\r
262 @SuppressWarnings({"unchecked"})
\r
263 Map<String, Object> mTestDetails;
\r
265 mTestDetails = JSON(testDetailsString).mapTo(HashMap.class);
\r
266 } catch (Exception e) {
\r
268 "Unable to convert testDetails to a map.\nError: "
\r
270 + "\ntestDetails: "
\r
271 + testDetailsString);
\r
272 mTestDetails = new HashMap<>();
\r
274 return mTestDetails;
\r
277 // get testDetails as a map.
\r
278 @SuppressWarnings({"unchecked"})
\r
279 Map<String, Object> testDetails =
\r
280 (Map<String, Object>)
\r
281 this.getExecutionVariable(variables, ExecutionVariable.TEST_DETAILS, Map.class);
\r
283 if (testDetails == null) {
\r
286 + "Unable to retrieve test details as primitive type String. Setting to an empty JSON.");
\r
287 testDetails = new HashMap<>();
\r
289 return testDetails;
\r