Support deletion of archived services in SDC BE
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ServiceBusinessLogic.java
index ccaadba..8dac6ff 100644 (file)
@@ -102,6 +102,7 @@ import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
+import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
 import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceDistributionReqInfo;
 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
 import org.openecomp.sdc.be.impl.WebAppContextWrapper;
@@ -123,6 +124,7 @@ import org.openecomp.sdc.be.model.PropertyDefinition;
 import org.openecomp.sdc.be.model.Resource;
 import org.openecomp.sdc.be.model.Service;
 import org.openecomp.sdc.be.model.User;
+import org.openecomp.sdc.be.model.Model;
 import org.openecomp.sdc.be.model.category.CategoryDefinition;
 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ForwardingPathOperation;
@@ -133,6 +135,7 @@ import org.openecomp.sdc.be.model.operations.api.IGroupOperation;
 import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation;
+import org.openecomp.sdc.be.model.operations.impl.ModelOperation;
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils;
 import org.openecomp.sdc.be.plugins.ServiceCreationPlugin;
@@ -194,6 +197,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
     private ServiceCategoryValidator serviceCategoryValidator;
     @Autowired
     private ServiceValidator serviceValidator;
+    private final ModelOperation modelOperation;
 
     @Autowired
     public ServiceBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation,
@@ -205,7 +209,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
                                 ComponentContactIdValidator componentContactIdValidator, ComponentNameValidator componentNameValidator,
                                 ComponentTagsValidator componentTagsValidator, ComponentValidator componentValidator,
                                 ComponentIconValidator componentIconValidator, ComponentProjectCodeValidator componentProjectCodeValidator,
-                                ComponentDescriptionValidator componentDescriptionValidator) {
+                                ComponentDescriptionValidator componentDescriptionValidator, ModelOperation modelOperation) {
         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation,
             interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation, componentContactIdValidator, componentNameValidator,
             componentTagsValidator, componentValidator, componentIconValidator, componentProjectCodeValidator, componentDescriptionValidator);
@@ -214,6 +218,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         this.serviceDistributionValidation = serviceDistributionValidation;
         this.forwardingPathValidator = forwardingPathValidator;
         this.uiComponentDataConverter = uiComponentDataConverter;
+        this.modelOperation = modelOperation;
     }
 
     @Autowired
@@ -382,11 +387,11 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         if (STATIC.equals(sourceValue)) {
             // Validate constraint on input value
             Either<Boolean, ResponseFormat> constraintValidationResult = validateOperationInputConstraint(operationInputDefinition, consumptionValue,
-                type);
+                type, containerService.getModel());
             if (constraintValidationResult.isRight()) {
                 return Either.right(constraintValidationResult.right().value());
             }
-            return handleConsumptionStaticValue(consumptionValue, type, operation, operationInputDefinition);
+            return handleConsumptionStaticValue(consumptionValue, type, operation, operationInputDefinition, containerService.getModel());
         }
         if (Objects.isNull(sourceValue)) {
             List<PropertyDefinition> propertyDefinitions;
@@ -523,13 +528,13 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
     }
 
     public Either<Operation, ResponseFormat> handleConsumptionStaticValue(String value, String type, Operation operation,
-                                                                          OperationInputDefinition operationInputDefinition) {
+                                                                          OperationInputDefinition operationInputDefinition, String model) {
         boolean isInputTypeSimilarToOperation = isAssignedValueFromValidType(type, value);
         if (!isInputTypeSimilarToOperation) {
             return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONSUMPTION_TYPE, type));
         }
         //Validate Constraint and Value
-        Either<Boolean, ResponseFormat> constraintValidationResponse = validateOperationInputConstraint(operationInputDefinition, value, type);
+        Either<Boolean, ResponseFormat> constraintValidationResponse = validateOperationInputConstraint(operationInputDefinition, value, type, model);
         if (constraintValidationResponse.isRight()) {
             return Either.right(constraintValidationResponse.right().value());
         }
