2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.vid.services;
23 import static java.util.stream.Collectors.counting;
24 import static java.util.function.Function.identity;
25 import static java.util.stream.Collectors.groupingBy;
26 import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
27 import static org.onap.vid.controller.MsoController.SVC_INSTANCE_ID;
28 import static org.onap.vid.controller.MsoController.VNF_INSTANCE_ID;
29 import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
31 import com.google.common.collect.ImmutableMap;
32 import java.io.IOException;
33 import java.time.ZonedDateTime;
34 import java.util.ArrayList;
35 import java.util.Calendar;
36 import java.util.Collection;
37 import java.util.Date;
38 import java.util.HashMap;
39 import java.util.List;
41 import java.util.UUID;
42 import java.util.function.Consumer;
43 import java.util.function.Function;
44 import java.util.stream.Collectors;
45 import org.apache.commons.collections.CollectionUtils;
46 import org.apache.commons.lang3.StringUtils;
47 import org.hibernate.SessionFactory;
48 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
49 import org.onap.vid.aai.AaiClientInterface;
50 import org.onap.vid.aai.model.ResourceType;
51 import org.onap.vid.dal.AsyncInstantiationRepository;
52 import org.onap.vid.exceptions.DbFailureUncheckedException;
53 import org.onap.vid.exceptions.GenericUncheckedException;
54 import org.onap.vid.exceptions.MaxRetriesException;
55 import org.onap.vid.exceptions.OperationNotAllowedException;
56 import org.onap.vid.job.Job;
57 import org.onap.vid.job.Job.JobStatus;
58 import org.onap.vid.job.JobAdapter;
59 import org.onap.vid.job.JobType;
60 import org.onap.vid.job.JobsBrokerService;
61 import org.onap.vid.job.impl.JobSharedData;
62 import org.onap.vid.model.Action;
63 import org.onap.vid.model.NameCounter;
64 import org.onap.vid.model.ResourceInfo;
65 import org.onap.vid.model.ServiceInfo;
66 import org.onap.vid.model.serviceInstantiation.BaseResource;
67 import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
68 import org.onap.vid.mso.MsoBusinessLogicImpl;
69 import org.onap.vid.mso.MsoProperties;
70 import org.onap.vid.mso.MsoUtil;
71 import org.onap.vid.mso.RestObject;
72 import org.onap.vid.mso.rest.AsyncRequestStatus;
73 import org.onap.vid.mso.rest.RequestStatus;
74 import org.onap.vid.properties.Features;
75 import org.onap.vid.utils.DaoUtils;
76 import org.onap.vid.utils.TimeUtils;
77 import org.springframework.beans.factory.annotation.Autowired;
78 import org.springframework.stereotype.Service;
79 import org.togglz.core.manager.FeatureManager;
82 public class AsyncInstantiationBusinessLogicImpl implements
83 AsyncInstantiationBusinessLogic {
85 private static final int MAX_RETRIES_GETTING_COUNTER = 100;
86 private static final int MAX_RETRIES_GETTING_FREE_NAME_FROM_AAI = 10000;
87 public static final String NAME_FOR_CHECK_AAI_STATUS = "NAME_FOR_CHECK_AAI_STATUS";
89 private final JobAdapter jobAdapter;
91 private final JobsBrokerService jobService;
93 private final CloudOwnerService cloudOwnerService;
95 private final AsyncInstantiationRepository asyncInstantiationRepository;
97 private SessionFactory sessionFactory;
99 private AaiClientInterface aaiClient;
101 private FeatureManager featureManager;
103 private AuditService auditService;
106 private int maxRetriesGettingFreeNameFromAai = MAX_RETRIES_GETTING_FREE_NAME_FROM_AAI;
108 private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AsyncInstantiationBusinessLogicImpl.class);
109 private Map<String, JobStatus> msoStateToJobStatusMap = ImmutableMap.<String, JobStatus>builder()
110 .put("inprogress", JobStatus.IN_PROGRESS)
111 .put("failed", JobStatus.FAILED)
112 .put("pause", JobStatus.PAUSE)
113 .put("paused", JobStatus.PAUSE)
114 .put("complete", JobStatus.COMPLETED)
115 .put("pending", JobStatus.IN_PROGRESS)
116 .put("pendingmanualtask", JobStatus.PAUSE)
117 .put("unlocked", JobStatus.IN_PROGRESS)
118 .put("aborted", JobStatus.COMPLETED_WITH_ERRORS)
119 .put("rolledback", JobStatus.FAILED)
120 .put("rolledbacktoassigned", JobStatus.FAILED)
121 .put("rolledbacktocreated", JobStatus.FAILED)
126 public AsyncInstantiationBusinessLogicImpl(JobAdapter jobAdapter,
127 JobsBrokerService jobService,
128 SessionFactory sessionFactory,
129 AaiClientInterface aaiClient,
130 FeatureManager featureManager,
131 CloudOwnerService cloudOwnerService, AsyncInstantiationRepository asyncInstantiationRepository,
132 AuditService auditService) {
133 this.jobAdapter = jobAdapter;
134 this.jobService = jobService;
135 this.sessionFactory = sessionFactory;
136 this.aaiClient = aaiClient;
137 this.featureManager = featureManager;
138 this.cloudOwnerService = cloudOwnerService;
139 this.asyncInstantiationRepository = asyncInstantiationRepository;
140 this.auditService = auditService;
144 public List<ServiceInfo> getAllServicesInfo() {
145 return asyncInstantiationRepository.getAllServicesInfo();
148 JobType getJobType(ServiceInstantiation request) {
149 if (request.isALaCarte()) {
150 switch (defaultIfNull(request.getAction(), Action.Create)) {
152 return JobType.ALaCarteService;
154 return JobType.ALaCarteService;
156 return JobType.ALaCarteServiceInstantiation;
159 return JobType.MacroServiceInstantiation;
164 public List<UUID> pushBulkJob(ServiceInstantiation request, String userId) {
166 List<UUID> uuids = new ArrayList<>();
167 Date createdBulkDate = Calendar.getInstance().getTime();
168 int bulkSize = request.getBulkSize();
169 UUID templateId = UUID.randomUUID();
170 for (int i = 0; i < bulkSize; i++) {
171 ServiceInstantiation requestPerJob = prepareServiceToBeUnique(request);
172 ServiceInfo.ServiceAction serviceAction = getAction(requestPerJob);
173 JobType jobType = getJobType(requestPerJob);
174 final String optimisticUniqueServiceInstanceName = bulkSize>1 ? //only bulk with more than 1 service need to get multiple names
175 getOptimisticUniqueServiceInstanceName(requestPerJob.getInstanceName()) : requestPerJob.getInstanceName();
176 Job job = jobAdapter.createServiceInstantiationJob(jobType, requestPerJob, templateId, userId, request.getTestApi(), optimisticUniqueServiceInstanceName, i);
177 UUID jobId = job.getUuid();
179 asyncInstantiationRepository.saveServiceInfo(createServiceInfo(userId, requestPerJob, jobId, templateId, createdBulkDate, optimisticUniqueServiceInstanceName, serviceAction));
180 asyncInstantiationRepository.addJobRequest(jobId, requestPerJob);
181 auditService.auditVidStatus(jobId, job.getStatus());
189 public Map<String, Long> getSummarizedChildrenMap(ServiceInstantiation serviceInstantiation){
190 List<String> existingTypesList = new ArrayList<>();
191 Map<String, Long> existingTypesCounters;
193 existingTypesList = getChildrenList(serviceInstantiation, existingTypesList);
194 existingTypesCounters = existingTypesList.stream().collect(groupingBy(identity(), counting()));
196 return existingTypesCounters;
199 private List<String> getChildrenList(BaseResource resource, List<String> list){
200 Collection<? extends BaseResource> children = resource.getChildren();
201 if (CollectionUtils.isNotEmpty(children)){
202 children.forEach( child -> {
203 String childType = child.getModelInfo().getModelType();
204 getChildrenList(child, list);
211 private ServiceInfo.ServiceAction getAction(ServiceInstantiation request) {
212 if (request.getAction() == null) {
213 //throw new GenericUncheckedException("Required 'action' field not provided at service level");
214 return Action.Create.getServiceAction();
216 return request.getAction().getServiceAction();
220 private String getOptimisticUniqueServiceInstanceName(String instanceName) {
221 return StringUtils.isNotEmpty(instanceName) ? getUniqueNameFromDbOnly(instanceName) : instanceName;
224 protected ServiceInfo createServiceInfo(String userId, ServiceInstantiation serviceInstantiation, UUID jobId, UUID templateId, Date createdBulkDate, String optimisticUniqueServiceInstanceName, ServiceInfo.ServiceAction serviceAction) {
225 return new ServiceInfo(
227 serviceInstantiation.isALaCarte(),
228 Job.JobStatus.PENDING, serviceInstantiation.isPause(), jobId, templateId,
229 serviceInstantiation.getOwningEntityId(),
230 serviceInstantiation.getOwningEntityName(),
231 serviceInstantiation.getProjectName(),
232 serviceInstantiation.getAicZoneId(),
233 serviceInstantiation.getAicZoneName(),
234 serviceInstantiation.getTenantId(),
235 serviceInstantiation.getTenantName(),
236 serviceInstantiation.getLcpCloudRegionId(),
238 serviceInstantiation.getSubscriptionServiceType(),
239 serviceInstantiation.getSubscriberName(),
240 serviceInstantiation.getGlobalSubscriberId(),
241 serviceInstantiation.getInstanceId(),
242 optimisticUniqueServiceInstanceName,
243 serviceInstantiation.getModelInfo().getModelVersionId(),
244 serviceInstantiation.getModelInfo().getModelName(),
245 serviceInstantiation.getModelInfo().getModelVersion(),
252 public boolean isPartOfBulk(UUID jobId) {
256 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobId);
257 UUID templateId = serviceInfo.getTemplateId();
258 if (templateId != null) {
259 return getNumberOfJobsInBulk(templateId) > 1;
265 private int getNumberOfJobsInBulk(UUID templateId) {
266 String hqlSelectJob = "from JobDaoImpl where templateId = :templateId";
267 return DaoUtils.tryWithSessionAndTransaction(sessionFactory, session ->
268 session.createQuery(hqlSelectJob)
269 .setText("templateId", templateId.toString())
276 public String getServiceInstantiationPath(ServiceInstantiation serviceInstantiationRequest) {
277 //in case pause flag is true - use assign , else - use create.
278 return MsoBusinessLogicImpl.validateEndpointPath(
279 serviceInstantiationRequest.isPause() ?
280 MsoProperties.MSO_REST_API_SERVICE_INSTANCE_ASSIGN : MsoProperties.MSO_RESTAPI_SERVICE_INSTANCE
285 public String getServiceDeletionPath(String serviceInstanceId) {
286 return MsoBusinessLogicImpl.validateEndpointPath( MsoProperties.MSO_RESTAPI_SERVICE_INSTANCE) + "/" + serviceInstanceId;
290 public String getVnfInstantiationPath(String serviceInstanceId) {
291 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE).
292 replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
296 public String getVnfDeletionPath(String serviceInstanceId, String vnfInstanceId) {
297 return (MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE)
298 + '/' + vnfInstanceId)
299 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId).replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
303 public String getNetworkInstantiationPath(String serviceInstanceId) {
304 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_NETWORK_INSTANCE).
305 replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
309 public String getVfmoduleInstantiationPath(String serviceInstanceId, String vnfInstanceId) {
310 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE)
311 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
312 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
316 public String getVfModuleReplacePath(String serviceInstanceId, String vnfInstanceId, String vfModuleInstanceId)
318 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE)
319 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
320 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId)
321 + "/" + vfModuleInstanceId
326 public String getVfModuleDeletePath(String serviceInstanceId, String vnfInstanceId, String vfModuleInstanceId) {
327 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE)
328 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
329 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId)
330 + "/" + vfModuleInstanceId;
334 public String getVolumeGroupInstantiationPath(String serviceInstanceId, String vnfInstanceId) {
335 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VOLUME_GROUP_INSTANCE)
336 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
337 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
341 public String getInstanceGroupInstantiationPath() {
342 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP);
346 public String getInstanceGroupMemberInstantiationPath(String vnfGroupInstanceId) {
347 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP)
348 + '/' + vnfGroupInstanceId + "/addMembers";
352 public String getInstanceGroupDeletePath(String instanceGroupId) {
353 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP)
354 + '/' + instanceGroupId;
358 public String getInstanceGroupMemberDeletePath(String vnfGroupInstanceId){
359 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP)
360 + '/' + vnfGroupInstanceId + "/removeMembers";
364 public String getNetworkDeletePath(String serviceInstanceId, String networkInstanceId) {
365 return (MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_NETWORK_INSTANCE)
366 + "/" + networkInstanceId)
367 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
371 public String getResumeRequestPath(String requestId) {
372 return MsoBusinessLogicImpl.validateEndpointPath("mso.restapi.resume.orc.req")
373 .replaceFirst("<request_id>", requestId);
377 public String getOrchestrationRequestsPath() {
378 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_GET_ORC_REQ);
382 public ServiceInfo updateServiceInfo(UUID jobUUID, Consumer<ServiceInfo> serviceUpdater) {
383 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobUUID);
384 serviceUpdater.accept(serviceInfo);
385 asyncInstantiationRepository.saveServiceInfo(serviceInfo);
390 public ServiceInfo updateServiceInfoAndAuditStatus(UUID jobUuid, JobStatus jobStatus) {
391 auditService.auditVidStatus(jobUuid, jobStatus);
392 return updateServiceInfo(jobUuid, x -> setServiceInfoStatus(x, jobStatus));
395 private boolean isRetryEnabledForStatus(JobStatus jobStatus) {
396 return featureManager.isActive(Features.FLAG_1902_RETRY_JOB) &&
397 (jobStatus==JobStatus.COMPLETED_WITH_ERRORS || jobStatus==JobStatus.FAILED);
400 private void setServiceInfoStatus(ServiceInfo serviceInfo, JobStatus jobStatus) {
401 serviceInfo.setJobStatus(jobStatus);
402 serviceInfo.setStatusModifiedDate(new Date());
403 serviceInfo.setRetryEnabled(isRetryEnabledForStatus(jobStatus));
406 public Job.JobStatus calcStatus(AsyncRequestStatus asyncRequestStatus) {
407 String msoRequestState = asyncRequestStatus.request.requestStatus.getRequestState().toLowerCase().replaceAll("[^a-z]+", "");
408 JobStatus jobStatus = msoStateToJobStatusMap.get(msoRequestState);
409 return (jobStatus != null ? jobStatus : JobStatus.IN_PROGRESS);
413 public void handleFailedInstantiation(UUID jobUUID) {
414 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobUUID);
415 List<ServiceInfo> serviceInfoList = asyncInstantiationRepository.getServiceInfoByTemplateIdAndJobStatus(serviceInfo.getTemplateId(), JobStatus.PENDING);
416 serviceInfoList.forEach(si -> updateServiceInfoAndAuditStatus(si.getJobId(), JobStatus.STOPPED));
420 public void deleteJob(UUID jobId) {
421 jobService.delete(jobId);
422 Date now = new Date();
423 updateServiceInfo(jobId, x -> x.setDeletedAt(now));
427 public void hideServiceInfo(UUID jobUUID) {
428 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobUUID);
429 if (!serviceInfo.getJobStatus().isFinal()) {
430 String message = String.format("jobId %s: Service status does not allow hide service, status = %s",
431 serviceInfo.getJobId(),
432 serviceInfo.getJobStatus());
433 logger.error(EELFLoggerDelegate.errorLogger, message);
434 throw new OperationNotAllowedException(message);
436 serviceInfo.setHidden(true);
437 asyncInstantiationRepository.saveServiceInfo(serviceInfo);
441 public int getCounterForName(String name) {
443 String hqlSelectNC = "from NameCounter where name = :name";
444 String hqlUpdateCounter = "update NameCounter set counter = :newCounter " +
445 "where name= :name " +
446 "and counter= :prevCounter";
448 Integer counter = null;
449 GenericUncheckedException lastException = null;
450 for (int i = 0; i< MAX_RETRIES_GETTING_COUNTER && counter==null; i++) {
452 counter = calcCounter(name, hqlSelectNC, hqlUpdateCounter);
454 catch (GenericUncheckedException exception) {
455 lastException = exception; //do nothing, we will try again in the loop
463 throw lastException!=null ? new DbFailureUncheckedException(lastException) :
464 new DbFailureUncheckedException("Failed to get counter for "+name+" due to unknown error");
468 private Integer calcCounter(String name, String hqlSelectNC, String hqlUpdateCounter) {
470 counter = DaoUtils.tryWithSessionAndTransaction(sessionFactory, session -> {
471 NameCounter nameCounter = (NameCounter) session.createQuery(hqlSelectNC)
472 .setText("name", name)
474 if (nameCounter != null) {
475 int updatedRows = session.createQuery(hqlUpdateCounter)
476 .setText("name", nameCounter.getName())
477 .setInteger("prevCounter", nameCounter.getCounter())
478 .setInteger("newCounter", nameCounter.getCounter() + 1)
480 if (updatedRows == 1) {
481 return nameCounter.getCounter() + 1;
484 Object nameAsId = session.save(new NameCounter(name));
486 if (nameAsId != null) {
490 //in case of failure return null, in order to continue the loop
497 public int getMaxRetriesGettingFreeNameFromAai() {
498 return maxRetriesGettingFreeNameFromAai;
502 public void setMaxRetriesGettingFreeNameFromAai(int maxRetriesGettingFreeNameFromAai) {
503 this.maxRetriesGettingFreeNameFromAai = maxRetriesGettingFreeNameFromAai;
507 public String getUniqueName(String name, ResourceType resourceType) {
508 //check that name aai response well before increasing counter from DB
509 //Prevents unnecessary increasing of the counter while AAI doesn't response
510 isNameFreeInAai(NAME_FOR_CHECK_AAI_STATUS, resourceType);
512 for (int i=0; i<getMaxRetriesGettingFreeNameFromAai(); i++) {
513 String newName = getUniqueNameFromDbOnly(name);
514 if (isNameFreeInAai(newName, resourceType)) {
519 throw new MaxRetriesException("can't find unused name for "+name, getMaxRetriesGettingFreeNameFromAai());
523 public ServiceInstantiation prepareServiceToBeUnique(ServiceInstantiation serviceInstantiation) {
525 ServiceInstantiation clonedServiceInstantiation = JACKSON_OBJECT_MAPPER.readValue(
526 JACKSON_OBJECT_MAPPER.writeValueAsBytes(serviceInstantiation), ServiceInstantiation.class);
527 clonedServiceInstantiation.setBulkSize(1);
528 return replaceAllTrackById(clonedServiceInstantiation);
529 } catch (IOException e) {
530 throw new GenericUncheckedException(e);
535 private<T extends BaseResource> T replaceAllTrackById(T resource) {
536 resource.setTrackById(UUID.randomUUID().toString());
537 resource.getChildren().forEach(this::replaceAllTrackById);
542 public List<UUID> retryJob(ServiceInstantiation request, UUID jobId, String userId ) {
543 updateServiceInfo(jobId, si->si.setRetryEnabled(false));
544 return pushBulkJob(request, userId);
548 public List<UUID> retryJob(UUID jobId, String userId) {
549 ServiceInstantiation serviceInstantiationRequest = asyncInstantiationRepository.getJobRequest(jobId);
550 enrichBulkForRetry(serviceInstantiationRequest, jobId);
553 logger.debug(EELFLoggerDelegate.debugLogger, "retry ServiceInstantiation request: "+
554 JACKSON_OBJECT_MAPPER.writeValueAsString(serviceInstantiationRequest));
555 } catch (Exception e) {
556 logger.error(EELFLoggerDelegate.errorLogger, "failed to log retry of ServiceInstantiation request ", e);
558 return retryJob(serviceInstantiationRequest, jobId, userId);
562 public ServiceInstantiation getBulkForRetry(UUID jobId) {
563 return enrichBulkForRetry( asyncInstantiationRepository.getJobRequest(jobId), jobId);
567 public void addResourceInfo(JobSharedData sharedData, Job.JobStatus jobStatus, String instanceId) {
568 String trackById = ((BaseResource) sharedData.getRequest()).getTrackById();
569 ResourceInfo resourceInfo = new ResourceInfo(trackById, sharedData.getRootJobId(), instanceId, jobStatus, null);
570 asyncInstantiationRepository.saveResourceInfo(resourceInfo);
574 public void addFailedResourceInfo(JobSharedData sharedData, RestObject msoResponse) {
575 String trackById = ((BaseResource) sharedData.getRequest()).getTrackById();
576 String errorMessage = MsoUtil.formatExceptionAdditionalInfo(msoResponse.getStatusCode(), msoResponse.getRaw());
577 AsyncRequestStatus asyncRequestStatus = convertMessageToAsyncRequestStatus(errorMessage);
578 ResourceInfo resourceInfo = new ResourceInfo(trackById, sharedData.getRootJobId(), null, JobStatus.FAILED, asyncRequestStatus);
580 asyncInstantiationRepository.saveResourceInfo(resourceInfo);
584 public void updateResourceInfo(JobSharedData sharedData, JobStatus jobStatus, AsyncRequestStatus message) {
585 ResourceInfo resourceInfo = asyncInstantiationRepository.getResourceInfoByTrackId(((BaseResource) sharedData.getRequest()).getTrackById());
586 resourceInfo.setJobStatus(jobStatus);
587 if (jobStatus.isFailure()) {
588 resourceInfo.setErrorMessage(message);
590 asyncInstantiationRepository.saveResourceInfo(resourceInfo);
593 public AsyncRequestStatus convertMessageToAsyncRequestStatus(String message) {
594 RequestStatus requestStatus = new RequestStatus("FAILED", message, TimeUtils.zonedDateTimeToString(ZonedDateTime.now()));
595 AsyncRequestStatus.Request request = new AsyncRequestStatus.Request(requestStatus);
596 return new AsyncRequestStatus(request);
599 protected String getUniqueNameFromDbOnly(String name) {
600 int counter = getCounterForName(name);
601 return formatNameAndCounter(name, counter);
604 //the method is protected so we can call it in the UT
605 protected String formatNameAndCounter(String name, int counter) {
606 return counter==0 ? name : name + "_" + String.format("%03d", counter);
609 private boolean isNameFreeInAai(String name, ResourceType resourceType){
610 return !aaiClient.isNodeTypeExistsByName(name, resourceType);
614 public ServiceInstantiation enrichBulkForRetry(ServiceInstantiation serviceInstantiation, UUID jobId){
615 Map<String, ResourceInfo> resourceInfoByTrackId = asyncInstantiationRepository.getResourceInfoByRootJobId(jobId);
617 return setResourceStatus(resourceInfoByTrackId, serviceInstantiation);
620 protected String readStatusMsg(ResourceInfo resourceInfo){
621 if(resourceInfo!=null && resourceInfo.getErrorMessage()!=null && resourceInfo.getErrorMessage().request != null &&resourceInfo.getErrorMessage().request.requestStatus != null ) {
622 return resourceInfo.getErrorMessage().request.requestStatus.getStatusMessage();
627 private<T extends BaseResource> T setResourceStatus(Map<String, ResourceInfo> resourceInfoByTrackId, T resource) {
628 ResourceInfo resourceInfo = resourceInfoByTrackId.get(resource.getTrackById());
629 if(resourceInfo != null) {
630 boolean failed = resourceInfo.getJobStatus().isFailure();
631 resource.setIsFailed(failed);
632 resource.setStatusMessage(readStatusMsg(resourceInfo));
634 // if(resource.getAction().equals(Action.Delete)){
635 // TODO not yet implemented- completed after delete should remove the node
636 resource.setAction(Action.None);
637 resource.setInstanceId(resourceInfo.getInstanceId());
640 resource.getChildren().forEach(child -> setResourceStatus(resourceInfoByTrackId, child));