7c954ff4da1f9d3c0b14b57bc88395b2c3a10a76
[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         buildOrderMessageIfNeeded(serviceOrderItem, serviceOrder, response);
191         return response;
192     }
193
194     private void buildOrderMessageIfNeeded(ServiceOrderItem serviceOrderItem, ServiceOrder serviceOrder,
195         ResponseEntity<?> response) {
196         if(response!=null)
197         {
198             if(response.getStatusCode()== HttpStatus.INTERNAL_SERVER_ERROR) {
199                 serviceOrderService.addOrderMessage(serviceOrder, "502");
200             }
201             if(response.getStatusCode()== HttpStatus.BAD_REQUEST) {
202                 ResponseEntity<?> messageError=response;
203                 if(messageError.getBody().toString().toLowerCase().contains("serviceinstance already exists")){
204                     serviceOrderService.addOrderItemMessage(serviceOrder, serviceOrderItem, "105");
205                 }
206             }
207         }
208     }
209
210     private ResponseEntity<CreateE2EServiceInstanceResponse> postE2ESORequest(ServiceOrderItem serviceOrderItem,
211         ServiceOrderInfo serviceOrderInfo, ServiceOrder serviceOrder) {
212         ServiceModel service = buildE2ESoRequest(serviceOrderItem, serviceOrderInfo.getServiceOrderItemInfos().get(serviceOrderItem.getId()).getCatalogResponse(), serviceOrderInfo.getSubscriberInfo(), serviceOrder);
213         MSOE2EPayload msoE2EPayload = new MSOE2EPayload(service);
214         ResponseEntity<CreateE2EServiceInstanceResponse> response = null;
215         switch (serviceOrderItem.getAction()) {
216             case ADD:
217                 response = soClient.callE2ECreateServiceInstance(msoE2EPayload);
218                 break;
219             case DELETE:
220                 response = soClient.callE2EDeleteServiceInstance(service.getGlobalSubscriberId(), service.getServiceType(),serviceOrderItem.getService().getId());
221                 break;
222             default:
223                 break;
224         }
225         buildOrderMessageIfNeeded(serviceOrderItem, serviceOrder, response);
226         return response;
227     }
228
229     private void updateServiceOrder(ServiceOrder serviceOrder) {
230         boolean atLeastOneCompleted = false;
231         boolean atLeastOneNotFinished = false;
232         boolean atLeastOneFailed = false;
233
234         for (ServiceOrderItem serviceOrderItem : serviceOrder.getOrderItem()) {
235             switch (serviceOrderItem.getState()) {
236                 case COMPLETED:
237                     atLeastOneCompleted = true;
238                     break;
239                 case INPROGRESS:
240                 case ACKNOWLEDGED:
241                     atLeastOneNotFinished = true;
242                     break;
243                 case FAILED:
244                     atLeastOneFailed = true;
245                     break;
246                 default:
247                     break;
248
249             }
250         }
251
252         if (atLeastOneNotFinished) {
253             serviceOrderService.updateOrderState(serviceOrder,StateType.INPROGRESS);
254         } else {
255             StateType finalState;
256             if (atLeastOneFailed) {
257                 if (!atLeastOneCompleted) {
258                     finalState=StateType.FAILED;
259                 } else {
260                     finalState=StateType.PARTIAL;
261                 }
262             } else {
263                 finalState=StateType.COMPLETED;
264             }
265             serviceOrderService.updateOrderState(serviceOrder,finalState);
266         }
267     }
268
269
270     /**
271      * * @param orderItem
272      */
273     private void pollSoRequestStatus(ServiceOrder serviceOrder,
274         ServiceOrderItem orderItem) throws InterruptedException {
275         boolean stopPolling = false;
276         String requestId = orderItem.getRequestId();
277         GetRequestStatusResponse response = null;
278         int nbRetries = 0;
279
280         while (!stopPolling) {
281             response = soClient.callGetRequestStatus(requestId);
282             if (response != null) {
283                 if (response.getRequest().getRequestStatus().getPercentProgress() != 100) {
284                     nbRetries++;
285                     serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS);
286                     Thread.sleep(1000);
287                     LOGGER.debug("orderitem id {} still in progress from so",orderItem.getId());
288                 } else if (RequestState.COMPLETE != response.getRequest().getRequestStatus().getRequestState()) {
289                     serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED);
290                     stopPolling = true;
291                     LOGGER.debug("orderitem id {} failed, response from request status {}",orderItem.getId(),response.getRequest().getRequestStatus().getRequestState());
292                 } else {
293                     serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.COMPLETED);
294                     stopPolling = true;
295                     LOGGER.debug("orderitem id {} completed");
296                 }
297             } else {
298                 serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS);
299                 stopPolling = true;
300                 LOGGER.debug("orderitem id {} still in progress from so",orderItem.getId());
301             }
302             if (nbRetries == 3) {
303                 stopPolling = true;
304                 LOGGER.debug("orderitem id {} stop polling from getrequeststatus, 3 retries done",orderItem.getId());
305
306             }
307         }
308     }
309
310     private void pollE2ESoRequestStatus(ServiceOrder serviceOrder, ServiceOrderItem orderItem) throws InterruptedException {
311         boolean stopPolling = false;
312         String operationId = orderItem.getRequestId();
313         String serviceId = orderItem.getService().getId();
314         int nbRetries = 0;
315         GetE2ERequestStatusResponse response = null;
316         final String ERROR = "error";
317         final String FINISHED = "finished";
318         final String PROCESSING = "processing";
319         String result = null;
320         while (!stopPolling) {
321             response = soClient.callE2EGetRequestStatus(operationId, serviceId);
322             if (response != null) {
323                 result = response.getOperation().getResult();
324                 if (PROCESSING.equals(result)) {
325                     nbRetries++;
326                     serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS);
327                     Thread.sleep(1000);
328                     LOGGER.debug("orderitem id {} still in progress from so",orderItem.getId());
329                 } else if (ERROR.equals(result)) {
330                         serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED);
331                     stopPolling = true;
332                     LOGGER.debug("orderitem id {} failed, response from request status {}",orderItem.getId(),response.getOperation().getResult());
333                 } else if (FINISHED.equals(result)) {
334                         serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.COMPLETED);
335                     stopPolling = true;
336                     LOGGER.debug("orderitem id {} completed");
337                 }
338             } else {
339                 serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS);
340                 stopPolling = true;
341                 LOGGER.debug("orderitem id {} still in progress from so",orderItem.getId());
342             }
343             if (nbRetries == 3) {
344                 stopPolling = true;
345                 LOGGER.debug("orderitem id {} stop polling from getrequeststatus, 3 retries done",orderItem.getId());
346
347             }
348         }
349     }
350
351     /**
352      * Build SO CREATE request from the ServiceOrder and catalog informations from SDC
353      *
354      * @param orderItem
355      * @param sdcInfos
356      * @param subscriberInfo
357      * @return
358      */
359     private RequestDetails buildSoRequest(ServiceOrderItem orderItem, Map<String, Object> sdcInfos,
360         SubscriberInfo subscriberInfo) {
361         RequestDetails requestDetails = new RequestDetails();
362
363         requestDetails.setSubscriberInfo(subscriberInfo);
364
365         ModelInfo modelInfo = new ModelInfo();
366         modelInfo.setModelType("service");
367         modelInfo.setModelInvariantId((String) sdcInfos.get("invariantUUID"));
368         modelInfo.setModelNameVersionId(orderItem.getService().getServiceSpecification().getId());
369         modelInfo.setModelVersionId(orderItem.getService().getServiceSpecification().getId());
370         modelInfo.setModelName((String) sdcInfos.get("name"));
371         modelInfo.setModelVersion((String) sdcInfos.get("version"));
372         requestDetails.setModelInfo(modelInfo);
373
374         RequestInfo requestInfo = new RequestInfo();
375         requestInfo.setInstanceName(orderItem.getService().getName());
376         requestInfo.setSource("VID");
377         requestInfo.setSuppressRollback(false);
378         requestInfo.setRequestorId("NBI");
379         requestDetails.setRequestInfo(requestInfo);
380
381         RequestParameters requestParameters = new RequestParameters();
382         requestParameters.setSubscriptionServiceType((String) sdcInfos.get("name"));
383         requestParameters.setUserParams(
384             retrieveUserParamsFromServiceCharacteristics(orderItem.getService().getServiceCharacteristic()));
385         requestParameters.setaLaCarte(true);
386         requestDetails.setRequestParameters(requestParameters);
387
388         CloudConfiguration cloudConfiguration = new CloudConfiguration(lcpCloudRegionId, tenantId);
389         requestDetails.setCloudConfiguration(cloudConfiguration);
390
391         OwningEntity owningEntity = new OwningEntity();
392         owningEntity.setOwningEntityId(soOwningEntityId);
393         owningEntity.setOwningEntityName(soOwningEntityName);
394         requestDetails.setOwningEntity(owningEntity);
395
396         Project project = new Project();
397         project.setProjectName(soProjectName);
398
399         requestDetails.setProject(project);
400
401         return requestDetails;
402     }
403
404     /**
405      * Build E2E SO CREATE request from the ServiceOrder and catalog informations from SDC
406      *
407      * @param serviceOrderItem
408      * @param serviceOrder
409      * @param sdcInfos
410      * @return
411      */
412     //ServiceOrderItem serviceOrderItem --> orderItem?
413     private ServiceModel buildE2ESoRequest(ServiceOrderItem serviceOrderItem, Map<String, Object> sdcInfos,
414             SubscriberInfo subscriberInfo, ServiceOrder serviceOrder) {
415
416         subscriberInfo.getGlobalSubscriberId();
417         ServiceModel service = new ServiceModel();
418         service.setName(serviceOrderItem.getService().getName());
419         service.setDescription(serviceOrder.getDescription());
420         service.setServiceUuid(serviceOrderItem.getService().getServiceSpecification().getId());
421         service.setServiceInvariantUuid((String) sdcInfos.get("invariantUUID"));
422         service.setGlobalSubscriberId(subscriberInfo.getGlobalSubscriberId());
423         service.setServiceType((String) sdcInfos.get("name"));
424
425         ParametersModel parameters = new ParametersModel();
426         ArrayList<ResourceModel> resources = new ArrayList();
427
428         ArrayList<Object> resourceObjects = (ArrayList<Object>)sdcInfos.get("resourceSpecification");
429
430         for(int i = 0; i < resourceObjects.size(); i++) {
431
432             ResourceModel resourceModel = new ResourceModel((Map<String, Object>)resourceObjects.get(i));
433             ParametersModel resourceParameters = new ParametersModel();
434             resourceModel.setParameters(resourceParameters);
435             resources.add(resourceModel);
436
437         }
438         parameters.setResources(resources);
439         List<UserParams> userParams = retrieveUserParamsFromServiceCharacteristics(serviceOrderItem.getService().getServiceCharacteristic());
440
441         // If there are ServiceCharacteristics add them to requestInputs
442         if (!userParams.isEmpty()){
443                 Map<String, String> requestInputs = new HashMap<String, String>();
444                 for (int i = 0; i < userParams.size(); i++) {
445                                 requestInputs.put(userParams.get(i).getName(), userParams.get(i).getValue());
446                         }
447
448                 parameters.setRequestInputs(requestInputs);
449         }
450         service.setParameters(parameters);
451
452         return service;
453     }
454
455     /**
456      * Build a list of UserParams for the SO request by browsing a list of ServiceCharacteristics from SDC
457      */
458     private List<UserParams> retrieveUserParamsFromServiceCharacteristics(List<ServiceCharacteristic> characteristics) {
459         List<UserParams> userParams = new ArrayList<>();
460
461         if (!CollectionUtils.isEmpty(characteristics)) {
462             for (ServiceCharacteristic characteristic : characteristics) {
463                 UserParams userParam = new UserParams(characteristic.getName(),
464                     characteristic.getValue().getServiceCharacteristicValue());
465                 userParams.add(userParam);
466             }
467         }
468
469         return userParams;
470     }
471
472
473     /**
474      * Update ServiceOrderItem with SO response by using serviceOrderRepository with the serviceOrderId
475      *  @param response
476      * @param orderItem
477      * @param serviceOrder
478      */
479     private void updateServiceOrderItem(ResponseEntity<CreateServiceInstanceResponse> response,
480         ServiceOrderItem orderItem, ServiceOrder serviceOrder) {
481
482         if (response==null || !response.getStatusCode().is2xxSuccessful()) {
483             LOGGER.warn("response ko for serviceOrderItem.id=" + orderItem.getId());
484             serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED);
485         }
486         else {
487             CreateServiceInstanceResponse createServiceInstanceResponse = response.getBody();
488             if (createServiceInstanceResponse != null && !orderItem.getState().equals(StateType.FAILED)) {
489                 orderItem.getService().setId(createServiceInstanceResponse.getRequestReferences().getInstanceId());
490                 orderItem.setRequestId(createServiceInstanceResponse.getRequestReferences().getRequestId());
491             }
492
493             if (!response.getStatusCode().is2xxSuccessful() || response.getBody() == null
494                 || response.getBody().getRequestReferences() == null) {
495                 serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED);
496                 LOGGER.warn("order item {} failed , status {} , response {}",orderItem.getId(),response.getStatusCode(),response.getBody());
497             } else {
498                 serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS);
499             }
500         }
501     }
502
503     /**
504      * Update E2EServiceOrderItem with SO response by using serviceOrderRepository with the serviceOrderId
505      *  @param response
506      * @param orderItem
507      * @param serviceOrder
508      */
509     private void updateE2EServiceOrderItem(ResponseEntity<CreateE2EServiceInstanceResponse> response,
510         ServiceOrderItem orderItem, ServiceOrder serviceOrder) {
511
512         if (response==null || !response.getStatusCode().is2xxSuccessful()) {
513             LOGGER.warn("response ko for serviceOrderItem.id=" + orderItem.getId());
514             serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED);
515         }
516         else {
517             CreateE2EServiceInstanceResponse createE2EServiceInstanceResponse = response.getBody();
518             if (createE2EServiceInstanceResponse != null && !orderItem.getState().equals(StateType.FAILED)) {
519                 orderItem.getService().setId(createE2EServiceInstanceResponse.getService().getServiceId());
520                 orderItem.setRequestId(createE2EServiceInstanceResponse.getService().getOperationId());
521             }
522
523             if (!response.getStatusCode().is2xxSuccessful() || response.getBody() == null
524                 || response.getBody().getService().getOperationId() == null || response.getBody().getService().getServiceId() == null) {
525                 serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.FAILED);
526                 LOGGER.warn("order item {} failed , status {} , response {}",orderItem.getId(),response.getStatusCode(),response.getBody());
527             } else {
528                 serviceOrderService.updateOrderItemState(serviceOrder,orderItem,StateType.INPROGRESS);
529             }
530         }
531     }
532
533     /**
534      * Update an executionTask in database when it's process with a success
535      *
536      * @param executionTask
537      */
538     private void updateSuccessTask(ExecutionTask executionTask) {
539         executionTaskRepository.delete(executionTask.getInternalId());
540         executionTaskRepository.updateReliedTaskAfterDelete(executionTask.getInternalId());
541
542     }
543
544     /**
545      * @param executionTask
546      * @param serviceOrder
547      */
548     private void updateFailedTask(ExecutionTask executionTask, ServiceOrder serviceOrder) {
549         List<ExecutionTask> executionTasksToDelete = findExecutionTasksRecursively(executionTask);
550         for (ExecutionTask taskId : executionTasksToDelete) {
551             executionTaskRepository.delete(taskId);
552             LOGGER.warn("task {} with orderitem id {} deleted cause orderitem id {} failed ",taskId.getInternalId(),taskId.getOrderItemId(),executionTask.getOrderItemId());
553         }
554         for (ServiceOrderItem item : serviceOrder.getOrderItem()) {
555             for (ExecutionTask taskToDelete : executionTasksToDelete) {
556                 if (taskToDelete.getOrderItemId().equals(item.getId())) {
557                     serviceOrderService.updateOrderItemState(serviceOrder,item,StateType.FAILED);
558                     LOGGER.warn("task {} with orderitem id {}  to failed cause orderitem id {} failed ",taskToDelete.getInternalId(),taskToDelete.getOrderItemId(),executionTask.getOrderItemId());
559
560                 }
561             }
562         }
563     }
564
565     /**
566      * @param executionTask
567      * @return
568      */
569     private List<ExecutionTask> findExecutionTasksRecursively(ExecutionTask executionTask) {
570
571         List<ExecutionTask> executionTasks = new ArrayList<>();
572
573         List<ExecutionTask> tasksReliedToAnOrderItemId =
574             executionTaskRepository.findTasksReliedToAnOrderItemId(executionTask.getInternalId());
575
576         if (CollectionUtils.isEmpty(tasksReliedToAnOrderItemId)) {
577             return Arrays.asList(executionTask);
578         } else {
579             for (ExecutionTask task : tasksReliedToAnOrderItemId) {
580                 executionTasks.addAll(findExecutionTasksRecursively(task));
581             }
582         }
583         executionTasks.add(executionTask);
584         return executionTasks;
585     }
586
587
588 }