When JobStatus is COMPLETED_AND_PAUSED add retry option dropdown menu on instantiatio...
[vid.git] / vid-app-common / src / main / java / org / onap / vid / services / AsyncInstantiationBusinessLogicImpl.java
index c77eb82..9180197 100644 (file)
 
 package org.onap.vid.services;
 
+import static com.google.common.collect.Streams.concat;
+import static java.util.function.Function.identity;
+import static java.util.stream.Collectors.counting;
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Stream.empty;
 import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
+import static org.apache.commons.lang3.StringUtils.isNotEmpty;
 import static org.onap.vid.controller.MsoController.SVC_INSTANCE_ID;
 import static org.onap.vid.controller.MsoController.VNF_INSTANCE_ID;
 import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
@@ -33,9 +39,10 @@ import java.util.Calendar;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.UUID;
 import java.util.function.Consumer;
-import org.apache.commons.lang3.StringUtils;
+import java.util.stream.Stream;
 import org.hibernate.SessionFactory;
 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
 import org.onap.vid.aai.AaiClientInterface;
@@ -55,12 +62,15 @@ import org.onap.vid.model.Action;
 import org.onap.vid.model.NameCounter;
 import org.onap.vid.model.ResourceInfo;
 import org.onap.vid.model.ServiceInfo;
+import org.onap.vid.model.ServiceInfo.ServiceAction;
 import org.onap.vid.model.serviceInstantiation.BaseResource;
 import org.onap.vid.model.serviceInstantiation.ServiceInstantiation;
+import org.onap.vid.model.serviceInstantiation.VfModule;
 import org.onap.vid.mso.MsoBusinessLogicImpl;
 import org.onap.vid.mso.MsoProperties;
 import org.onap.vid.mso.MsoUtil;
 import org.onap.vid.mso.RestObject;
+import org.onap.vid.mso.model.ModelInfo;
 import org.onap.vid.mso.rest.AsyncRequestStatus;
 import org.onap.vid.mso.rest.RequestStatus;
 import org.onap.vid.properties.Features;
@@ -160,7 +170,9 @@ public class AsyncInstantiationBusinessLogicImpl implements
         int bulkSize = request.getBulkSize();
         UUID templateId = UUID.randomUUID();
         for (int i = 0; i < bulkSize; i++) {
-            ServiceInstantiation requestPerJob = prepareServiceToBeUnique(request);
+            ServiceInstantiation clonedServiceInstantiation = cloneServiceInstantiation(request);
+            ServiceInstantiation requestPerJob = prepareServiceToBeUnique(clonedServiceInstantiation);
+            requestPerJob = clearStatusFromRequest(requestPerJob);
             ServiceInfo.ServiceAction serviceAction = getAction(requestPerJob);
             JobType jobType = getJobType(requestPerJob);
             final String optimisticUniqueServiceInstanceName = bulkSize>1 ? //only bulk with more than 1 service need to get multiple names
@@ -168,7 +180,10 @@ public class AsyncInstantiationBusinessLogicImpl implements
             Job job = jobAdapter.createServiceInstantiationJob(jobType, requestPerJob, templateId, userId, request.getTestApi(), optimisticUniqueServiceInstanceName, i);
             UUID jobId = job.getUuid();
 
-            asyncInstantiationRepository.saveServiceInfo(createServiceInfo(userId, requestPerJob, jobId, templateId, createdBulkDate, optimisticUniqueServiceInstanceName, serviceAction));
+            asyncInstantiationRepository.saveServiceInfo(createServiceInfo(
+                userId, requestPerJob, jobId, templateId, createdBulkDate,
+                optimisticUniqueServiceInstanceName, serviceAction,
+                requestSummaryOrNull(requestPerJob)));
             asyncInstantiationRepository.addJobRequest(jobId, requestPerJob);
             auditService.auditVidStatus(jobId, job.getStatus());
             uuids.add(jobId);
@@ -178,6 +193,60 @@ public class AsyncInstantiationBusinessLogicImpl implements
         return uuids;
     }
 
