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.function.Function.identity;
24 import static java.util.stream.Collectors.counting;
25 import static java.util.stream.Collectors.groupingBy;
26 import static java.util.stream.Stream.concat;
27 import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
28 import static org.onap.vid.controller.MsoController.SVC_INSTANCE_ID;
29 import static org.onap.vid.controller.MsoController.VNF_INSTANCE_ID;
30 import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
32 import com.google.common.collect.ImmutableMap;
33 import java.io.IOException;
34 import java.time.ZonedDateTime;
35 import java.util.ArrayList;
36 import java.util.Calendar;
37 import java.util.Date;
38 import java.util.List;
40 import java.util.Objects;
41 import java.util.UUID;
42 import java.util.function.Consumer;
43 import java.util.stream.Stream;
44 import org.apache.commons.lang3.StringUtils;
45 import org.hibernate.SessionFactory;
46 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
47 import org.onap.vid.aai.AaiClientInterface;
48 import org.onap.vid.aai.model.ResourceType;
49 import org.onap.vid.dal.AsyncInstantiationRepository;
50 import org.onap.vid.exceptions.DbFailureUncheckedException;
51 import org.onap.vid.exceptions.GenericUncheckedException;
52 import org.onap.vid.exceptions.MaxRetriesException;
53 import org.onap.vid.exceptions.OperationNotAllowedException;
54 import org.onap.vid.job.Job;
55 import org.onap.vid.job.Job.JobStatus;
56 import org.onap.vid.job.JobAdapter;
57 import org.onap.vid.job.JobType;
58 import org.onap.vid.job.JobsBrokerService;
59 import org.onap.vid.job.impl.JobSharedData;
60 import org.onap.vid.model.Action;
61 import org.onap.vid.model.NameCounter;
62 import org.onap.vid.model.ResourceInfo;
63 import org.onap.vid.model.ServiceInfo;
64 import org.onap.vid.model.serviceInstantiation.BaseResource;
65 import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
66 import org.onap.vid.mso.MsoBusinessLogicImpl;
67 import org.onap.vid.mso.MsoProperties;
68 import org.onap.vid.mso.MsoUtil;
69 import org.onap.vid.mso.RestObject;
70 import org.onap.vid.mso.model.ModelInfo;
71 import org.onap.vid.mso.rest.AsyncRequestStatus;
72 import org.onap.vid.mso.rest.RequestStatus;
73 import org.onap.vid.properties.Features;
74 import org.onap.vid.utils.DaoUtils;
75 import org.onap.vid.utils.TimeUtils;
76 import org.springframework.beans.factory.annotation.Autowired;
77 import org.springframework.stereotype.Service;
78 import org.togglz.core.manager.FeatureManager;
81 public class AsyncInstantiationBusinessLogicImpl implements
82 AsyncInstantiationBusinessLogic {
84 private static final int MAX_RETRIES_GETTING_COUNTER = 100;
85 private static final int MAX_RETRIES_GETTING_FREE_NAME_FROM_AAI = 10000;
86 public static final String NAME_FOR_CHECK_AAI_STATUS = "NAME_FOR_CHECK_AAI_STATUS";
88 private final JobAdapter jobAdapter;
90 private final JobsBrokerService jobService;
92 private final CloudOwnerService cloudOwnerService;
94 private final AsyncInstantiationRepository asyncInstantiationRepository;
96 private SessionFactory sessionFactory;
98 private AaiClientInterface aaiClient;
100 private FeatureManager featureManager;
102 private AuditService auditService;
105 private int maxRetriesGettingFreeNameFromAai = MAX_RETRIES_GETTING_FREE_NAME_FROM_AAI;
107 private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AsyncInstantiationBusinessLogicImpl.class);
108 private Map<String, JobStatus> msoStateToJobStatusMap = ImmutableMap.<String, JobStatus>builder()
109 .put("inprogress", JobStatus.IN_PROGRESS)
110 .put("failed", JobStatus.FAILED)
111 .put("pause", JobStatus.PAUSE)
112 .put("paused", JobStatus.PAUSE)
113 .put("complete", JobStatus.COMPLETED)
114 .put("pending", JobStatus.IN_PROGRESS)
115 .put("pendingmanualtask", JobStatus.PAUSE)
116 .put("unlocked", JobStatus.IN_PROGRESS)
117 .put("aborted", JobStatus.COMPLETED_WITH_ERRORS)
118 .put("rolledback", JobStatus.FAILED)
119 .put("rolledbacktoassigned", JobStatus.FAILED)
120 .put("rolledbacktocreated", JobStatus.FAILED)
125 public AsyncInstantiationBusinessLogicImpl(JobAdapter jobAdapter,
126 JobsBrokerService jobService,
127 SessionFactory sessionFactory,
128 AaiClientInterface aaiClient,
129 FeatureManager featureManager,
130 CloudOwnerService cloudOwnerService, AsyncInstantiationRepository asyncInstantiationRepository,
131 AuditService auditService) {
132 this.jobAdapter = jobAdapter;
133 this.jobService = jobService;
134 this.sessionFactory = sessionFactory;
135 this.aaiClient = aaiClient;
136 this.featureManager = featureManager;
137 this.cloudOwnerService = cloudOwnerService;
138 this.asyncInstantiationRepository = asyncInstantiationRepository;
139 this.auditService = auditService;
143 public List<ServiceInfo> getAllServicesInfo() {
144 return asyncInstantiationRepository.getAllServicesInfo();
147 JobType getJobType(ServiceInstantiation request) {
148 if (request.isALaCarte()) {
149 switch (defaultIfNull(request.getAction(), Action.Create)) {
151 return JobType.ALaCarteService;
153 return JobType.ALaCarteService;
155 return JobType.ALaCarteServiceInstantiation;
158 return JobType.MacroServiceInstantiation;
163 public List<UUID> pushBulkJob(ServiceInstantiation request, String userId) {
165 List<UUID> uuids = new ArrayList<>();
166 Date createdBulkDate = Calendar.getInstance().getTime();
167 int bulkSize = request.getBulkSize();
168 UUID templateId = UUID.randomUUID();
169 for (int i = 0; i < bulkSize; i++) {
170 ServiceInstantiation requestPerJob = prepareServiceToBeUnique(request);
171 ServiceInfo.ServiceAction serviceAction = getAction(requestPerJob);
172 JobType jobType = getJobType(requestPerJob);
173 final String optimisticUniqueServiceInstanceName = bulkSize>1 ? //only bulk with more than 1 service need to get multiple names
174 getOptimisticUniqueServiceInstanceName(requestPerJob.getInstanceName()) : requestPerJob.getInstanceName();
175 Job job = jobAdapter.createServiceInstantiationJob(jobType, requestPerJob, templateId, userId, request.getTestApi(), optimisticUniqueServiceInstanceName, i);
176 UUID jobId = job.getUuid();
178 asyncInstantiationRepository.saveServiceInfo(createServiceInfo(userId, requestPerJob, jobId, templateId, createdBulkDate, optimisticUniqueServiceInstanceName, serviceAction));
179 asyncInstantiationRepository.addJobRequest(jobId, requestPerJob);
180 auditService.auditVidStatus(jobId, job.getStatus());
188 public Map<String, Long> getSummarizedChildrenMap(ServiceInstantiation serviceInstantiation){
189 Stream<String> existingTypesStream =
190 allDeepChildResources(serviceInstantiation)
191 .map(BaseResource::getModelInfo)
192 .filter(Objects::nonNull)
193 .map(ModelInfo::getModelType);
195 Map<String, Long> existingTypesCounters =
196 existingTypesStream.collect(groupingBy(identity(), counting()));
198 return existingTypesCounters;
201 private Stream<BaseResource> allDeepChildResources(BaseResource resource) {
205 .map(it -> concat(Stream.of(it), allDeepChildResources(it)))
206 .flatMap(identity());
209 private ServiceInfo.ServiceAction getAction(ServiceInstantiation request) {
210 if (request.getAction() == null) {
211 //throw new GenericUncheckedException("Required 'action' field not provided at service level");
212 return Action.Create.getServiceAction();
214 return request.getAction().getServiceAction();
218 private String getOptimisticUniqueServiceInstanceName(String instanceName) {
219 return StringUtils.isNotEmpty(instanceName) ? getUniqueNameFromDbOnly(instanceName) : instanceName;
222 protected ServiceInfo createServiceInfo(String userId, ServiceInstantiation serviceInstantiation, UUID jobId, UUID templateId, Date createdBulkDate, String optimisticUniqueServiceInstanceName, ServiceInfo.ServiceAction serviceAction) {
223 return new ServiceInfo(
225 serviceInstantiation.isALaCarte(),
226 Job.JobStatus.PENDING, serviceInstantiation.isPause(), jobId, templateId,
227 serviceInstantiation.getOwningEntityId(),
228 serviceInstantiation.getOwningEntityName(),
229 serviceInstantiation.getProjectName(),
230 serviceInstantiation.getAicZoneId(),
231 serviceInstantiation.getAicZoneName(),
232 serviceInstantiation.getTenantId(),
233 serviceInstantiation.getTenantName(),
234 serviceInstantiation.getLcpCloudRegionId(),
236 serviceInstantiation.getSubscriptionServiceType(),
237 serviceInstantiation.getSubscriberName(),
238 serviceInstantiation.getGlobalSubscriberId(),
239 serviceInstantiation.getInstanceId(),
240 optimisticUniqueServiceInstanceName,
241 serviceInstantiation.getModelInfo().getModelVersionId(),
242 serviceInstantiation.getModelInfo().getModelName(),
243 serviceInstantiation.getModelInfo().getModelVersion(),
250 public boolean isPartOfBulk(UUID jobId) {
254 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobId);
255 UUID templateId = serviceInfo.getTemplateId();
256 if (templateId != null) {
257 return getNumberOfJobsInBulk(templateId) > 1;
263 private int getNumberOfJobsInBulk(UUID templateId) {
264 String hqlSelectJob = "from JobDaoImpl where templateId = :templateId";
265 return DaoUtils.tryWithSessionAndTransaction(sessionFactory, session ->
266 session.createQuery(hqlSelectJob)
267 .setText("templateId", templateId.toString())
274 public String getServiceInstantiationPath(ServiceInstantiation serviceInstantiationRequest) {
275 //in case pause flag is true - use assign , else - use create.
276 return MsoBusinessLogicImpl.validateEndpointPath(
277 serviceInstantiationRequest.isPause() ?
278 MsoProperties.MSO_REST_API_SERVICE_INSTANCE_ASSIGN : MsoProperties.MSO_RESTAPI_SERVICE_INSTANCE
283 public String getServiceDeletionPath(String serviceInstanceId) {
284 return MsoBusinessLogicImpl.validateEndpointPath( MsoProperties.MSO_RESTAPI_SERVICE_INSTANCE) + "/" + serviceInstanceId;
288 public String getVnfInstantiationPath(String serviceInstanceId) {
289 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE).
290 replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
294 public String getVnfDeletionPath(String serviceInstanceId, String vnfInstanceId) {
295 return (MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE)
296 + '/' + vnfInstanceId)
297 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId).replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
301 public String getNetworkInstantiationPath(String serviceInstanceId) {
302 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_NETWORK_INSTANCE).
303 replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
307 public String getVfmoduleInstantiationPath(String serviceInstanceId, String vnfInstanceId) {
308 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE)
309 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
310 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
314 public String getVfModuleReplacePath(String serviceInstanceId, String vnfInstanceId, String vfModuleInstanceId)
316 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE)
317 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
318 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId)
319 + "/" + vfModuleInstanceId
324 public String getVfModuleDeletePath(String serviceInstanceId, String vnfInstanceId, String vfModuleInstanceId) {
325 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE)
326 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
327 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId)
328 + "/" + vfModuleInstanceId;
332 public String getVolumeGroupInstantiationPath(String serviceInstanceId, String vnfInstanceId) {
333 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VOLUME_GROUP_INSTANCE)
334 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
335 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
339 public String getInstanceGroupInstantiationPath() {
340 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP);
344 public String getInstanceGroupMemberInstantiationPath(String vnfGroupInstanceId) {
345 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP)
346 + '/' + vnfGroupInstanceId + "/addMembers";
350 public String getInstanceGroupDeletePath(String instanceGroupId) {
351 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP)
352 + '/' + instanceGroupId;
356 public String getInstanceGroupMemberDeletePath(String vnfGroupInstanceId){
357 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP)
358 + '/' + vnfGroupInstanceId + "/removeMembers";
362 public String getNetworkDeletePath(String serviceInstanceId, String networkInstanceId) {
363 return (MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_NETWORK_INSTANCE)
364 + "/" + networkInstanceId)
365 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
369 public String getResumeRequestPath(String requestId) {
370 return MsoBusinessLogicImpl.validateEndpointPath("mso.restapi.resume.orc.req")
371 .replaceFirst("<request_id>", requestId);
375 public String getOrchestrationRequestsPath() {
376 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_GET_ORC_REQ);
380 public ServiceInfo updateServiceInfo(UUID jobUUID, Consumer<ServiceInfo> serviceUpdater) {
381 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobUUID);
382 serviceUpdater.accept(serviceInfo);
383 asyncInstantiationRepository.saveServiceInfo(serviceInfo);
388 public ServiceInfo updateServiceInfoAndAuditStatus(UUID jobUuid, JobStatus jobStatus) {
389 auditService.auditVidStatus(jobUuid, jobStatus);
390 return updateServiceInfo(jobUuid, x -> setServiceInfoStatus(x, jobStatus));
393 private boolean isRetryEnabledForStatus(JobStatus jobStatus) {
394 return featureManager.isActive(Features.FLAG_1902_RETRY_JOB) &&
395 (jobStatus==JobStatus.COMPLETED_WITH_ERRORS || jobStatus==JobStatus.FAILED);
398 private void setServiceInfoStatus(ServiceInfo serviceInfo, JobStatus jobStatus) {
399 serviceInfo.setJobStatus(jobStatus);
400 serviceInfo.setStatusModifiedDate(new Date());
401 serviceInfo.setRetryEnabled(isRetryEnabledForStatus(jobStatus));
404 public Job.JobStatus calcStatus(AsyncRequestStatus asyncRequestStatus) {
405 String msoRequestState = asyncRequestStatus.request.requestStatus.getRequestState().toLowerCase().replaceAll("[^a-z]+", "");
406 JobStatus jobStatus = msoStateToJobStatusMap.get(msoRequestState);
407 return (jobStatus != null ? jobStatus : JobStatus.IN_PROGRESS);
411 public void handleFailedInstantiation(UUID jobUUID) {
412 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobUUID);
413 List<ServiceInfo> serviceInfoList = asyncInstantiationRepository.getServiceInfoByTemplateIdAndJobStatus(serviceInfo.getTemplateId(), JobStatus.PENDING);
414 serviceInfoList.forEach(si -> updateServiceInfoAndAuditStatus(si.getJobId(), JobStatus.STOPPED));
418 public void deleteJob(UUID jobId) {
419 jobService.delete(jobId);
420 Date now = new Date();
421 updateServiceInfo(jobId, x -> x.setDeletedAt(now));
425 public void hideServiceInfo(UUID jobUUID) {
426 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobUUID);
427 if (!serviceInfo.getJobStatus().isFinal()) {
428 String message = String.format("jobId %s: Service status does not allow hide service, status = %s",
429 serviceInfo.getJobId(),
430 serviceInfo.getJobStatus());
431 logger.error(EELFLoggerDelegate.errorLogger, message);
432 throw new OperationNotAllowedException(message);
434 serviceInfo.setHidden(true);
435 asyncInstantiationRepository.saveServiceInfo(serviceInfo);
439 public int getCounterForName(String name) {
441 String hqlSelectNC = "from NameCounter where name = :name";
442 String hqlUpdateCounter = "update NameCounter set counter = :newCounter " +
443 "where name= :name " +
444 "and counter= :prevCounter";
446 Integer counter = null;
447 GenericUncheckedException lastException = null;
448 for (int i = 0; i< MAX_RETRIES_GETTING_COUNTER && counter==null; i++) {
450 counter = calcCounter(name, hqlSelectNC, hqlUpdateCounter);
452 catch (GenericUncheckedException exception) {
453 lastException = exception; //do nothing, we will try again in the loop
461 throw lastException!=null ? new DbFailureUncheckedException(lastException) :
462 new DbFailureUncheckedException("Failed to get counter for "+name+" due to unknown error");
466 private Integer calcCounter(String name, String hqlSelectNC, String hqlUpdateCounter) {
468 counter = DaoUtils.tryWithSessionAndTransaction(sessionFactory, session -> {
469 NameCounter nameCounter = (NameCounter) session.createQuery(hqlSelectNC)
470 .setText("name", name)
472 if (nameCounter != null) {
473 int updatedRows = session.createQuery(hqlUpdateCounter)
474 .setText("name", nameCounter.getName())
475 .setInteger("prevCounter", nameCounter.getCounter())
476 .setInteger("newCounter", nameCounter.getCounter() + 1)
478 if (updatedRows == 1) {
479 return nameCounter.getCounter() + 1;
482 Object nameAsId = session.save(new NameCounter(name));
484 if (nameAsId != null) {
488 //in case of failure return null, in order to continue the loop
495 public int getMaxRetriesGettingFreeNameFromAai() {
496 return maxRetriesGettingFreeNameFromAai;
500 public void setMaxRetriesGettingFreeNameFromAai(int maxRetriesGettingFreeNameFromAai) {
501 this.maxRetriesGettingFreeNameFromAai = maxRetriesGettingFreeNameFromAai;
505 public String getUniqueName(String name, ResourceType resourceType) {
506 //check that name aai response well before increasing counter from DB
507 //Prevents unnecessary increasing of the counter while AAI doesn't response
508 isNameFreeInAai(NAME_FOR_CHECK_AAI_STATUS, resourceType);
510 for (int i=0; i<getMaxRetriesGettingFreeNameFromAai(); i++) {
511 String newName = getUniqueNameFromDbOnly(name);
512 if (isNameFreeInAai(newName, resourceType)) {
517 throw new MaxRetriesException("can't find unused name for "+name, getMaxRetriesGettingFreeNameFromAai());
521 public ServiceInstantiation prepareServiceToBeUnique(ServiceInstantiation serviceInstantiation) {
523 ServiceInstantiation clonedServiceInstantiation = JACKSON_OBJECT_MAPPER.readValue(
524 JACKSON_OBJECT_MAPPER.writeValueAsBytes(serviceInstantiation), ServiceInstantiation.class);
525 clonedServiceInstantiation.setBulkSize(1);
526 return replaceAllTrackById(clonedServiceInstantiation);
527 } catch (IOException e) {
528 throw new GenericUncheckedException(e);
533 private<T extends BaseResource> T replaceAllTrackById(T resource) {
534 resource.setTrackById(UUID.randomUUID().toString());
535 resource.getChildren().forEach(this::replaceAllTrackById);
540 public List<UUID> retryJob(ServiceInstantiation request, UUID jobId, String userId ) {
541 updateServiceInfo(jobId, si->si.setRetryEnabled(false));
542 return pushBulkJob(request, userId);
546 public List<UUID> retryJob(UUID jobId, String userId) {
547 ServiceInstantiation serviceInstantiationRequest = asyncInstantiationRepository.getJobRequest(jobId);
548 enrichBulkForRetry(serviceInstantiationRequest, jobId);
551 logger.debug(EELFLoggerDelegate.debugLogger, "retry ServiceInstantiation request: "+
552 JACKSON_OBJECT_MAPPER.writeValueAsString(serviceInstantiationRequest));
553 } catch (Exception e) {
554 logger.error(EELFLoggerDelegate.errorLogger, "failed to log retry of ServiceInstantiation request ", e);
556 return retryJob(serviceInstantiationRequest, jobId, userId);
560 public ServiceInstantiation getBulkForRetry(UUID jobId) {
561 return enrichBulkForRetry( asyncInstantiationRepository.getJobRequest(jobId), jobId);
565 public void addResourceInfo(JobSharedData sharedData, Job.JobStatus jobStatus, String instanceId) {
566 String trackById = ((BaseResource) sharedData.getRequest()).getTrackById();
567 ResourceInfo resourceInfo = new ResourceInfo(trackById, sharedData.getRootJobId(), instanceId, jobStatus, null);
568 asyncInstantiationRepository.saveResourceInfo(resourceInfo);
572 public void addFailedResourceInfo(JobSharedData sharedData, RestObject msoResponse) {
573 String trackById = ((BaseResource) sharedData.getRequest()).getTrackById();
574 String errorMessage = MsoUtil.formatExceptionAdditionalInfo(msoResponse.getStatusCode(), msoResponse.getRaw());
575 AsyncRequestStatus asyncRequestStatus = convertMessageToAsyncRequestStatus(errorMessage);
576 ResourceInfo resourceInfo = new ResourceInfo(trackById, sharedData.getRootJobId(), null, JobStatus.FAILED, asyncRequestStatus);
578 asyncInstantiationRepository.saveResourceInfo(resourceInfo);
582 public void updateResourceInfo(JobSharedData sharedData, JobStatus jobStatus, AsyncRequestStatus message) {
583 ResourceInfo resourceInfo = asyncInstantiationRepository.getResourceInfoByTrackId(((BaseResource) sharedData.getRequest()).getTrackById());
584 resourceInfo.setJobStatus(jobStatus);
585 if (jobStatus.isFailure()) {
586 resourceInfo.setErrorMessage(message);
588 asyncInstantiationRepository.saveResourceInfo(resourceInfo);
591 public AsyncRequestStatus convertMessageToAsyncRequestStatus(String message) {
592 RequestStatus requestStatus = new RequestStatus("FAILED", message, TimeUtils.zonedDateTimeToString(ZonedDateTime.now()));
593 AsyncRequestStatus.Request request = new AsyncRequestStatus.Request(requestStatus);
594 return new AsyncRequestStatus(request);
597 protected String getUniqueNameFromDbOnly(String name) {
598 int counter = getCounterForName(name);
599 return formatNameAndCounter(name, counter);
602 //the method is protected so we can call it in the UT
603 protected String formatNameAndCounter(String name, int counter) {
604 return counter==0 ? name : name + "_" + String.format("%03d", counter);
607 private boolean isNameFreeInAai(String name, ResourceType resourceType){
608 return !aaiClient.isNodeTypeExistsByName(name, resourceType);
612 public ServiceInstantiation enrichBulkForRetry(ServiceInstantiation serviceInstantiation, UUID jobId){
613 Map<String, ResourceInfo> resourceInfoByTrackId = asyncInstantiationRepository.getResourceInfoByRootJobId(jobId);
615 return setResourceStatus(resourceInfoByTrackId, serviceInstantiation);
618 protected String readStatusMsg(ResourceInfo resourceInfo){
619 if(resourceInfo!=null && resourceInfo.getErrorMessage()!=null && resourceInfo.getErrorMessage().request != null &&resourceInfo.getErrorMessage().request.requestStatus != null ) {
620 return resourceInfo.getErrorMessage().request.requestStatus.getStatusMessage();
625 private<T extends BaseResource> T setResourceStatus(Map<String, ResourceInfo> resourceInfoByTrackId, T resource) {
626 ResourceInfo resourceInfo = resourceInfoByTrackId.get(resource.getTrackById());
627 if(resourceInfo != null) {
628 boolean failed = resourceInfo.getJobStatus().isFailure();
629 resource.setIsFailed(failed);
630 resource.setStatusMessage(readStatusMsg(resourceInfo));
632 // if(resource.getAction().equals(Action.Delete)){
633 // TODO not yet implemented- completed after delete should remove the node
634 resource.setAction(Action.None);
635 resource.setInstanceId(resourceInfo.getInstanceId());
638 resource.getChildren().forEach(child -> setResourceStatus(resourceInfoByTrackId, child));