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 com.google.common.collect.Streams.concat;
24 import static java.util.function.Function.identity;
25 import static java.util.stream.Collectors.counting;
26 import static java.util.stream.Collectors.groupingBy;
27 import static java.util.stream.Stream.empty;
28 import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
29 import static org.apache.commons.lang3.StringUtils.isNotEmpty;
30 import static org.onap.vid.controller.MsoController.SVC_INSTANCE_ID;
31 import static org.onap.vid.controller.MsoController.VNF_INSTANCE_ID;
32 import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
34 import com.google.common.collect.ImmutableMap;
35 import java.io.IOException;
36 import java.time.ZonedDateTime;
37 import java.util.ArrayList;
38 import java.util.Calendar;
39 import java.util.Date;
40 import java.util.List;
42 import java.util.Objects;
43 import java.util.UUID;
44 import java.util.function.Consumer;
45 import java.util.stream.Stream;
46 import org.hibernate.SessionFactory;
47 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
48 import org.onap.vid.aai.AaiClientInterface;
49 import org.onap.vid.aai.model.ResourceType;
50 import org.onap.vid.dal.AsyncInstantiationRepository;
51 import org.onap.vid.exceptions.DbFailureUncheckedException;
52 import org.onap.vid.exceptions.GenericUncheckedException;
53 import org.onap.vid.exceptions.MaxRetriesException;
54 import org.onap.vid.exceptions.OperationNotAllowedException;
55 import org.onap.vid.job.Job;
56 import org.onap.vid.job.Job.JobStatus;
57 import org.onap.vid.job.JobAdapter;
58 import org.onap.vid.job.JobType;
59 import org.onap.vid.job.JobsBrokerService;
60 import org.onap.vid.job.impl.JobSharedData;
61 import org.onap.vid.model.Action;
62 import org.onap.vid.model.NameCounter;
63 import org.onap.vid.model.ResourceInfo;
64 import org.onap.vid.model.ServiceInfo;
65 import org.onap.vid.model.ServiceInfo.ServiceAction;
66 import org.onap.vid.model.serviceInstantiation.BaseResource;
67 import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
68 import org.onap.vid.model.serviceInstantiation.VfModule;
69 import org.onap.vid.mso.MsoBusinessLogicImpl;
70 import org.onap.vid.mso.MsoProperties;
71 import org.onap.vid.mso.MsoUtil;
72 import org.onap.vid.mso.RestObject;
73 import org.onap.vid.mso.model.ModelInfo;
74 import org.onap.vid.mso.rest.AsyncRequestStatus;
75 import org.onap.vid.mso.rest.RequestStatus;
76 import org.onap.vid.properties.Features;
77 import org.onap.vid.utils.DaoUtils;
78 import org.onap.vid.utils.TimeUtils;
79 import org.springframework.beans.factory.annotation.Autowired;
80 import org.springframework.stereotype.Service;
81 import org.togglz.core.manager.FeatureManager;
84 public class AsyncInstantiationBusinessLogicImpl implements
85 AsyncInstantiationBusinessLogic {
87 private static final int MAX_RETRIES_GETTING_COUNTER = 100;
88 private static final int MAX_RETRIES_GETTING_FREE_NAME_FROM_AAI = 10000;
89 public static final String NAME_FOR_CHECK_AAI_STATUS = "NAME_FOR_CHECK_AAI_STATUS";
91 private final JobAdapter jobAdapter;
93 private final JobsBrokerService jobService;
95 private final CloudOwnerService cloudOwnerService;
97 private final AsyncInstantiationRepository asyncInstantiationRepository;
99 private SessionFactory sessionFactory;
101 private AaiClientInterface aaiClient;
103 private FeatureManager featureManager;
105 private AuditService auditService;
108 private int maxRetriesGettingFreeNameFromAai = MAX_RETRIES_GETTING_FREE_NAME_FROM_AAI;
110 private static final EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AsyncInstantiationBusinessLogicImpl.class);
111 private Map<String, JobStatus> msoStateToJobStatusMap = ImmutableMap.<String, JobStatus>builder()
112 .put("inprogress", JobStatus.IN_PROGRESS)
113 .put("failed", JobStatus.FAILED)
114 .put("pause", JobStatus.PAUSE)
115 .put("paused", JobStatus.PAUSE)
116 .put("complete", JobStatus.COMPLETED)
117 .put("pending", JobStatus.IN_PROGRESS)
118 .put("pendingmanualtask", JobStatus.PAUSE)
119 .put("unlocked", JobStatus.IN_PROGRESS)
120 .put("aborted", JobStatus.COMPLETED_WITH_ERRORS)
121 .put("rolledback", JobStatus.FAILED)
122 .put("rolledbacktoassigned", JobStatus.FAILED)
123 .put("rolledbacktocreated", JobStatus.FAILED)
128 public AsyncInstantiationBusinessLogicImpl(JobAdapter jobAdapter,
129 JobsBrokerService jobService,
130 SessionFactory sessionFactory,
131 AaiClientInterface aaiClient,
132 FeatureManager featureManager,
133 CloudOwnerService cloudOwnerService, AsyncInstantiationRepository asyncInstantiationRepository,
134 AuditService auditService) {
135 this.jobAdapter = jobAdapter;
136 this.jobService = jobService;
137 this.sessionFactory = sessionFactory;
138 this.aaiClient = aaiClient;
139 this.featureManager = featureManager;
140 this.cloudOwnerService = cloudOwnerService;
141 this.asyncInstantiationRepository = asyncInstantiationRepository;
142 this.auditService = auditService;
146 public List<ServiceInfo> getAllServicesInfo() {
147 return asyncInstantiationRepository.getAllServicesInfo();
150 JobType getJobType(ServiceInstantiation request) {
151 if (request.isALaCarte()) {
152 switch (defaultIfNull(request.getAction(), Action.Create)) {
154 return JobType.ALaCarteService;
156 return JobType.ALaCarteService;
158 return JobType.ALaCarteServiceInstantiation;
161 return JobType.MacroServiceInstantiation;
166 public List<UUID> pushBulkJob(ServiceInstantiation request, String userId) {
168 List<UUID> uuids = new ArrayList<>();
169 Date createdBulkDate = Calendar.getInstance().getTime();
170 int bulkSize = request.getBulkSize();
171 UUID templateId = UUID.randomUUID();
172 for (int i = 0; i < bulkSize; i++) {
173 ServiceInstantiation requestPerJob = prepareServiceToBeUnique(request);
174 ServiceInfo.ServiceAction serviceAction = getAction(requestPerJob);
175 JobType jobType = getJobType(requestPerJob);
176 final String optimisticUniqueServiceInstanceName = bulkSize>1 ? //only bulk with more than 1 service need to get multiple names
177 getOptimisticUniqueServiceInstanceName(requestPerJob.getInstanceName()) : requestPerJob.getInstanceName();
178 Job job = jobAdapter.createServiceInstantiationJob(jobType, requestPerJob, templateId, userId, request.getTestApi(), optimisticUniqueServiceInstanceName, i);
179 UUID jobId = job.getUuid();
181 asyncInstantiationRepository.saveServiceInfo(createServiceInfo(
182 userId, requestPerJob, jobId, templateId, createdBulkDate,
183 optimisticUniqueServiceInstanceName, serviceAction,
184 requestSummaryOrNull(requestPerJob)));
185 asyncInstantiationRepository.addJobRequest(jobId, requestPerJob);
186 auditService.auditVidStatus(jobId, job.getStatus());
194 Map<String, Long> requestSummaryOrNull(ServiceInstantiation request) {
195 if (!featureManager.isActive(Features.FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE)) {
199 if (getAction(request) != ServiceAction.INSTANTIATE) {
203 return summarizedChildrenMap(request);
206 public Map<String, Long> summarizedChildrenMap(ServiceInstantiation serviceInstantiation){
207 Stream<String> existingTypesStream =
208 allDeepChildResources(serviceInstantiation)
209 .map(this::getModelTypes)
210 .flatMap(identity());
212 Map<String, Long> existingTypesCounters =
213 existingTypesStream.collect(groupingBy(identity(), counting()));
215 return existingTypesCounters;
218 private Stream<String> getModelTypes(BaseResource resource) {
221 .map(BaseResource::getModelInfo)
222 .filter(Objects::nonNull)
223 .map(ModelInfo::getModelType),
224 streamVolumeGroups(resource)
228 private Stream<String> streamVolumeGroups(BaseResource resource) {
229 return hasVolumeGroup(resource)
230 ? Stream.of("volumeGroup")
234 private boolean hasVolumeGroup(BaseResource resource) {
236 resource instanceof VfModule
237 && isNotEmpty(((VfModule) resource).getVolumeGroupInstanceName());
240 private Stream<BaseResource> allDeepChildResources(BaseResource resource) {
244 .map(it -> concat(Stream.of(it), allDeepChildResources(it)))
245 .flatMap(identity());
248 private ServiceInfo.ServiceAction getAction(ServiceInstantiation request) {
249 if (request.getAction() == null) {
250 //throw new GenericUncheckedException("Required 'action' field not provided at service level");
251 return Action.Create.getServiceAction();
253 return request.getAction().getServiceAction();
257 private String getOptimisticUniqueServiceInstanceName(String instanceName) {
258 return isNotEmpty(instanceName) ? getUniqueNameFromDbOnly(instanceName) : instanceName;
261 protected ServiceInfo createServiceInfo(String userId, ServiceInstantiation serviceInstantiation, UUID jobId,
262 UUID templateId, Date createdBulkDate, String optimisticUniqueServiceInstanceName,
263 ServiceInfo.ServiceAction serviceAction, Map<String, Long> requestSummary) {
264 return new ServiceInfo(
266 serviceInstantiation.isALaCarte(),
267 Job.JobStatus.PENDING, serviceInstantiation.isPause(), jobId, templateId,
268 serviceInstantiation.getOwningEntityId(),
269 serviceInstantiation.getOwningEntityName(),
270 serviceInstantiation.getProjectName(),
271 serviceInstantiation.getAicZoneId(),
272 serviceInstantiation.getAicZoneName(),
273 serviceInstantiation.getTenantId(),
274 serviceInstantiation.getTenantName(),
275 serviceInstantiation.getLcpCloudRegionId(),
277 serviceInstantiation.getSubscriptionServiceType(),
278 serviceInstantiation.getSubscriberName(),
279 serviceInstantiation.getGlobalSubscriberId(),
280 serviceInstantiation.getInstanceId(),
281 optimisticUniqueServiceInstanceName,
282 serviceInstantiation.getModelInfo().getModelVersionId(),
283 serviceInstantiation.getModelInfo().getModelName(),
284 serviceInstantiation.getModelInfo().getModelVersion(),
292 public boolean isPartOfBulk(UUID jobId) {
296 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobId);
297 UUID templateId = serviceInfo.getTemplateId();
298 if (templateId != null) {
299 return getNumberOfJobsInBulk(templateId) > 1;
305 private int getNumberOfJobsInBulk(UUID templateId) {
306 String hqlSelectJob = "from JobDaoImpl where templateId = :templateId";
307 return DaoUtils.tryWithSessionAndTransaction(sessionFactory, session ->
308 session.createQuery(hqlSelectJob)
309 .setText("templateId", templateId.toString())
316 public String getServiceInstantiationPath(ServiceInstantiation serviceInstantiationRequest) {
317 //in case pause flag is true - use assign , else - use create.
318 return MsoBusinessLogicImpl.validateEndpointPath(
319 serviceInstantiationRequest.isPause() ?
320 MsoProperties.MSO_REST_API_SERVICE_INSTANCE_ASSIGN : MsoProperties.MSO_RESTAPI_SERVICE_INSTANCE
325 public String getServiceDeletionPath(String serviceInstanceId) {
326 return MsoBusinessLogicImpl.validateEndpointPath( MsoProperties.MSO_RESTAPI_SERVICE_INSTANCE) + "/" + serviceInstanceId;
330 public String getVnfInstantiationPath(String serviceInstanceId) {
331 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE).
332 replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
336 public String getVnfDeletionPath(String serviceInstanceId, String vnfInstanceId) {
337 return (MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE)
338 + '/' + vnfInstanceId)
339 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId).replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
343 public String getNetworkInstantiationPath(String serviceInstanceId) {
344 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_NETWORK_INSTANCE).
345 replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
349 public String getVfmoduleInstantiationPath(String serviceInstanceId, String vnfInstanceId) {
350 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE)
351 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
352 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
356 public String getVfModuleReplacePath(String serviceInstanceId, String vnfInstanceId, String vfModuleInstanceId)
358 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE)
359 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
360 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId)
361 + "/" + vfModuleInstanceId
366 public String getVfModuleDeletePath(String serviceInstanceId, String vnfInstanceId, String vfModuleInstanceId) {
367 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE)
368 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
369 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId)
370 + "/" + vfModuleInstanceId;
374 public String getVolumeGroupInstantiationPath(String serviceInstanceId, String vnfInstanceId) {
375 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VOLUME_GROUP_INSTANCE)
376 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
377 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
381 public String getInstanceGroupInstantiationPath() {
382 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP);
386 public String getInstanceGroupMemberInstantiationPath(String vnfGroupInstanceId) {
387 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP)
388 + '/' + vnfGroupInstanceId + "/addMembers";
392 public String getInstanceGroupDeletePath(String instanceGroupId) {
393 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP)
394 + '/' + instanceGroupId;
398 public String getInstanceGroupMemberDeletePath(String vnfGroupInstanceId){
399 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP)
400 + '/' + vnfGroupInstanceId + "/removeMembers";
404 public String getNetworkDeletePath(String serviceInstanceId, String networkInstanceId) {
405 return (MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_NETWORK_INSTANCE)
406 + "/" + networkInstanceId)
407 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
411 public String getResumeRequestPath(String requestId) {
412 return MsoBusinessLogicImpl.validateEndpointPath("mso.restapi.resume.orc.req")
413 .replaceFirst("<request_id>", requestId);
417 public String getOrchestrationRequestsPath() {
418 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_GET_ORC_REQ);
422 public ServiceInfo updateServiceInfo(UUID jobUUID, Consumer<ServiceInfo> serviceUpdater) {
423 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobUUID);
424 serviceUpdater.accept(serviceInfo);
425 asyncInstantiationRepository.saveServiceInfo(serviceInfo);
430 public ServiceInfo updateServiceInfoAndAuditStatus(UUID jobUuid, JobStatus jobStatus) {
431 auditService.auditVidStatus(jobUuid, jobStatus);
432 return updateServiceInfo(jobUuid, x -> setServiceInfoStatus(x, jobStatus));
435 private boolean isRetryEnabledForStatus(JobStatus jobStatus) {
436 return featureManager.isActive(Features.FLAG_1902_RETRY_JOB) &&
437 (jobStatus==JobStatus.COMPLETED_WITH_ERRORS || jobStatus==JobStatus.FAILED);
440 private void setServiceInfoStatus(ServiceInfo serviceInfo, JobStatus jobStatus) {
441 serviceInfo.setJobStatus(jobStatus);
442 serviceInfo.setStatusModifiedDate(new Date());
443 serviceInfo.setRetryEnabled(isRetryEnabledForStatus(jobStatus));
446 public Job.JobStatus calcStatus(AsyncRequestStatus asyncRequestStatus) {
447 String msoRequestState = asyncRequestStatus.request.requestStatus.getRequestState().toLowerCase().replaceAll("[^a-z]+", "");
448 JobStatus jobStatus = msoStateToJobStatusMap.get(msoRequestState);
449 return (jobStatus != null ? jobStatus : JobStatus.IN_PROGRESS);
453 public void handleFailedInstantiation(UUID jobUUID) {
454 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobUUID);
455 List<ServiceInfo> serviceInfoList = asyncInstantiationRepository.getServiceInfoByTemplateIdAndJobStatus(serviceInfo.getTemplateId(), JobStatus.PENDING);
456 serviceInfoList.forEach(si -> updateServiceInfoAndAuditStatus(si.getJobId(), JobStatus.STOPPED));
460 public void deleteJob(UUID jobId) {
461 jobService.delete(jobId);
462 Date now = new Date();
463 updateServiceInfo(jobId, x -> x.setDeletedAt(now));
467 public void hideServiceInfo(UUID jobUUID) {
468 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobUUID);
469 if (!serviceInfo.getJobStatus().isFinal()) {
470 String message = String.format("jobId %s: Service status does not allow hide service, status = %s",
471 serviceInfo.getJobId(),
472 serviceInfo.getJobStatus());
473 logger.error(EELFLoggerDelegate.errorLogger, message);
474 throw new OperationNotAllowedException(message);
476 serviceInfo.setHidden(true);
477 asyncInstantiationRepository.saveServiceInfo(serviceInfo);
481 public int getCounterForName(String name) {
483 String hqlSelectNC = "from NameCounter where name = :name";
484 String hqlUpdateCounter = "update NameCounter set counter = :newCounter " +
485 "where name= :name " +
486 "and counter= :prevCounter";
488 Integer counter = null;
489 GenericUncheckedException lastException = null;
490 for (int i = 0; i< MAX_RETRIES_GETTING_COUNTER && counter==null; i++) {
492 counter = calcCounter(name, hqlSelectNC, hqlUpdateCounter);
494 catch (GenericUncheckedException exception) {
495 lastException = exception; //do nothing, we will try again in the loop
503 throw lastException!=null ? new DbFailureUncheckedException(lastException) :
504 new DbFailureUncheckedException("Failed to get counter for "+name+" due to unknown error");
508 private Integer calcCounter(String name, String hqlSelectNC, String hqlUpdateCounter) {
510 counter = DaoUtils.tryWithSessionAndTransaction(sessionFactory, session -> {
511 NameCounter nameCounter = (NameCounter) session.createQuery(hqlSelectNC)
512 .setText("name", name)
514 if (nameCounter != null) {
515 int updatedRows = session.createQuery(hqlUpdateCounter)
516 .setText("name", nameCounter.getName())
517 .setInteger("prevCounter", nameCounter.getCounter())
518 .setInteger("newCounter", nameCounter.getCounter() + 1)
520 if (updatedRows == 1) {
521 return nameCounter.getCounter() + 1;
524 Object nameAsId = session.save(new NameCounter(name));
526 if (nameAsId != null) {
530 //in case of failure return null, in order to continue the loop
537 public int getMaxRetriesGettingFreeNameFromAai() {
538 return maxRetriesGettingFreeNameFromAai;
542 public void setMaxRetriesGettingFreeNameFromAai(int maxRetriesGettingFreeNameFromAai) {
543 this.maxRetriesGettingFreeNameFromAai = maxRetriesGettingFreeNameFromAai;
547 public String getUniqueName(String name, ResourceType resourceType) {
548 //check that name aai response well before increasing counter from DB
549 //Prevents unnecessary increasing of the counter while AAI doesn't response
550 isNameFreeInAai(NAME_FOR_CHECK_AAI_STATUS, resourceType);
552 for (int i=0; i<getMaxRetriesGettingFreeNameFromAai(); i++) {
553 String newName = getUniqueNameFromDbOnly(name);
554 if (isNameFreeInAai(newName, resourceType)) {
559 throw new MaxRetriesException("can't find unused name for "+name, getMaxRetriesGettingFreeNameFromAai());
563 public ServiceInstantiation prepareServiceToBeUnique(ServiceInstantiation serviceInstantiation) {
565 ServiceInstantiation clonedServiceInstantiation = JACKSON_OBJECT_MAPPER.readValue(
566 JACKSON_OBJECT_MAPPER.writeValueAsBytes(serviceInstantiation), ServiceInstantiation.class);
567 clonedServiceInstantiation.setBulkSize(1);
568 return replaceAllTrackById(clonedServiceInstantiation);
569 } catch (IOException e) {
570 throw new GenericUncheckedException(e);
575 private<T extends BaseResource> T replaceAllTrackById(T resource) {
576 resource.setTrackById(UUID.randomUUID().toString());
577 resource.getChildren().forEach(this::replaceAllTrackById);
582 public List<UUID> retryJob(ServiceInstantiation request, UUID jobId, String userId ) {
583 updateServiceInfo(jobId, si->si.setRetryEnabled(false));
584 return pushBulkJob(request, userId);
588 public List<UUID> retryJob(UUID jobId, String userId) {
589 ServiceInstantiation serviceInstantiationRequest = asyncInstantiationRepository.getJobRequest(jobId);
590 enrichBulkForRetry(serviceInstantiationRequest, jobId);
593 logger.debug(EELFLoggerDelegate.debugLogger, "retry ServiceInstantiation request: "+
594 JACKSON_OBJECT_MAPPER.writeValueAsString(serviceInstantiationRequest));
595 } catch (Exception e) {
596 logger.error(EELFLoggerDelegate.errorLogger, "failed to log retry of ServiceInstantiation request ", e);
598 return retryJob(serviceInstantiationRequest, jobId, userId);
602 public ServiceInstantiation getBulkForRetry(UUID jobId) {
603 return enrichBulkForRetry( asyncInstantiationRepository.getJobRequest(jobId), jobId);
607 public void addResourceInfo(JobSharedData sharedData, Job.JobStatus jobStatus, String instanceId) {
608 String trackById = ((BaseResource) sharedData.getRequest()).getTrackById();
609 ResourceInfo resourceInfo = new ResourceInfo(trackById, sharedData.getRootJobId(), instanceId, jobStatus, null);
610 asyncInstantiationRepository.saveResourceInfo(resourceInfo);
614 public void addFailedResourceInfo(JobSharedData sharedData, RestObject msoResponse) {
615 String trackById = ((BaseResource) sharedData.getRequest()).getTrackById();
616 String errorMessage = MsoUtil.formatExceptionAdditionalInfo(msoResponse.getStatusCode(), msoResponse.getRaw());
617 AsyncRequestStatus asyncRequestStatus = convertMessageToAsyncRequestStatus(errorMessage);
618 ResourceInfo resourceInfo = new ResourceInfo(trackById, sharedData.getRootJobId(), null, JobStatus.FAILED, asyncRequestStatus);
620 asyncInstantiationRepository.saveResourceInfo(resourceInfo);
624 public void updateResourceInfo(JobSharedData sharedData, JobStatus jobStatus, AsyncRequestStatus message) {
625 ResourceInfo resourceInfo = asyncInstantiationRepository.getResourceInfoByTrackId(((BaseResource) sharedData.getRequest()).getTrackById());
626 resourceInfo.setJobStatus(jobStatus);
627 if (jobStatus.isFailure()) {
628 resourceInfo.setErrorMessage(message);
630 asyncInstantiationRepository.saveResourceInfo(resourceInfo);
633 public AsyncRequestStatus convertMessageToAsyncRequestStatus(String message) {
634 RequestStatus requestStatus = new RequestStatus("FAILED", message, TimeUtils.zonedDateTimeToString(ZonedDateTime.now()));
635 AsyncRequestStatus.Request request = new AsyncRequestStatus.Request(requestStatus);
636 return new AsyncRequestStatus(request);
639 protected String getUniqueNameFromDbOnly(String name) {
640 int counter = getCounterForName(name);
641 return formatNameAndCounter(name, counter);
644 //the method is protected so we can call it in the UT
645 protected String formatNameAndCounter(String name, int counter) {
646 return counter==0 ? name : name + "_" + String.format("%03d", counter);
649 private boolean isNameFreeInAai(String name, ResourceType resourceType){
650 return !aaiClient.isNodeTypeExistsByName(name, resourceType);
654 public ServiceInstantiation enrichBulkForRetry(ServiceInstantiation serviceInstantiation, UUID jobId){
655 Map<String, ResourceInfo> resourceInfoByTrackId = asyncInstantiationRepository.getResourceInfoByRootJobId(jobId);
657 return setResourceStatus(resourceInfoByTrackId, serviceInstantiation);
660 protected String readStatusMsg(ResourceInfo resourceInfo){
661 if(resourceInfo!=null && resourceInfo.getErrorMessage()!=null && resourceInfo.getErrorMessage().request != null &&resourceInfo.getErrorMessage().request.requestStatus != null ) {
662 return resourceInfo.getErrorMessage().request.requestStatus.getStatusMessage();
667 private<T extends BaseResource> T setResourceStatus(Map<String, ResourceInfo> resourceInfoByTrackId, T resource) {
668 ResourceInfo resourceInfo = resourceInfoByTrackId.get(resource.getTrackById());
669 if(resourceInfo != null) {
670 boolean failed = resourceInfo.getJobStatus().isFailure();
671 resource.setIsFailed(failed);
672 resource.setStatusMessage(readStatusMsg(resourceInfo));
674 // if(resource.getAction().equals(Action.Delete)){
675 // TODO not yet implemented- completed after delete should remove the node
676 resource.setAction(Action.None);
677 resource.setInstanceId(resourceInfo.getInstanceId());
680 resource.getChildren().forEach(child -> setResourceStatus(resourceInfoByTrackId, child));