+    Map<String, Long> requestSummaryOrNull(ServiceInstantiation request) {
+        if (!featureManager.isActive(Features.FLAG_2004_CREATE_ANOTHER_INSTANCE_FROM_TEMPLATE)) {
+            return null;
+        }
+
+        if (getAction(request) != ServiceAction.INSTANTIATE) {
+            return null;
+        }
+
+        return summarizedChildrenMap(request);
+    }
+
+    public Map<String, Long> summarizedChildrenMap(ServiceInstantiation serviceInstantiation){
+        Stream<String> existingTypesStream =
+            allDeepChildResources(serviceInstantiation)
+                .map(this::getModelTypes)
+                .flatMap(identity());
+
+        Map<String, Long> existingTypesCounters =
+            existingTypesStream.collect(groupingBy(identity(), counting()));
+
+        return existingTypesCounters;
+    }
+
+    private Stream<String> getModelTypes(BaseResource resource) {
+        return concat(
+            Stream.of(resource)
+                .map(BaseResource::getModelInfo)
+                .filter(Objects::nonNull)
+                .map(ModelInfo::getModelType),
+            streamVolumeGroups(resource)
+        );
+    }
+
+    private Stream<String> streamVolumeGroups(BaseResource resource) {
+        return hasVolumeGroup(resource)
+            ? Stream.of("volumeGroup")
+            : empty();
+    }
+
+    private boolean hasVolumeGroup(BaseResource resource) {
+        return
+            resource instanceof VfModule
+            && isNotEmpty(((VfModule) resource).getVolumeGroupInstanceName());
+    }
+
+    private Stream<BaseResource> allDeepChildResources(BaseResource resource) {
+        return resource
+            .getChildren()
+            .stream()
+            .map(it -> concat(Stream.of(it), allDeepChildResources(it)))
+            .flatMap(identity());
+    }
+
     private ServiceInfo.ServiceAction getAction(ServiceInstantiation request) {
         if (request.getAction() == null) {
             //throw new GenericUncheckedException("Required 'action' field not provided at service level");
@@ -188,10 +257,12 @@ public class AsyncInstantiationBusinessLogicImpl implements
 
 
     private String getOptimisticUniqueServiceInstanceName(String instanceName) {
-        return StringUtils.isNotEmpty(instanceName) ? getUniqueNameFromDbOnly(instanceName) : instanceName;
+        return isNotEmpty(instanceName) ? getUniqueNameFromDbOnly(instanceName) : instanceName;
     }
 
-    protected ServiceInfo createServiceInfo(String userId, ServiceInstantiation serviceInstantiation, UUID jobId, UUID templateId, Date createdBulkDate, String optimisticUniqueServiceInstanceName, ServiceInfo.ServiceAction serviceAction) {
+    protected ServiceInfo createServiceInfo(String userId, ServiceInstantiation serviceInstantiation, UUID jobId,
+        UUID templateId, Date createdBulkDate, String optimisticUniqueServiceInstanceName,
+        ServiceInfo.ServiceAction serviceAction, Map<String, Long> requestSummary) {
         return new ServiceInfo(
                 userId,
                 serviceInstantiation.isALaCarte(),
@@ -215,7 +286,8 @@ public class AsyncInstantiationBusinessLogicImpl implements
                 serviceInstantiation.getModelInfo().getModelVersion(),
                 createdBulkDate,
                 serviceAction,
-                false);
+                false,
+                requestSummary);
     }
 
     @Override
@@ -363,8 +435,8 @@ public class AsyncInstantiationBusinessLogicImpl implements
     }
 
     private boolean isRetryEnabledForStatus(JobStatus jobStatus) {
-        return featureManager.isActive(Features.FLAG_1902_RETRY_JOB) &&
-                (jobStatus==JobStatus.COMPLETED_WITH_ERRORS || jobStatus==JobStatus.FAILED);
+        return jobStatus==JobStatus.COMPLETED_AND_PAUSED || (featureManager.isActive(Features.FLAG_1902_RETRY_JOB) &&
+                (jobStatus==JobStatus.COMPLETED_WITH_ERRORS || jobStatus==JobStatus.FAILED));
     }
 
     private void setServiceInfoStatus(ServiceInfo serviceInfo, JobStatus jobStatus) {
@@ -491,20 +563,28 @@ public class AsyncInstantiationBusinessLogicImpl implements
 
     @Override
     public ServiceInstantiation prepareServiceToBeUnique(ServiceInstantiation serviceInstantiation) {
+        serviceInstantiation.setBulkSize(1);
+        return replaceAllTrackById(serviceInstantiation);
+    }
+    private<T extends BaseResource> T replaceAllTrackById(T resource) {
+        resource.setTrackById(UUID.randomUUID().toString());
+        resource.getChildren().forEach(this::replaceAllTrackById);
+        return resource;
+    }
+
+    private ServiceInstantiation cloneServiceInstantiation(ServiceInstantiation serviceInstantiation) {
         try {
-            ServiceInstantiation clonedServiceInstantiation = JACKSON_OBJECT_MAPPER.readValue(
-                    JACKSON_OBJECT_MAPPER.writeValueAsBytes(serviceInstantiation), ServiceInstantiation.class);
-            clonedServiceInstantiation.setBulkSize(1);
-            return replaceAllTrackById(clonedServiceInstantiation);
+            return JACKSON_OBJECT_MAPPER.readValue(
+                JACKSON_OBJECT_MAPPER.writeValueAsBytes(serviceInstantiation), ServiceInstantiation.class);
         } catch (IOException e) {
             throw new GenericUncheckedException(e);
         }
-
     }
 
-    private<T extends BaseResource> T replaceAllTrackById(T resource) {
-        resource.setTrackById(UUID.randomUUID().toString());
-        resource.getChildren().forEach(this::replaceAllTrackById);
+    <T extends BaseResource> T clearStatusFromRequest(T resource) {
+        resource.setIsFailed(false);
+        resource.setStatusMessage(null);
+        resource.getChildren().forEach(this::clearStatusFromRequest);
         return resource;
     }