added svcapi ui and camunda code
[it/otf.git] / otf-camunda / src / main / java / org / oran / otf / camunda / workflow / WorkflowProcessor.java
1 /*-\r
2  * ============LICENSE_START=======================================================\r
3  * ONAP - SO\r
4  * ================================================================================\r
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.\r
6  * ================================================================================\r
7  * Modifications Copyright (c) 2019 Samsung\r
8  * ================================================================================\r
9  * Licensed under the Apache License, Version 2.0 (the "License");\r
10  * you may not use this file except in compliance with the License.\r
11  * You may obtain a copy of the License at\r
12  *\r
13  *      http://www.apache.org/licenses/LICENSE-2.0\r
14  *\r
15  * Unless required by applicable law or agreed to in writing, software\r
16  * distributed under the License is distributed on an "AS IS" BASIS,\r
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
18  * See the License for the specific language governing permissions and\r
19  * limitations under the License.\r
20  * ============LICENSE_END=========================================================\r
21  */\r
22 \r
23 package org.oran.otf.camunda.workflow;\r
24 \r
25 import org.oran.otf.camunda.configuration.OtfCamundaConfiguration;\r
26 import org.oran.otf.camunda.exception.TestExecutionException;\r
27 import org.oran.otf.camunda.exception.WorkflowProcessorException;\r
28 import org.oran.otf.camunda.model.ExecutionConstants.ExecutionVariable;\r
29 import org.oran.otf.camunda.model.ExecutionConstants.TestResult;\r
30 import org.oran.otf.camunda.model.WorkflowResponse;\r
31 import org.oran.otf.camunda.service.ProcessEngineAwareService;\r
32 import org.oran.otf.camunda.workflow.utility.WorkflowUtility;\r
33 import org.oran.otf.common.model.*;\r
34 import org.oran.otf.common.model.historic.TestDefinitionHistoric;\r
35 import org.oran.otf.common.model.historic.TestInstanceHistoric;\r
36 import org.oran.otf.common.model.local.BpmnInstance;\r
37 import org.oran.otf.common.model.local.ParallelFlowInput;\r
38 import org.oran.otf.common.repository.*;\r
39 import org.oran.otf.common.utility.Utility;\r
40 import org.oran.otf.common.utility.database.Generic;\r
41 import org.oran.otf.common.utility.permissions.PermissionChecker;\r
42 import org.oran.otf.common.utility.permissions.UserPermission;\r
43 import com.mongodb.client.result.UpdateResult;\r
44 import java.util.ArrayList;\r
45 import java.util.Date;\r
46 import java.util.HashMap;\r
47 import java.util.List;\r
48 import java.util.Map;\r
49 import java.util.Objects;\r
50 import java.util.UUID;\r
51 import org.bson.types.ObjectId;\r
52 import org.camunda.bpm.BpmPlatform;\r
53 import org.camunda.bpm.engine.RepositoryService;\r
54 import org.camunda.bpm.engine.RuntimeService;\r
55 import org.camunda.bpm.engine.repository.ProcessDefinition;\r
56 import org.camunda.bpm.engine.runtime.ProcessInstance;\r
57 import org.camunda.bpm.engine.variable.VariableMap;\r
58 import org.camunda.bpm.engine.variable.Variables;\r
59 import org.camunda.bpm.engine.variable.impl.VariableMapImpl;\r
60 import org.oran.otf.common.model.*;\r
61 import org.oran.otf.common.repository.*;\r
62 import org.slf4j.Logger;\r
63 import org.slf4j.LoggerFactory;\r
64 import org.springframework.beans.factory.annotation.Autowired;\r
65 import org.springframework.boot.context.event.ApplicationReadyEvent;\r
66 import org.springframework.context.event.EventListener;\r
67 import org.springframework.data.mongodb.core.MongoTemplate;\r
68 import org.springframework.data.mongodb.core.query.Criteria;\r
69 import org.springframework.data.mongodb.core.query.Query;\r
70 import org.springframework.data.mongodb.core.query.Update;\r
71 import org.springframework.stereotype.Component;\r
72 \r
73 @Component\r
74 public class WorkflowProcessor extends ProcessEngineAwareService {\r
75 \r
76     private static final String logPrefix = Utility.getLoggerPrefix();\r
77     private static final Logger logger = LoggerFactory.getLogger(WorkflowProcessor.class);\r
78 \r
79     @Autowired\r
80     GroupRepository groupRepository;\r
81     @Autowired\r
82     TestDefinitionRepository testDefinitionRepository;\r
83     @Autowired\r
84     TestInstanceRepository testInstanceRepository;\r
85     @Autowired\r
86     UserRepository userRepository;\r
87     @Autowired\r
88     TestExecutionRepository testExecutionRepository;\r
89     @Autowired\r
90     MongoTemplate mongoOperation;\r
91     @Autowired\r
92     WorkflowUtility workflowUtility;\r
93 \r
94     private RuntimeService runtimeService;\r
95     private RepositoryService repositoryService;\r
96 \r
97     // Note: the business key is used to identify the process in unit tests\r
98     protected static String getBusinessKey(Map<String, Object> inputVariables) {\r
99         return getOrCreate(inputVariables, "otf-business-key");\r
100     }\r
101 \r
102     protected static Map<String, Object> getInputVariables(VariableMapImpl variableMap) {\r
103         Map<String, Object> inputVariables = new HashMap<>();\r
104         @SuppressWarnings("unchecked")\r
105         Map<String, Object> vMap = (Map<String, Object>) variableMap.get("variables");\r
106         for (Map.Entry<String, Object> entry : vMap.entrySet()) {\r
107             String vName = entry.getKey();\r
108             Object value = entry.getValue();\r
109             @SuppressWarnings("unchecked")\r
110             Map<String, Object> valueMap = (Map<String, Object>) value; // value, type\r
111             inputVariables.put(vName, valueMap.get("value"));\r
112         }\r
113         return inputVariables;\r
114     }\r
115 \r
116     protected static String getOrCreate(Map<String, Object> inputVariables, String key) {\r
117         String value = Objects.toString(inputVariables.get(key), null);\r
118         if (value == null) {\r
119             value = UUID.randomUUID().toString();\r
120             inputVariables.put(key, value);\r
121         }\r
122         return value;\r
123     }\r
124 \r
125     private static void buildVariable(\r
126         String key, String value, Map<String, Object> variableValueType) {\r
127         Map<String, Object> host = new HashMap<>();\r
128         host.put("value", value);\r
129         host.put("type", "String");\r
130         variableValueType.put(key, host);\r
131     }\r
132 \r
133     @EventListener(ApplicationReadyEvent.class)\r
134     private void initialize() {\r
135         if (this.runtimeService == null) {\r
136             this.runtimeService =\r
137                 BpmPlatform.getProcessEngineService()\r
138                     .getProcessEngine(OtfCamundaConfiguration.processEngineName)\r
139                     .getRuntimeService();\r
140         }\r
141         if (this.repositoryService == null) {\r
142             this.repositoryService =\r
143                 BpmPlatform.getProcessEngineService()\r
144                     .getProcessEngine(OtfCamundaConfiguration.processEngineName)\r
145                     .getRepositoryService();\r
146         }\r
147     }\r
148 \r
149     public TestExecution processWorkflowRequest(WorkflowRequest request)\r
150         throws WorkflowProcessorException {\r
151 \r
152         // Check if the test instance exists.\r
153         TestInstance testInstance =\r
154             Generic.findByIdGeneric(testInstanceRepository, request.getTestInstanceId());\r
155         if (testInstance == null) {\r
156             WorkflowResponse response = new WorkflowResponse();\r
157             response.setMessage(\r
158                 String.format(\r
159                     "Test instance with identifier %s was not found.",\r
160                     request.getTestInstanceId().toString()));\r
161             response.setMessageCode(404);\r
162             response.setResponse("Unable to start the test instance.");\r
163             TestExecution testExecution = generateTestExecution(request, null, null, null);\r
164             testExecution.setTestResult(TestResult.DOES_NOT_EXIST);\r
165             testExecution.setTestDetails(generateTestDetailsWithMessage(response.getMessage()));\r
166             response.setTestExecution(testExecution);\r
167             throw new WorkflowProcessorException(response);\r
168         }\r
169 \r
170         // Override the test data and vth input of the instance if the request contains the data.\r
171         Map<String, Object> vthInput =\r
172                 request.getVthInput() == null ? testInstance.getVthInput() : request.getVthInput();\r
173         Map<String, Object> testData =\r
174                 request.getTestData() == null ? testInstance.getTestData() : request.getTestData();\r
175         Map<String, ParallelFlowInput> plfoInput =\r
176                 request.getPfloInput() == null ? testInstance.getPfloInput() : request.getPfloInput();\r
177 \r
178         testInstance.setVthInput((HashMap<String, Object>) vthInput);\r
179         testInstance.setTestData((HashMap<String, Object>) testData);\r
180         testInstance.setPfloInput((HashMap<String, ParallelFlowInput>) plfoInput);\r
181 \r
182 \r
183         // Check if the test definition linked to the test instance is also present.\r
184         TestDefinition testDefinition =\r
185             Generic.findByIdGeneric(testDefinitionRepository, testInstance.getTestDefinitionId());\r
186         if (testDefinition == null) {\r
187             WorkflowResponse response = new WorkflowResponse();\r
188             response.setMessage(\r
189                 String.format(\r
190                     "Test definition with identifier %s was not found.",\r
191                     testInstance.getTestDefinitionId().toString()));\r
192             response.setMessageCode(404);\r
193             response.setResponse("Unable to start the test instance.");\r
194             TestExecution testExecution = generateTestExecution(request, testInstance, null, null);\r
195             testExecution.setTestResult(TestResult.DOES_NOT_EXIST);\r
196             testExecution.setTestDetails(generateTestDetailsWithMessage(response.getMessage()));\r
197             response.setTestExecution(testExecution);\r
198             throw new WorkflowProcessorException(response);\r
199         }\r
200 \r
201         // is using latest defintion, verify that the processDefinitionId within camunda is present in\r
202         // the test definition bpmn instance list\r
203         if (testInstance.isUseLatestTestDefinition()) {\r
204             String processDefinitionId =\r
205                 findLatestProcessDefinition(testDefinition.getProcessDefinitionKey());\r
206             boolean isBpmnInstancePresent =\r
207                 verifyIdExistsInTestDefinition(testDefinition, processDefinitionId);\r
208             if (isBpmnInstancePresent) {\r
209                 testInstance.setProcessDefinitionId(processDefinitionId);\r
210             } else {\r
211                 WorkflowResponse response = new WorkflowResponse();\r
212                 response.setMessage(\r
213                     String.format(\r
214                         "Latest Test Definition does not exist for key %s.",\r
215                         testDefinition.getProcessDefinitionKey()));\r
216                 response.setMessageCode(404);\r
217                 response.setResponse("Unable to start the test instance.");\r
218                 TestExecution testExecution =\r
219                     generateTestExecution(request, testInstance, testDefinition, null);\r
220                 testExecution.setTestResult(TestResult.DOES_NOT_EXIST);\r
221                 testExecution.setTestDetails(generateTestDetailsWithMessage(response.getMessage()));\r
222                 response.setTestExecution(testExecution);\r
223                 throw new WorkflowProcessorException(response);\r
224             }\r
225         }\r
226 \r
227         // Check if the entity making the request has permission to run the test instance.\r
228         User executor = Generic.findByIdGeneric(userRepository, request.getExecutorId());\r
229         if (executor == null) {\r
230             WorkflowResponse response = new WorkflowResponse();\r
231             response.setMessage(\r
232                 String\r
233                     .format("User with id %s was not found.", request.getExecutorId().toString()));\r
234             response.setMessageCode(404);\r
235             response.setResponse("Unable to start the test instance.");\r
236             TestExecution testExecution =\r
237                 generateTestExecution(request, testInstance, testDefinition, null);\r
238             testExecution.setTestResult(TestResult.DOES_NOT_EXIST);\r
239             testExecution.setTestDetails(generateTestDetailsWithMessage(response.getMessage()));\r
240             response.setTestExecution(testExecution);\r
241             throw new WorkflowProcessorException(response);\r
242         }\r
243 //        if (!workflowUtility.hasPermission(executor, testInstance)) {\r
244 //            WorkflowResponse response = new WorkflowResponse();\r
245 //            response.setMessage(\r
246 //                String.format(\r
247 //                    "The user with email %s does not have permission to execute test instance with id: %s.",\r
248 //                    executor.getEmail(), testInstance.get_id().toString()));\r
249 //            response.setMessageCode(401);\r
250 //            response.setResponse("Unauthorized to execute the test instance.");\r
251 //            TestExecution testExecution =\r
252 //                generateTestExecution(request, testInstance, testDefinition, executor);\r
253 //            testExecution.setTestResult(TestResult.UNAUTHORIZED);\r
254 //            testExecution.setTestDetails(generateTestDetailsWithMessage(response.getMessage()));\r
255 //            response.setTestExecution(testExecution);\r
256 //            throw new WorkflowProcessorException(response);\r
257 //        }\r
258         Group testInstanceGroup = groupRepository.findById(testInstance.getGroupId().toString()).orElse(null);\r
259         if(testInstanceGroup == null){\r
260             WorkflowResponse response = new WorkflowResponse();\r
261             response.setMessage(\r
262                     String.format("unable to find test instance group. Group id: %s",testInstance.getGroupId().toString()));\r
263             response.setMessageCode(404);\r
264             response.setResponse("unable to find test instance group");\r
265             TestExecution testExecution = generateTestExecution(request,testInstance,testDefinition,executor);\r
266             testExecution.setTestResult(TestResult.DOES_NOT_EXIST);\r
267             testExecution.setTestDetails(generateTestDetailsWithMessage(response.getMessage()));\r
268             response.setTestExecution(testExecution);\r
269             throw new WorkflowProcessorException(response);\r
270         }\r
271         if (!PermissionChecker.hasPermissionTo(executor,testInstanceGroup, UserPermission.Permission.EXECUTE,groupRepository)){\r
272             WorkflowResponse response = new WorkflowResponse();\r
273             response.setMessage(\r
274                     String.format(\r
275                             "User with email: %s does not have execute permission on test instance group with id: %s",\r
276                             executor.getEmail(),testInstance.getGroupId().toString()));\r
277             response.setMessageCode(401);\r
278             response.setResponse("unauthorized to execute test instance");\r
279             TestExecution testExecution = generateTestExecution(request,testInstance,testDefinition,executor);\r
280             testExecution.setTestResult(TestResult.UNAUTHORIZED);\r
281             testExecution.setTestDetails(generateTestDetailsWithMessage(response.getMessage()));\r
282             response.setTestExecution(testExecution);\r
283             throw new WorkflowProcessorException(response);\r
284         }\r
285 \r
286         // Generate a testExecution with a historic copy of the test instance, test definition, and the\r
287         // email of the person executing the test.\r
288         TestExecution testExecution =\r
289             generateTestExecution(request, testInstance, testDefinition, executor);\r
290 \r
291         // Prepare the test details, test result, test execution, and vth input variables for the\r
292         // process instance.\r
293         VariableMap variableMap =\r
294             Variables.createVariables()\r
295                 .putValueTyped(\r
296                     ExecutionVariable.TEST_DETAILS,\r
297                     Variables.objectValue(testExecution.getTestDetails()).create())\r
298                 .putValueTyped(\r
299                     ExecutionVariable.TEST_RESULT,\r
300                     Variables.objectValue(testExecution.getTestResult()).create())\r
301                 .putValueTyped(\r
302                     ExecutionVariable.TEST_RESULT_MESSAGE,\r
303                     Variables.objectValue(testExecution.getTestResultMessage()).create())\r
304                 .putValueTyped(ExecutionVariable.VTH_INPUT,\r
305                     Variables.objectValue(vthInput).create())\r
306                 .putValueTyped(ExecutionVariable.TEST_DATA,\r
307                     Variables.objectValue(testData).create())\r
308                 .putValue(\r
309                     ExecutionVariable.TEST_EXECUTION,\r
310                     Variables.objectValue(testExecution)\r
311                         .serializationDataFormat(Variables.SerializationDataFormats.JAVA)\r
312                         .create())\r
313                 .putValue(\r
314                     ExecutionVariable.PFLO_INPUT,\r
315                     Variables.objectValue(plfoInput)\r
316                         .serializationDataFormat(Variables.SerializationDataFormats.JAVA)\r
317                         .create());\r
318 \r
319         if (testInstance.isUseLatestTestDefinition()) {\r
320             return startProcessByKey(\r
321                 testDefinition.getProcessDefinitionKey(), variableMap, testExecution);\r
322         } else {\r
323             return startProcessById(testInstance.getProcessDefinitionId(), variableMap,\r
324                 testExecution);\r
325         }\r
326     }\r
327 \r
328     public TestExecution startProcessByKey(\r
329         String processKey, Map<String, Object> variableMap, TestExecution testExecution) {\r
330         try {\r
331             logger.info(\r
332                 "***OTF startProcessInstanceByKey with processKey: {} and variables: {}",\r
333                 processKey,\r
334                 variableMap);\r
335 \r
336             // Set the start time as close to the runtime service start function.\r
337             testExecution.setStartTime(new Date(System.currentTimeMillis()));\r
338             testExecutionRepository.insert(testExecution);\r
339 \r
340             ProcessInstance processInstance =\r
341                 runtimeService.startProcessInstanceByKey(\r
342                     processKey, testExecution.getBusinessKey(), variableMap);\r
343 \r
344             // Update the test execution object with the processInstanceId after the processInstanceId is\r
345             // available.\r
346             testExecution.setProcessInstanceId(processInstance.getProcessInstanceId());\r
347             Query query = new Query();\r
348             query.addCriteria(Criteria.where("_id").is(testExecution.get_id()));\r
349             // Also add businessKey as a criteria because the object won't be found if the business key\r
350             // was somehow modified in the workflow.\r
351             query.addCriteria(Criteria.where("businessKey").is(testExecution.getBusinessKey()));\r
352             Update update = new Update();\r
353             update.set("processInstanceId", processInstance.getProcessInstanceId());\r
354             UpdateResult result = mongoOperation.updateFirst(query, update, TestExecution.class);\r
355             // Check the status of the findAndUpdate database, and appropriately handle the errors.\r
356             if (result.getMatchedCount() == 0) {\r
357                 throw new TestExecutionException(\r
358                     String.format(\r
359                         "Unable to log the test result because a testExecution associated with _id, %s and businessKey %s, was not found.",\r
360                         testExecution.get_id(), testExecution.getBusinessKey()));\r
361             } else if (result.getModifiedCount() == 0) {\r
362                 throw new TestExecutionException(\r
363                     "Unable to persist the testExecution to the database.");\r
364             }\r
365 \r
366             logger.debug(\r
367                 logPrefix\r
368                     + "Process "\r
369                     + processKey\r
370                     + ":"\r
371                     + processInstance.getProcessInstanceId()\r
372                     + " "\r
373                     + (processInstance.isEnded() ? "ENDED" : "RUNNING"));\r
374         } catch (Exception e) {\r
375             WorkflowResponse workflowResponse = new WorkflowResponse();\r
376             workflowResponse.setResponse("Error occurred while executing the process: " + e);\r
377             workflowResponse.setProcessInstanceId(testExecution.getProcessInstanceId());\r
378             workflowResponse.setMessageCode(500);\r
379             workflowResponse.setMessage("Failed to execute test instance: " + e.getMessage());\r
380             testExecution.setTestResult(TestResult.FAILED);\r
381             testExecution\r
382                 .setTestDetails(generateTestDetailsWithMessage(workflowResponse.getMessage()));\r
383             workflowResponse.setTestExecution(testExecution);\r
384             throw new WorkflowProcessorException(workflowResponse);\r
385         }\r
386 \r
387         return testExecution;\r
388     }\r
389 \r
390     private TestExecution startProcessById(\r
391         String processId, Map<String, Object> variableMap, TestExecution testExecution) {\r
392         try {\r
393             logger.debug(\r
394                 "***OTF startProcessInstanceById with processId: {} and variables: {}",\r
395                 processId,\r
396                 variableMap);\r
397 \r
398             // Set the start time as close to the runtime service start function.\r
399             testExecution.setStartTime(new Date(System.currentTimeMillis()));\r
400             testExecutionRepository.insert(testExecution);\r
401 \r
402             ProcessInstance processInstance =\r
403                 runtimeService.startProcessInstanceById(\r
404                     processId, testExecution.getBusinessKey(), variableMap);\r
405 \r
406             // Update the test execution object with the processInstanceId after the processInstanceId is\r
407             // available.\r
408             testExecution.setProcessInstanceId(processInstance.getProcessInstanceId());\r
409             Query query = new Query();\r
410             query.addCriteria(Criteria.where("_id").is(testExecution.get_id()));\r
411             // Also add businessKey as a criteria because the object won't be found if the business key\r
412             // was somehow modified in the workflow.\r
413             query.addCriteria(Criteria.where("businessKey").is(testExecution.getBusinessKey()));\r
414             Update update = new Update();\r
415             update.set("processInstanceId", processInstance.getProcessInstanceId());\r
416             UpdateResult result = mongoOperation.updateFirst(query, update, TestExecution.class);\r
417             // Check the status of the findAndUpdate database, and appropriately handle the errors.\r
418             if (result.getMatchedCount() == 0) {\r
419                 throw new TestExecutionException(\r
420                     String.format(\r
421                         "Unable to log the test result because a testExecution associated with _id, %s and businessKey %s, was not found.",\r
422                         testExecution.get_id(), testExecution.getBusinessKey()));\r
423             } else if (result.getModifiedCount() == 0) {\r
424                 throw new TestExecutionException(\r
425                     "Unable to persist the testExecution to the database.");\r
426             }\r
427 \r
428             logger.debug(\r
429                 logPrefix\r
430                     + "Process "\r
431                     + processInstance.getProcessInstanceId()\r
432                     + ":"\r
433                     + processInstance.getProcessInstanceId()\r
434                     + " "\r
435                     + (processInstance.isEnded() ? "ENDED" : "RUNNING"));\r
436         } catch (Exception e) {\r
437             WorkflowResponse workflowResponse = new WorkflowResponse();\r
438             workflowResponse.setResponse("Error occurred while executing the process: " + e);\r
439             workflowResponse.setProcessInstanceId(testExecution.getProcessInstanceId());\r
440             workflowResponse.setMessageCode(500);\r
441             workflowResponse.setMessage("Failed to execute test instance: " + e.getMessage());\r
442             testExecution.setTestResult(TestResult.FAILED);\r
443             testExecution\r
444                 .setTestDetails(generateTestDetailsWithMessage(workflowResponse.getMessage()));\r
445             workflowResponse.setTestExecution(testExecution);\r
446             throw new WorkflowProcessorException(workflowResponse);\r
447         }\r
448 \r
449         return testExecution;\r
450     }\r
451 \r
452     private TestExecution generateTestExecution(\r
453         WorkflowRequest request,\r
454         TestInstance testInstance,\r
455         TestDefinition testDefinition,\r
456         User executor) {\r
457         TestExecution testExecution = new TestExecution();\r
458         testExecution.set_id(new ObjectId());\r
459         testExecution.setExecutorId(request.getExecutorId());\r
460         testExecution.setAsync(request.isAsync());\r
461         testExecution.setStartTime(null);\r
462         testExecution.setTestDetails(new HashMap<>());\r
463         testExecution.setTestResult(TestResult.UNKNOWN);\r
464         testExecution.setTestResultMessage("");\r
465         testExecution.setProcessInstanceId(null);\r
466         testExecution.setBusinessKey(UUID.randomUUID().toString());\r
467         testExecution.setTestHeadResults(new ArrayList<>());\r
468         testExecution.setTestInstanceResults(new ArrayList<>());\r
469         if (testInstance != null) {\r
470             testExecution.setGroupId(testInstance.getGroupId());\r
471             TestInstanceHistoric testInstanceHistoric = new TestInstanceHistoric(testInstance);\r
472             testExecution.setHistoricTestInstance(testInstanceHistoric);\r
473         }\r
474         if (testDefinition != null && testInstance != null) {\r
475             TestDefinitionHistoric testDefinitionHistoric =\r
476                 new TestDefinitionHistoric(testDefinition, testInstance.getProcessDefinitionId());\r
477             testExecution.setHistoricTestDefinition(testDefinitionHistoric);\r
478         }\r
479         if (executor != null) {\r
480             testExecution.setHistoricEmail(executor.getEmail());\r
481         }\r
482         return testExecution;\r
483     }\r
484 \r
485     private Map<String, Object> generateTestDetailsWithMessage(String message) {\r
486         Map<String, Object> map = new HashMap<>();\r
487         map.put("message", message);\r
488         return map;\r
489     }\r
490 \r
491     private String findLatestProcessDefinition(String processDefinitionKey) {\r
492         logger.info("Before find process definition key query.");\r
493         ProcessDefinition definition =\r
494             repositoryService\r
495                 .createProcessDefinitionQuery()\r
496                 .processDefinitionKey(processDefinitionKey)\r
497                 .latestVersion()\r
498                 .singleResult();\r
499         logger.info("After find process definition key query.");\r
500         String processDefinitionId = null;\r
501         if (definition != null) {\r
502             processDefinitionId = definition.getId();\r
503         }\r
504         return processDefinitionId;\r
505     }\r
506 \r
507     private boolean verifyIdExistsInTestDefinition(\r
508         TestDefinition definition, String processDefinitionId) {\r
509         if (processDefinitionId == null || definition == null) {\r
510             return false;\r
511         }\r
512 \r
513         List<BpmnInstance> bpmnInstances = definition.getBpmnInstances();\r
514         BpmnInstance bpmnInstance =\r
515             bpmnInstances.stream()\r
516                 .filter(\r
517                     _bpmnInstance -> {\r
518                         return _bpmnInstance.isDeployed()\r
519                             && _bpmnInstance.getProcessDefinitionId() != null\r
520                             && _bpmnInstance.getProcessDefinitionId().equals(processDefinitionId);\r
521                     })\r
522                 .findFirst()\r
523                 .orElse(null);\r
524         return bpmnInstance != null;\r
525     }\r
526 }\r