EXTAPI-102 Initial commit
[externalapi/nbi.git] / src / main / java / org / onap / nbi / apis / serviceorder / workflow / SOTaskProcessor.java
1 /**
2  * Copyright (c) 2018 Orange
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5  * the License. You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
10  * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11  * specific language governing permissions and limitations under the License.
12  */
13 package org.onap.nbi.apis.serviceorder.workflow;
14
15 import org.onap.nbi.apis.serviceorder.SoClient;
16 import org.onap.nbi.apis.serviceorder.model.ServiceCharacteristic;
17 import org.onap.nbi.apis.serviceorder.model.ServiceOrder;
18 import org.onap.nbi.apis.serviceorder.model.ServiceOrderItem;
19 import org.onap.nbi.apis.serviceorder.model.StateType;
20 import org.onap.nbi.apis.serviceorder.model.consumer.*;
21 import org.onap.nbi.apis.serviceorder.model.orchestrator.ExecutionTask;
22 import org.onap.nbi.apis.serviceorder.model.orchestrator.ServiceOrderInfo;
23 import org.onap.nbi.apis.serviceorder.repositories.ExecutionTaskRepository;
24 import org.onap.nbi.apis.serviceorder.service.ServiceOrderService;
25 import org.onap.nbi.apis.serviceorder.utils.E2EServiceUtils;
26 import org.onap.nbi.apis.serviceorder.utils.JsonEntityConverter;
27 import org.onap.nbi.exceptions.TechnicalException;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30 import org.springframework.beans.factory.annotation.Autowired;
31 import org.springframework.beans.factory.annotation.Value;
32 import org.springframework.http.HttpStatus;
33 import org.springframework.http.ResponseEntity;
34 import org.springframework.stereotype.Service;
35 import org.springframework.util.CollectionUtils;
36
37 import java.io.IOException;
38 import java.util.*;
39
40 @Service
41 public class SOTaskProcessor {
42
43     @Value("${nbi.callForVNF}")
44     private boolean enableCallForVNF;
45
46     @Value("${onap.lcpCloudRegionId}")
47     private String lcpCloudRegionId;
48
49     @Value("${onap.tenantId}")
50     private String tenantId;
51
52     @Value("${so.owning.entity.id}")
53     private String soOwningEntityId;
54
55     @Value("${so.owning.entity.name}")
56     private String soOwningEntityName;
57
58     @Value("${so.project.name}")
59     private String soProjectName;
60
61
62     @Autowired
63     private ServiceOrderService serviceOrderService;
64
65     @Autowired
66     private ExecutionTaskRepository executionTaskRepository;
67
68     @Autowired
69     private SoClient soClient;
70
71
72     private static final Logger LOGGER = LoggerFactory.getLogger(SOTaskProcessor.class);
73
74     /**
75      * Run the ServiceOrchestrator processing for a serviceOrderItem which with any sub relations
76      *
77      * @throws InterruptedException
78      */
79     public void processOrderItem(ExecutionTask executionTask) throws InterruptedException {
80
81         ServiceOrderInfo serviceOrderInfo = getServiceOrderInfo(executionTask);
82
83         ServiceOrder serviceOrder = serviceOrderService.findServiceOrderById(serviceOrderInfo.getServiceOrderId());
84         ServiceOrderItem serviceOrderItem = getServiceOrderItem(executionTask, serviceOrder);
85         boolean e2eService = E2EServiceUtils.isE2EService(serviceOrderInfo.getServiceOrderItemInfos().get(serviceOrderItem.getId()));
86         
87         if (StateType.ACKNOWLEDGED == serviceOrderItem.getState()) {
88                 if (e2eService) {
89                 ResponseEntity<CreateE2EServiceInstanceResponse> response = postE2EServiceOrderItem(serviceOrderInfo,
90                     serviceOrderItem, serviceOrder);
91                 updateE2EServiceOrderItem(response, serviceOrderItem, serviceOrder);
92             } else {
93
94                 ResponseEntity<CreateServiceInstanceResponse> response = postServiceOrderItem(serviceOrderInfo,serviceOrder,
95                     serviceOrderItem);
96                 updateServiceOrderItem(response, serviceOrderItem,serviceOrder);
97             }
98         }
99
100         if (executionTask.getNbRetries() > 0 && StateType.FAILED != serviceOrderItem.getState()
101             ) {
102             // TODO lancer en asynchrone
103                 if (e2eService)
104                 pollE2ESoRequestStatus(serviceOrder, serviceOrderItem);
105             else
106                 pollSoRequestStatus(serviceOrder, serviceOrderItem);
107             
108             if (serviceOrderItem.getState().equals(StateType.COMPLETED)) {
109                 updateSuccessTask(executionTask);
110             } else {
111                 int nbRetries = executionTask.getNbRetries();
112                 executionTask.setNbRetries(--nbRetries);
113                 executionTask.setLastAttemptDate(new Date());
114                 executionTaskRepository.save(executionTask);
115             }
116         } else {
117             updateFailedTask(executionTask, serviceOrder);
118         }
119
120         updateServiceOrder(serviceOrder);
121     }
122
123     private ResponseEntity<CreateServiceInstanceResponse> postServiceOrderItem(ServiceOrderInfo serviceOrderInfo,
124         ServiceOrder serviceOrder, ServiceOrderItem serviceOrderItem) {
125         ResponseEntity<CreateServiceInstanceResponse> response = null;
126         try {
127             response = postSORequest(serviceOrderItem,serviceOrder, serviceOrderInfo);
128         } catch (NullPointerException e) {
129             LOGGER.error("Unable to create service instance for serviceOrderItem.id=" + serviceOrderItem.getId(), e);
130             response = null;
131         }
132         return response;
133     }
134
135     private ResponseEntity<CreateE2EServiceInstanceResponse> postE2EServiceOrderItem(ServiceOrderInfo serviceOrderInfo,
136         ServiceOrderItem serviceOrderItem, ServiceOrder serviceOrder) {
137         ResponseEntity<CreateE2EServiceInstanceResponse> response;
138         try {
139             response = postE2ESORequest(serviceOrderItem, serviceOrderInfo, serviceOrder);
140         } catch (NullPointerException e) {
141             LOGGER.error("Unable to create service instance for serviceOrderItem.id=" + serviceOrderItem.getId(), e);
142             response = null;
143         }
144         return response;
145     }
146     
147     private ServiceOrderItem getServiceOrderItem(ExecutionTask executionTask, ServiceOrder serviceOrder) {
148         for (ServiceOrderItem item : serviceOrder.getOrderItem()) {
149             if (item.getId().equals(executionTask.getOrderItemId())) {
150                 return item;
151             }
152         }
153         throw new TechnicalException(
154             "Unable to retrieve serviceOrderItem forexecutionTaskId " + executionTask.getInternalId());
155     }
156
157     private ServiceOrderInfo getServiceOrderInfo(ExecutionTask executionTask) {
158         String serviceOrderInfoJson = executionTask.getServiceOrderInfoJson();
159         ServiceOrderInfo serviceOrderInfo = null;
160         try {
161             serviceOrderInfo =
162                 JsonEntityConverter.convertJsonToServiceOrderInfo(serviceOrderInfoJson);
163         } catch (IOException e) {
164             LOGGER
165                 .error("Unable to read ServiceOrderInfo Json for executionTaskId " + executionTask.getInternalId(), e);
166             throw new TechnicalException(
167                 "Unable to read ServiceOrderInfo Json for executionTaskId " + executionTask.getInternalId());
168         }
169         return serviceOrderInfo;
170     }
171
172     private ResponseEntity<CreateServiceInstanceResponse> postSORequest(ServiceOrderItem serviceOrderItem,
173         ServiceOrder serviceOrder, ServiceOrderInfo serviceOrderInfo) {
174         RequestDetails requestDetails = buildSoRequest(serviceOrderItem,
175             serviceOrderInfo.getServiceOrderItemInfos().get(serviceOrderItem.getId()).getCatalogResponse(),
176             serviceOrderInfo.getSubscriberInfo());
177         MSOPayload msoPayload = new MSOPayload(requestDetails);
178         ResponseEntity<CreateServiceInstanceResponse> response = null;
179
180         switch (serviceOrderItem.getAction()) {
181             case ADD:
182                 response = soClient.callCreateServiceInstance(msoPayload);
183                 break;
184             case DELETE:
185                 response = soClient.callDeleteServiceInstance(msoPayload,serviceOrderItem.getService().getId());
186                 break;
187             default:
188                 break;
189         }
190         if(response!=null && response.getStatusCode()== HttpStatus.INTERNAL_SERVER_ERROR) {
191             serviceOrderService.addOrderMessage(serviceOrder, "502");
192         }
193         return response;
194     }
195
196     private ResponseEntity<CreateE2EServiceInstanceResponse> postE2ESORequest(ServiceOrderItem serviceOrderItem,
197         ServiceOrderInfo serviceOrderInfo, ServiceOrder serviceOrder) {
198         ServiceModel service = buildE2ESoRequest(serviceOrderItem, serviceOrderInfo.getServiceOrderItemInfos().get(serviceOrderItem.getId()).getCatalogResponse(), serviceOrderInfo.getSubscriberInfo(), serviceOrder);
199         MSOE2EPayload msoE2EPayload = new MSOE2EPayload(service);
200         ResponseEntity<CreateE2EServiceInstanceResponse> response = null;
201         switch (serviceOrderItem.getAction()) {
202             case ADD:
203                 response = soClient.callE2ECreateServiceInstance(msoE2EPayload);
204                 break;
205             case DELETE:
206                 response = soClient.callE2EDeleteServiceInstance(service.getGlobalSubscriberId(), service.getServiceType(),serviceOrderItem.getService().getId());
207                 break;
208             default:
209                 break;
210         }
211         if(response!=null && response.getStatusCode()== HttpStatus.INTERNAL_SERVER_ERROR) {
212             serviceOrderService.addOrderMessage(serviceOrder, "502");
213         }
214         return response;
215     }
216     
217     private void updateServiceOrder(ServiceOrder serviceOrder) {
218         boolean atLeastOneCompleted = false;
219         boolean atLeastOneNotFinished = false;
220         boolean atLeastOneFailed = false;
221
222         for (ServiceOrderItem serviceOrderItem : serviceOrder.getOrderItem()) {
223             switch (serviceOrderItem.getState()) {
224                 case COMPLETED:
225                     atLeastOneCompleted = true;
226                     break;
227                 case INPROGRESS:
228                 case ACKNOWLEDGED:
229                     atLeastOneNotFinished = true;
230                     break;
231                 case FAILED:
232                     atLeastOneFailed = true;
233                     break;
234                 default:
235                     break;
236
237             }
238         }
239
240         if (atLeastOneNotFinished) {
241             serviceOrderService.updateOrderState(serviceOrder,StateType.INPROGRESS);
242         } else {
243             StateType finalState;
244             if (atLeastOneFailed) {
245                 if (!atLeastOneCompleted) {
246                     finalState=StateType.FAILED;
247                 } else {
248                     finalState=StateType.PARTIAL;
249                 }
250             } else {
251                 finalState=StateType.COMPLETED;
252             }
253             serviceOrderService.updateOrderState(serviceOrder,finalState);
254         }
255     }
256
257
258     /**
259      * * @param orderItem
260      */
261     private void pollSoRequestStatus(ServiceOrder serviceOrder,
262         ServiceOrderItem orderItem) throws InterruptedException {
263         boolean stopPolling = false;
264         String requestId = orderItem.getRequestId();
265         GetRequestStatusResponse response = null;
266         int nbRetries = 0;
267
268         while (!stopPolling) {
269             response = soClient.callGetRequestStatus(requestId);
270             if (response != null) {
271                 if (response.getRequest().getRequestStatus().getPercentProgress() != 100) {
272                     nbRetries++;
273                     serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS);
274                     Thread.sleep(1000);
275                     LOGGER.debug("orderitem id {} still in progress from so",orderItem.getId());
276                 } else if (RequestState.COMPLETE != response.getRequest().getRequestStatus().getRequestState()) {
277                     serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED);
278                     stopPolling = true;
279                     LOGGER.debug("orderitem id {} failed, response from request status {}",orderItem.getId(),response.getRequest().getRequestStatus().getRequestState());
280                 } else {
281                     serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.COMPLETED);
282                     stopPolling = true;
283                     LOGGER.debug("orderitem id {} completed");
284                 }
285             } else {
286                 serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS);
287                 stopPolling = true;
288                 LOGGER.debug("orderitem id {} still in progress from so",orderItem.getId());
289             }
290             if (nbRetries == 3) {
291                 stopPolling = true;
292                 LOGGER.debug("orderitem id {} stop polling from getrequeststatus, 3 retries done",orderItem.getId());
293
294             }
295         }
296     }
297
298     private void pollE2ESoRequestStatus(ServiceOrder serviceOrder, ServiceOrderItem orderItem) throws InterruptedException {
299         boolean stopPolling = false;
300         String operationId = orderItem.getRequestId();
301         String serviceId = orderItem.getService().getId();
302         int nbRetries = 0;
303         GetE2ERequestStatusResponse response = null;
304         final String ERROR = "error";
305         final String FINISHED = "finished";
306         final String PROCESSING = "processing";
307         String result = null;
308         while (!stopPolling) {
309             response = soClient.callE2EGetRequestStatus(operationId, serviceId);
310             if (response != null) {
311                 result = response.getOperation().getResult();
312                 if (PROCESSING.equals(result)) {
313                     nbRetries++;
314                     serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS);
315                     Thread.sleep(1000);
316                     LOGGER.debug("orderitem id {} still in progress from so",orderItem.getId());
317                 } else if (ERROR.equals(result)) {
318                         serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED);
319                     stopPolling = true;
320                     LOGGER.debug("orderitem id {} failed, response from request status {}",orderItem.getId(),response.getOperation().getResult());
321                 } else if (FINISHED.equals(result)) {
322                         serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.COMPLETED);
323                     stopPolling = true;
324                     LOGGER.debug("orderitem id {} completed");
325                 }
326             } else {
327                 serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS);
328                 stopPolling = true;
329                 LOGGER.debug("orderitem id {} still in progress from so",orderItem.getId());
330             }
331             if (nbRetries == 3) {
332                 stopPolling = true;
333                 LOGGER.debug("orderitem id {} stop polling from getrequeststatus, 3 retries done",orderItem.getId());
334
335             }
336         }
337     }
338     
339     /**
340      * Build SO CREATE request from the ServiceOrder and catalog informations from SDC
341      *
342      * @param orderItem
343      * @param sdcInfos
344      * @param subscriberInfo
345      * @return
346      */
347     private RequestDetails buildSoRequest(ServiceOrderItem orderItem, Map<String, Object> sdcInfos,
348         SubscriberInfo subscriberInfo) {
349         RequestDetails requestDetails = new RequestDetails();
350
351         requestDetails.setSubscriberInfo(subscriberInfo);
352
353         ModelInfo modelInfo = new ModelInfo();
354         modelInfo.setModelType("service");
355         modelInfo.setModelInvariantId((String) sdcInfos.get("invariantUUID"));
356         modelInfo.setModelNameVersionId(orderItem.getService().getServiceSpecification().getId());
357         modelInfo.setModelVersionId(orderItem.getService().getServiceSpecification().getId());
358         modelInfo.setModelName((String) sdcInfos.get("name"));
359         modelInfo.setModelVersion((String) sdcInfos.get("version"));
360         requestDetails.setModelInfo(modelInfo);
361
362         RequestInfo requestInfo = new RequestInfo();
363         requestInfo.setInstanceName(orderItem.getService().getName());
364         requestInfo.setSource("VID");
365         requestInfo.setSuppressRollback(false);
366         requestInfo.setRequestorId("NBI");
367         requestDetails.setRequestInfo(requestInfo);
368
369         RequestParameters requestParameters = new RequestParameters();
370         requestParameters.setSubscriptionServiceType((String) sdcInfos.get("name"));
371         requestParameters.setUserParams(
372             retrieveUserParamsFromServiceCharacteristics(orderItem.getService().getServiceCharacteristic()));
373         requestParameters.setaLaCarte(true);
374         requestDetails.setRequestParameters(requestParameters);
375
376         CloudConfiguration cloudConfiguration = new CloudConfiguration(lcpCloudRegionId, tenantId);
377         requestDetails.setCloudConfiguration(cloudConfiguration);
378
379         OwningEntity owningEntity = new OwningEntity();
380         owningEntity.setOwningEntityId(soOwningEntityId);
381         owningEntity.setOwningEntityName(soOwningEntityName);
382         requestDetails.setOwningEntity(owningEntity);
383
384         Project project = new Project();
385         project.setProjectName(soProjectName);
386
387         requestDetails.setProject(project);
388
389         return requestDetails;
390     }
391     
392     /**
393      * Build E2E SO CREATE request from the ServiceOrder and catalog informations from SDC
394      *
395      * @param serviceOrderItem
396      * @param serviceOrder
397      * @param sdcInfos
398      * @return
399      */
400     //ServiceOrderItem serviceOrderItem --> orderItem?
401     private ServiceModel buildE2ESoRequest(ServiceOrderItem serviceOrderItem, Map<String, Object> sdcInfos,
402             SubscriberInfo subscriberInfo, ServiceOrder serviceOrder) {
403
404         subscriberInfo.getGlobalSubscriberId();
405         ServiceModel service = new ServiceModel();
406         service.setName(serviceOrderItem.getService().getName());
407         service.setDescription(serviceOrder.getDescription());
408         service.setServiceUuid(serviceOrderItem.getService().getServiceSpecification().getId());
409         service.setServiceInvariantUuid((String) sdcInfos.get("invariantUUID"));
410         service.setGlobalSubscriberId(subscriberInfo.getGlobalSubscriberId());
411         service.setServiceType((String) sdcInfos.get("name"));
412
413         ParametersModel parameters = new ParametersModel();
414         ArrayList<ResourceModel> resources = new ArrayList();
415
416         ArrayList<Object> resourceObjects = (ArrayList<Object>)sdcInfos.get("resourceSpecification");
417
418         for(int i = 0; i < resourceObjects.size(); i++) {
419
420             ResourceModel resourceModel = new ResourceModel((Map<String, Object>)resourceObjects.get(i));
421             ParametersModel resourceParameters = new ParametersModel();
422             resourceModel.setParameters(resourceParameters);
423             resources.add(resourceModel);
424
425         }
426         parameters.setResources(resources);
427         List<UserParams> userParams = retrieveUserParamsFromServiceCharacteristics(serviceOrderItem.getService().getServiceCharacteristic());
428
429         // If there are ServiceCharacteristics add them to requestInputs
430         if (!userParams.isEmpty()){
431                 Map<String, String> requestInputs = new HashMap<String, String>();
432                 for (int i = 0; i < userParams.size(); i++) {
433                                 requestInputs.put(userParams.get(i).getName(), userParams.get(i).getValue());
434                         }
435
436                 parameters.setRequestInputs(requestInputs);
437         }
438         service.setParameters(parameters);
439
440         return service;
441     }
442
443     /**
444      * Build a list of UserParams for the SO request by browsing a list of ServiceCharacteristics from SDC
445      */
446     private List<UserParams> retrieveUserParamsFromServiceCharacteristics(List<ServiceCharacteristic> characteristics) {
447         List<UserParams> userParams = new ArrayList<>();
448
449         if (!CollectionUtils.isEmpty(characteristics)) {
450             for (ServiceCharacteristic characteristic : characteristics) {
451                 UserParams userParam = new UserParams(characteristic.getName(),
452                     characteristic.getValue().getServiceCharacteristicValue());
453                 userParams.add(userParam);
454             }
455         }
456
457         return userParams;
458     }
459
460
461     /**
462      * Update ServiceOrderItem with SO response by using serviceOrderRepository with the serviceOrderId
463      *  @param response
464      * @param orderItem
465      * @param serviceOrder
466      */
467     private void updateServiceOrderItem(ResponseEntity<CreateServiceInstanceResponse> response,
468         ServiceOrderItem orderItem, ServiceOrder serviceOrder) {
469
470         if (response==null || !response.getStatusCode().is2xxSuccessful()) {
471             LOGGER.warn("response ko for serviceOrderItem.id=" + orderItem.getId());
472             serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED);
473         }
474         else {
475             CreateServiceInstanceResponse createServiceInstanceResponse = response.getBody();
476             if (createServiceInstanceResponse != null && !orderItem.getState().equals(StateType.FAILED)) {
477                 orderItem.getService().setId(createServiceInstanceResponse.getRequestReferences().getInstanceId());
478                 orderItem.setRequestId(createServiceInstanceResponse.getRequestReferences().getRequestId());
479             }
480
481             if (!response.getStatusCode().is2xxSuccessful() || response.getBody() == null
482                 || response.getBody().getRequestReferences() == null) {
483                 serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED);
484                 LOGGER.warn("order item {} failed , status {} , response {}",orderItem.getId(),response.getStatusCode(),response.getBody());
485             } else {
486                 serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS);
487             }
488         }
489     }
490
491     /**
492      * Update E2EServiceOrderItem with SO response by using serviceOrderRepository with the serviceOrderId
493      *  @param response
494      * @param orderItem
495      * @param serviceOrder
496      */
497     private void updateE2EServiceOrderItem(ResponseEntity<CreateE2EServiceInstanceResponse> response,
498         ServiceOrderItem orderItem, ServiceOrder serviceOrder) {
499
500         if (response==null || !response.getStatusCode().is2xxSuccessful()) {
501             LOGGER.warn("response ko for serviceOrderItem.id=" + orderItem.getId());
502             serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED);
503         }
504         else {
505             CreateE2EServiceInstanceResponse createE2EServiceInstanceResponse = response.getBody();
506             if (createE2EServiceInstanceResponse != null && !orderItem.getState().equals(StateType.FAILED)) {
507                 orderItem.getService().setId(createE2EServiceInstanceResponse.getService().getServiceId());
508                 orderItem.setRequestId(createE2EServiceInstanceResponse.getService().getOperationId());
509             }
510
511             if (!response.getStatusCode().is2xxSuccessful() || response.getBody() == null
512                 || response.getBody().getService().getOperationId() == null || response.getBody().getService().getServiceId() == null) {
513                 serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED);
514                 LOGGER.warn("order item {} failed , status {} , response {}",orderItem.getId(),response.getStatusCode(),response.getBody());
515             } else {
516                 serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS);
517             }
518         }
519     }
520     
521     /**
522      * Update an executionTask in database when it's process with a success
523      *
524      * @param executionTask
525      */
526     private void updateSuccessTask(ExecutionTask executionTask) {
527         executionTaskRepository.delete(executionTask.getInternalId());
528         executionTaskRepository.updateReliedTaskAfterDelete(executionTask.getInternalId());
529
530     }
531
532     /**
533      * @param executionTask
534      * @param serviceOrder
535      */
536     private void updateFailedTask(ExecutionTask executionTask, ServiceOrder serviceOrder) {
537         List<ExecutionTask> executionTasksToDelete = findExecutionTasksRecursively(executionTask);
538         for (ExecutionTask taskId : executionTasksToDelete) {
539             executionTaskRepository.delete(taskId);
540             LOGGER.warn("task {} with orderitem id {} deleted cause orderitem id {} failed ",taskId.getInternalId(),taskId.getOrderItemId(),executionTask.getOrderItemId());
541         }
542         for (ServiceOrderItem item : serviceOrder.getOrderItem()) {
543             for (ExecutionTask taskToDelete : executionTasksToDelete) {
544                 if (taskToDelete.getOrderItemId().equals(item.getId())) {
545                     serviceOrderService.updateOrderItemState(serviceOrder,item,StateType.FAILED);
546                     LOGGER.warn("task {} with orderitem id {}  to failed cause orderitem id {} failed ",taskToDelete.getInternalId(),taskToDelete.getOrderItemId(),executionTask.getOrderItemId());
547
548                 }
549             }
550         }
551     }
552
553     /**
554      * @param executionTask
555      * @return
556      */
557     private List<ExecutionTask> findExecutionTasksRecursively(ExecutionTask executionTask) {
558
559         List<ExecutionTask> executionTasks = new ArrayList<>();
560
561         List<ExecutionTask> tasksReliedToAnOrderItemId =
562             executionTaskRepository.findTasksReliedToAnOrderItemId(executionTask.getInternalId());
563
564         if (CollectionUtils.isEmpty(tasksReliedToAnOrderItemId)) {
565             return Arrays.asList(executionTask);
566         } else {
567             for (ExecutionTask task : tasksReliedToAnOrderItemId) {
568                 executionTasks.addAll(findExecutionTasksRecursively(task));
569             }
570         }
571         executionTasks.add(executionTask);
572         return executionTasks;
573     }
574
575
576 }