@@ -538,7 +543,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
     }
 
     private Either<Boolean, ResponseFormat> validateOperationInputConstraint(OperationInputDefinition operationInputDefinition, String value,
-                                                                             String type) {
+                                                                             String type, String model) {
         ComponentInstanceProperty propertyDefinition = new ComponentInstanceProperty();
         propertyDefinition.setType(operationInputDefinition.getParentPropertyType());
         InputDefinition inputDefinition = new InputDefinition();
@@ -548,8 +553,8 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         if (Objects.nonNull(operationInputDefinition.getParentPropertyType())) {
             inputDefinition.setProperties(Collections.singletonList(propertyDefinition));
         }
-        return PropertyValueConstraintValidationUtil.getInstance()
-            .validatePropertyConstraints(Collections.singletonList(inputDefinition), applicationDataTypeCache);
+        return new PropertyValueConstraintValidationUtil().validatePropertyConstraints(Collections.singletonList(inputDefinition),
+            applicationDataTypeCache, model);
     }
 
     private void addStaticValueToInputOperation(String value, Operation operation, OperationInputDefinition operationInputDefinition) {
@@ -701,9 +706,12 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
             createMandatoryArtifactsData(service, user);
             createServiceApiArtifactsData(service, user);
             setToscaArtifactsPlaceHolders(service, user);
-            final Resource genericType = fetchAndSetDerivedFromGenericType(service);
-            generatePropertiesFromGenericType(service, genericType);
-            generateAndAddInputsFromGenericTypeProperties(service, genericType);
+
+            if (service.isSubstituteCandidate() || genericTypeBusinessLogic.hasMandatorySubstitutionType(service)) {
+                final Resource genericType = fetchAndSetDerivedFromGenericType(service);
+                generatePropertiesFromGenericType(service, genericType);
+                generateAndAddInputsFromGenericTypeProperties(service, genericType);
+            }
             beforeCreate(service);
             Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
             if (dataModelResponse.isLeft()) {
@@ -737,23 +745,6 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         });
     }
 
-    private void generatePropertiesFromGenericType(final Service service, final Resource genericType) {
-        if (CollectionUtils.isEmpty(genericType.getProperties())) {
-            return;
-        }
-        final List<PropertyDefinition> genericTypePropertyList = genericType.getProperties().stream().map(PropertyDefinition::new)
-            .peek(propertyDefinition -> propertyDefinition.setUniqueId(null)).collect(Collectors.toList());
-        if (service.getProperties() == null) {
-            service.setProperties(new ArrayList<>(genericTypePropertyList));
-        } else {
-            List<PropertyDefinition> servicePropertyList = service.getProperties();
-            genericTypePropertyList.stream()
-                .filter(property -> servicePropertyList.stream().noneMatch(property1 -> property1.getName().equals(property.getName())))
-                .forEach(servicePropertyList::add);
-        }
-        service.getProperties().forEach(propertyDefinition -> propertyDefinition.setUniqueId(null));
-    }
-
     @SuppressWarnings("unchecked")
     private void createServiceApiArtifactsData(Service service, User user) {
         // create mandatory artifacts
@@ -1315,7 +1306,39 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         return Either.left(serviceRelations);
     }
 
-    public ResponseFormat deleteService(String serviceId, User user) {
+    public void deleteServiceAllVersions(String serviceId, User user) {
+        validateUserExists(user);
+        Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);
+        if (serviceStatus.isRight()) {
+            log.debug("Failed to get service {}", serviceId);
+            componentException(serviceStatus.right().value());
+        }
+        Service service = serviceStatus.left().value();
+        if (Boolean.FALSE.equals(service.isArchived())) {
+            log.debug("The service, {}, requested for delete has not been archived.", serviceId);
+            throw new ComponentException(ActionStatus.COMPONENT_NOT_ARCHIVED, serviceId);
+        }
+        List<String> deletedServiceList = new ArrayList<>();
+        try {
+            String model = service.getModel();
+            final Optional<Model> modelOptional = modelOperation.findModelByName(model);
+            deletedServiceList = toscaOperationFacade.deleteService(service.getInvariantUUID(), true);
+            if (log.isDebugEnabled()) {
+                deletedServiceList.forEach(deletedS -> log.debug("Component {} was deleted.", deletedS));
+            }
+            if (modelOptional.isPresent() && modelOptional.get().getModelType() == ModelTypeEnum.NORMATIVE_EXTENSION) {
+                modelOperation.deleteModel(modelOptional.get(), false);
+            }
+            toscaOperationFacade.commitAndCheck(service.getUniqueId());
+            updateCatalog(service, ChangeTypeEnum.DELETE);
+        } catch (ComponentException exception) {
+            log.debug("Failed to delete service, {}, in ServiceServlet", serviceId);
+            janusGraphDao.rollback();
+            throw exception;
+        }
+    }
+
+    public ResponseFormat markServiceForDeletion(String serviceId, User user) {
         ResponseFormat responseFormat;
         validateUserExists(user);
         Either<Service, StorageOperationStatus> serviceStatus = toscaOperationFacade.getToscaElement(serviceId);