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 clonedServiceInstantiation = cloneServiceInstantiation(request);
174 ServiceInstantiation requestPerJob = prepareServiceToBeUnique(clonedServiceInstantiation);
175 requestPerJob = clearStatusFromRequest(requestPerJob);
176 ServiceInfo.ServiceAction serviceAction = getAction(requestPerJob);
177 JobType jobType = getJobType(requestPerJob);
178 final String optimisticUniqueServiceInstanceName = bulkSize>1 ? //only bulk with more than 1 service need to get multiple names
179 getOptimisticUniqueServiceInstanceName(requestPerJob.getInstanceName()) : requestPerJob.getInstanceName();
180 Job job = jobAdapter.createServiceInstantiationJob(jobType, requestPerJob, templateId, userId, request.getTestApi(), optimisticUniqueServiceInstanceName, i);
181 UUID jobId = job.getUuid();
183 asyncInstantiationRepository.saveServiceInfo(createServiceInfo(
184 userId, requestPerJob, jobId, templateId, createdBulkDate,
185 optimisticUniqueServiceInstanceName, serviceAction,
186 requestSummaryOrNull(requestPerJob)));
187 asyncInstantiationRepository.addJobRequest(jobId, requestPerJob);
188 auditService.auditVidStatus(jobId, job.getStatus());
196 Map<String, Long> requestSummaryOrNull(ServiceInstantiation request) {
197 if (!featureManager.isActive(Features.FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE)) {
201 if (getAction(request) != ServiceAction.INSTANTIATE) {
205 return summarizedChildrenMap(request);
208 public Map<String, Long> summarizedChildrenMap(ServiceInstantiation serviceInstantiation){
209 Stream<String> existingTypesStream =
210 allDeepChildResources(serviceInstantiation)
211 .map(this::getModelTypes)
212 .flatMap(identity());
214 Map<String, Long> existingTypesCounters =
215 existingTypesStream.collect(groupingBy(identity(), counting()));
217 return existingTypesCounters;
220 private Stream<String> getModelTypes(BaseResource resource) {
223 .map(BaseResource::getModelInfo)
224 .filter(Objects::nonNull)
225 .map(ModelInfo::getModelType),
226 streamVolumeGroups(resource)
230 private Stream<String> streamVolumeGroups(BaseResource resource) {
231 return hasVolumeGroup(resource)
232 ? Stream.of("volumeGroup")
236 private boolean hasVolumeGroup(BaseResource resource) {
238 resource instanceof VfModule
239 && isNotEmpty(((VfModule) resource).getVolumeGroupInstanceName());
242 private Stream<BaseResource> allDeepChildResources(BaseResource resource) {
246 .map(it -> concat(Stream.of(it), allDeepChildResources(it)))
247 .flatMap(identity());
250 private ServiceInfo.ServiceAction getAction(ServiceInstantiation request) {
251 if (request.getAction() == null) {
252 //throw new GenericUncheckedException("Required 'action' field not provided at service level");
253 return Action.Create.getServiceAction();
255 return request.getAction().getServiceAction();
259 private String getOptimisticUniqueServiceInstanceName(String instanceName) {
260 return isNotEmpty(instanceName) ? getUniqueNameFromDbOnly(instanceName) : instanceName;
263 protected ServiceInfo createServiceInfo(String userId, ServiceInstantiation serviceInstantiation, UUID jobId,
264 UUID templateId, Date createdBulkDate, String optimisticUniqueServiceInstanceName,
265 ServiceInfo.ServiceAction serviceAction, Map<String, Long> requestSummary) {
266 return new ServiceInfo(
268 serviceInstantiation.isALaCarte(),
269 Job.JobStatus.PENDING, serviceInstantiation.isPause(), jobId, templateId,
270 serviceInstantiation.getOwningEntityId(),
271 serviceInstantiation.getOwningEntityName(),
272 serviceInstantiation.getProjectName(),
273 serviceInstantiation.getAicZoneId(),
274 serviceInstantiation.getAicZoneName(),
275 serviceInstantiation.getTenantId(),
276 serviceInstantiation.getTenantName(),
277 serviceInstantiation.getLcpCloudRegionId(),
279 serviceInstantiation.getSubscriptionServiceType(),
280 serviceInstantiation.getSubscriberName(),
281 serviceInstantiation.getGlobalSubscriberId(),
282 serviceInstantiation.getInstanceId(),
283 optimisticUniqueServiceInstanceName,
284 serviceInstantiation.getModelInfo().getModelVersionId(),
285 serviceInstantiation.getModelInfo().getModelName(),
286 serviceInstantiation.getModelInfo().getModelVersion(),
294 public boolean isPartOfBulk(UUID jobId) {
298 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobId);
299 UUID templateId = serviceInfo.getTemplateId();
300 if (templateId != null) {
301 return getNumberOfJobsInBulk(templateId) > 1;
307 private int getNumberOfJobsInBulk(UUID templateId) {
308 String hqlSelectJob = "from JobDaoImpl where templateId = :templateId";
309 return DaoUtils.tryWithSessionAndTransaction(sessionFactory, session ->
310 session.createQuery(hqlSelectJob)
311 .setText("templateId", templateId.toString())
318 public String getServiceInstantiationPath(ServiceInstantiation serviceInstantiationRequest) {
319 //in case pause flag is true - use assign , else - use create.
320 return MsoBusinessLogicImpl.validateEndpointPath(
321 serviceInstantiationRequest.isPause() ?
322 MsoProperties.MSO_REST_API_SERVICE_INSTANCE_ASSIGN : MsoProperties.MSO_RESTAPI_SERVICE_INSTANCE
327 public String getServiceDeletionPath(String serviceInstanceId) {
328 return MsoBusinessLogicImpl.validateEndpointPath( MsoProperties.MSO_RESTAPI_SERVICE_INSTANCE) + "/" + serviceInstanceId;
332 public String getVnfInstantiationPath(String serviceInstanceId) {
333 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE).
334 replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
338 public String getVnfDeletionPath(String serviceInstanceId, String vnfInstanceId) {
339 return (MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VNF_INSTANCE)
340 + '/' + vnfInstanceId)
341 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId).replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
345 public String getNetworkInstantiationPath(String serviceInstanceId) {
346 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_NETWORK_INSTANCE).
347 replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
351 public String getVfmoduleInstantiationPath(String serviceInstanceId, String vnfInstanceId) {
352 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE)
353 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
354 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
358 public String getVfModuleReplacePath(String serviceInstanceId, String vnfInstanceId, String vfModuleInstanceId)
360 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE)
361 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
362 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId)
363 + "/" + vfModuleInstanceId
368 public String getVfModuleDeletePath(String serviceInstanceId, String vnfInstanceId, String vfModuleInstanceId) {
369 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VF_MODULE_INSTANCE)
370 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
371 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId)
372 + "/" + vfModuleInstanceId;
376 public String getVolumeGroupInstantiationPath(String serviceInstanceId, String vnfInstanceId) {
377 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_VOLUME_GROUP_INSTANCE)
378 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId)
379 .replaceFirst(VNF_INSTANCE_ID, vnfInstanceId);
383 public String getInstanceGroupInstantiationPath() {
384 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP);
388 public String getInstanceGroupMemberInstantiationPath(String vnfGroupInstanceId) {
389 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP)
390 + '/' + vnfGroupInstanceId + "/addMembers";
394 public String getInstanceGroupDeletePath(String instanceGroupId) {
395 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP)
396 + '/' + instanceGroupId;
400 public String getInstanceGroupMemberDeletePath(String vnfGroupInstanceId){
401 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_INSTANCE_GROUP)
402 + '/' + vnfGroupInstanceId + "/removeMembers";
406 public String getNetworkDeletePath(String serviceInstanceId, String networkInstanceId) {
407 return (MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_NETWORK_INSTANCE)
408 + "/" + networkInstanceId)
409 .replaceFirst(SVC_INSTANCE_ID, serviceInstanceId);
413 public String getResumeRequestPath(String requestId) {
414 return MsoBusinessLogicImpl.validateEndpointPath("mso.restapi.resume.orc.req")
415 .replaceFirst("<request_id>", requestId);
419 public String getOrchestrationRequestsPath() {
420 return MsoBusinessLogicImpl.validateEndpointPath(MsoProperties.MSO_REST_API_GET_ORC_REQ);
424 public ServiceInfo updateServiceInfo(UUID jobUUID, Consumer<ServiceInfo> serviceUpdater) {
425 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobUUID);
426 serviceUpdater.accept(serviceInfo);
427 asyncInstantiationRepository.saveServiceInfo(serviceInfo);
432 public ServiceInfo updateServiceInfoAndAuditStatus(UUID jobUuid, JobStatus jobStatus) {
433 auditService.auditVidStatus(jobUuid, jobStatus);
434 return updateServiceInfo(jobUuid, x -> setServiceInfoStatus(x, jobStatus));
437 private boolean isRetryEnabledForStatus(JobStatus jobStatus) {
438 return jobStatus==JobStatus.COMPLETED_AND_PAUSED || (featureManager.isActive(Features.FLAG_1902_RETRY_JOB) &&
439 (jobStatus==JobStatus.COMPLETED_WITH_ERRORS || jobStatus==JobStatus.FAILED || jobStatus==JobStatus.FAILED_AND_PAUSED));
442 private void setServiceInfoStatus(ServiceInfo serviceInfo, JobStatus jobStatus) {
443 serviceInfo.setJobStatus(jobStatus);
444 serviceInfo.setStatusModifiedDate(new Date());
445 serviceInfo.setRetryEnabled(isRetryEnabledForStatus(jobStatus));
448 public Job.JobStatus calcStatus(AsyncRequestStatus asyncRequestStatus) {
449 String msoRequestState = asyncRequestStatus.request.requestStatus.getRequestState().toLowerCase().replaceAll("[^a-z]+", "");
450 JobStatus jobStatus = msoStateToJobStatusMap.get(msoRequestState);
451 return (jobStatus != null ? jobStatus : JobStatus.IN_PROGRESS);
455 public void handleFailedInstantiation(UUID jobUUID) {
456 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobUUID);
457 List<ServiceInfo> serviceInfoList = asyncInstantiationRepository.getServiceInfoByTemplateIdAndJobStatus(serviceInfo.getTemplateId(), JobStatus.PENDING);
458 serviceInfoList.forEach(si -> updateServiceInfoAndAuditStatus(si.getJobId(), JobStatus.STOPPED));
462 public void deleteJob(UUID jobId) {
463 jobService.delete(jobId);
464 Date now = new Date();
465 updateServiceInfo(jobId, x -> x.setDeletedAt(now));
469 public void hideServiceInfo(UUID jobUUID) {
470 ServiceInfo serviceInfo = asyncInstantiationRepository.getServiceInfoByJobId(jobUUID);
471 if (!serviceInfo.getJobStatus().isFinal()) {
472 String message = String.format("jobId %s: Service status does not allow hide service, status = %s",
473 serviceInfo.getJobId(),
474 serviceInfo.getJobStatus());
475 logger.error(EELFLoggerDelegate.errorLogger, message);
476 throw new OperationNotAllowedException(message);
478 serviceInfo.setHidden(true);
479 asyncInstantiationRepository.saveServiceInfo(serviceInfo);
483 public int getCounterForName(String name) {
485 String hqlSelectNC = "from NameCounter where name = :name";
486 String hqlUpdateCounter = "update NameCounter set counter = :newCounter " +
487 "where name= :name " +
488 "and counter= :prevCounter";
490 Integer counter = null;
491 GenericUncheckedException lastException = null;
492 for (int i = 0; i< MAX_RETRIES_GETTING_COUNTER && counter==null; i++) {
494 counter = calcCounter(name, hqlSelectNC, hqlUpdateCounter);
496 catch (GenericUncheckedException exception) {
497 lastException = exception; //do nothing, we will try again in the loop
505 throw lastException!=null ? new DbFailureUncheckedException(lastException) :
506 new DbFailureUncheckedException("Failed to get counter for "+name+" due to unknown error");
510 private Integer calcCounter(String name, String hqlSelectNC, String hqlUpdateCounter) {
512 counter = DaoUtils.tryWithSessionAndTransaction(sessionFactory, session -> {
513 NameCounter nameCounter = (NameCounter) session.createQuery(hqlSelectNC)
514 .setText("name", name)
516 if (nameCounter != null) {
517 int updatedRows = session.createQuery(hqlUpdateCounter)
518 .setText("name", nameCounter.getName())
519 .setInteger("prevCounter", nameCounter.getCounter())
520 .setInteger("newCounter", nameCounter.getCounter() + 1)
522 if (updatedRows == 1) {
523 return nameCounter.getCounter() + 1;
526 Object nameAsId = session.save(new NameCounter(name));
528 if (nameAsId != null) {
532 //in case of failure return null, in order to continue the loop
539 public int getMaxRetriesGettingFreeNameFromAai() {
540 return maxRetriesGettingFreeNameFromAai;
544 public void setMaxRetriesGettingFreeNameFromAai(int maxRetriesGettingFreeNameFromAai) {
545 this.maxRetriesGettingFreeNameFromAai = maxRetriesGettingFreeNameFromAai;
549 public String getUniqueName(String name, ResourceType resourceType) {
550 //check that name aai response well before increasing counter from DB
551 //Prevents unnecessary increasing of the counter while AAI doesn't response
552 isNameFreeInAai(NAME_FOR_CHECK_AAI_STATUS, resourceType);
554 for (int i=0; i<getMaxRetriesGettingFreeNameFromAai(); i++) {
555 String newName = getUniqueNameFromDbOnly(name);
556 if (isNameFreeInAai(newName, resourceType)) {
561 throw new MaxRetriesException("can't find unused name for "+name, getMaxRetriesGettingFreeNameFromAai());
565 public ServiceInstantiation prepareServiceToBeUnique(ServiceInstantiation serviceInstantiation) {
566 serviceInstantiation.setBulkSize(1);
567 return replaceAllTrackById(serviceInstantiation);
569 private<T extends BaseResource> T replaceAllTrackById(T resource) {
570 resource.setTrackById(UUID.randomUUID().toString());
571 resource.getChildren().forEach(this::replaceAllTrackById);
575 private ServiceInstantiation cloneServiceInstantiation(ServiceInstantiation serviceInstantiation) {
577 return JACKSON_OBJECT_MAPPER.readValue(
578 JACKSON_OBJECT_MAPPER.writeValueAsBytes(serviceInstantiation), ServiceInstantiation.class);
579 } catch (IOException e) {
580 throw new GenericUncheckedException(e);
584 <T extends BaseResource> T clearStatusFromRequest(T resource) {
585 resource.setIsFailed(false);
586 resource.setStatusMessage(null);
587 resource.getChildren().forEach(this::clearStatusFromRequest);
592 public List<UUID> retryJob(ServiceInstantiation request, UUID jobId, String userId ) {
593 updateServiceInfo(jobId, si->si.setRetryEnabled(false));
594 return pushBulkJob(request, userId);
598 public List<UUID> retryJob(UUID jobId, String userId) {
599 ServiceInstantiation serviceInstantiationRequest = asyncInstantiationRepository.getJobRequest(jobId);
600 enrichBulkForRetry(serviceInstantiationRequest, jobId);
603 logger.debug(EELFLoggerDelegate.debugLogger, "retry ServiceInstantiation request: "+
604 JACKSON_OBJECT_MAPPER.writeValueAsString(serviceInstantiationRequest));
605 } catch (Exception e) {
606 logger.error(EELFLoggerDelegate.errorLogger, "failed to log retry of ServiceInstantiation request ", e);
608 return retryJob(serviceInstantiationRequest, jobId, userId);
612 public ServiceInstantiation getBulkForRetry(UUID jobId) {
613 return enrichBulkForRetry( asyncInstantiationRepository.getJobRequest(jobId), jobId);
617 public void addResourceInfo(JobSharedData sharedData, Job.JobStatus jobStatus, String instanceId) {
618 String trackById = ((BaseResource) sharedData.getRequest()).getTrackById();
619 ResourceInfo resourceInfo = new ResourceInfo(trackById, sharedData.getRootJobId(), instanceId, jobStatus, null);
620 asyncInstantiationRepository.saveResourceInfo(resourceInfo);
624 public void addFailedResourceInfo(JobSharedData sharedData, RestObject msoResponse) {
625 String trackById = ((BaseResource) sharedData.getRequest()).getTrackById();
626 String errorMessage = MsoUtil.formatExceptionAdditionalInfo(msoResponse.getStatusCode(), msoResponse.getRaw());
627 AsyncRequestStatus asyncRequestStatus = convertMessageToAsyncRequestStatus(errorMessage);
628 ResourceInfo resourceInfo = new ResourceInfo(trackById, sharedData.getRootJobId(), null, JobStatus.FAILED, asyncRequestStatus);
630 asyncInstantiationRepository.saveResourceInfo(resourceInfo);
634 public void updateResourceInfo(JobSharedData sharedData, JobStatus jobStatus, AsyncRequestStatus message) {
635 ResourceInfo resourceInfo = asyncInstantiationRepository.getResourceInfoByTrackId(((BaseResource) sharedData.getRequest()).getTrackById());
636 resourceInfo.setJobStatus(jobStatus);
637 if (jobStatus.isFailure()) {
638 resourceInfo.setErrorMessage(message);
640 asyncInstantiationRepository.saveResourceInfo(resourceInfo);
643 public AsyncRequestStatus convertMessageToAsyncRequestStatus(String message) {
644 RequestStatus requestStatus = new RequestStatus("FAILED", message, TimeUtils.zonedDateTimeToString(ZonedDateTime.now()));
645 AsyncRequestStatus.Request request = new AsyncRequestStatus.Request(requestStatus);
646 return new AsyncRequestStatus(request);
649 protected String getUniqueNameFromDbOnly(String name) {
650 int counter = getCounterForName(name);
651 return formatNameAndCounter(name, counter);
654 //the method is protected so we can call it in the UT
655 protected String formatNameAndCounter(String name, int counter) {
656 return counter==0 ? name : name + "_" + String.format("%03d", counter);
659 private boolean isNameFreeInAai(String name, ResourceType resourceType){
660 return !aaiClient.isNodeTypeExistsByName(name, resourceType);
664 public ServiceInstantiation enrichBulkForRetry(ServiceInstantiation serviceInstantiation, UUID jobId){
665 Map<String, ResourceInfo> resourceInfoByTrackId = asyncInstantiationRepository.getResourceInfoByRootJobId(jobId);
667 return setResourceStatus(resourceInfoByTrackId, serviceInstantiation);
670 protected String readStatusMsg(ResourceInfo resourceInfo){
671 if(resourceInfo!=null && resourceInfo.getErrorMessage()!=null && resourceInfo.getErrorMessage().request != null &&resourceInfo.getErrorMessage().request.requestStatus != null ) {
672 return resourceInfo.getErrorMessage().request.requestStatus.getStatusMessage();
677 private<T extends BaseResource> T setResourceStatus(Map<String, ResourceInfo> resourceInfoByTrackId, T resource) {
678 ResourceInfo resourceInfo = resourceInfoByTrackId.get(resource.getTrackById());
679 if(resourceInfo != null) {
680 boolean failed = resourceInfo.getJobStatus().isFailure();
681 resource.setIsFailed(failed);
682 resource.setStatusMessage(readStatusMsg(resourceInfo));
684 // if(resource.getAction().equals(Action.Delete)){
685 // TODO not yet implemented- completed after delete should remove the node
686 resource.setAction(Action.None);
687 resource.setInstanceId(resourceInfo.getInstanceId());
690 resource.getChildren().forEach(child -> setResourceStatus(resourceInfoByTrackId, child));