Implement 'Update Service by importing Tosca Template'-story
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ServiceBusinessLogic.java
index 2cccc31..9874020 100644 (file)
@@ -19,6 +19,7 @@
  * Modifications copyright (c) 2019 Nokia
  * ================================================================================
  */
+
 package org.openecomp.sdc.be.components.impl;
 
 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
@@ -45,6 +46,7 @@ import java.util.Comparator;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
@@ -53,6 +55,8 @@ import java.util.function.Function;
 import java.util.stream.Collectors;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
 import lombok.Getter;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
@@ -67,6 +71,7 @@ import org.openecomp.sdc.be.components.health.HealthCheckBusinessLogic;
 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
+import org.openecomp.sdc.be.components.kafka.KafkaHandler;
 import org.openecomp.sdc.be.components.path.ForwardingPathValidator;
 import org.openecomp.sdc.be.components.utils.InterfaceOperationUtils;
 import org.openecomp.sdc.be.components.utils.PropertiesUtils;
@@ -97,6 +102,10 @@ import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
 import org.openecomp.sdc.be.datatypes.elements.OperationOutputDefinition;
+import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.ToscaFunction;
+import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType;
+import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentFieldsEnum;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
@@ -170,7 +179,7 @@ import org.springframework.web.context.WebApplicationContext;
 @org.springframework.stereotype.Component("serviceBusinessLogic")
 public class ServiceBusinessLogic extends ComponentBusinessLogic {
 
-    static final String IS_VALID = "isValid";
+    private static final String IS_VALID = "isValid";
     private static final String THE_SERVICE_WITH_SYSTEM_NAME_LOCKED = "The service with system name {} locked. ";
     private static final String FAILED_TO_LOCK_SERVICE_RESPONSE_IS = "Failed to lock service {}. Response is {}. ";
     private static final String AUDIT_BEFORE_SENDING_RESPONSE = "audit before sending response";
@@ -189,8 +198,8 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
     private final ServiceInstantiationTypeValidator serviceInstantiationTypeValidator;
     private final ServiceCategoryValidator serviceCategoryValidator;
     private final ServiceValidator serviceValidator;
-    private final PolicyBusinessLogic policyBusinessLogic;
     private final GroupBusinessLogic groupBusinessLogic;
+    private final KafkaHandler kafkaHandler;
     private ForwardingPathOperation forwardingPathOperation;
     private AuditCassandraDao auditCassandraDao;
     private ServiceTypeValidator serviceTypeValidator;
@@ -210,7 +219,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
                                 final ServiceRoleValidator serviceRoleValidator,
                                 final ServiceInstantiationTypeValidator serviceInstantiationTypeValidator,
                                 final ServiceCategoryValidator serviceCategoryValidator, final ServiceValidator serviceValidator,
-                                final PolicyBusinessLogic policyBusinessLogic) {
+                                KafkaHandler kafkaHandler) {
         super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, groupBusinessLogic, interfaceOperation,
             interfaceLifecycleTypeOperation, artifactsBusinessLogic, artifactToscaOperation, componentContactIdValidator, componentNameValidator,
             componentTagsValidator, componentValidator, componentIconValidator, componentProjectCodeValidator, componentDescriptionValidator);
@@ -224,8 +233,8 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         this.serviceInstantiationTypeValidator = serviceInstantiationTypeValidator;
         this.serviceCategoryValidator = serviceCategoryValidator;
         this.serviceValidator = serviceValidator;
-        this.policyBusinessLogic = policyBusinessLogic;
         this.groupBusinessLogic = groupBusinessLogic;
+        this.kafkaHandler = kafkaHandler;
     }
 
     @Autowired
@@ -668,7 +677,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         validateUserRole(user, service, new ArrayList<>(), AuditingActionEnum.CREATE_RESOURCE, null);
         service.setCreatorUserId(user.getUserId());
         // warn on overridden fields
-        checkFieldsForOverideAttampt(service);
+        checkFieldsForOverideAttempt(service);
         // enrich object
         log.debug("enrich service with version and state");
         service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
@@ -683,7 +692,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         return createServiceByDao(service, user).left().bind(c -> updateCatalog(c, ChangeTypeEnum.LIFECYCLE).left().map(Service.class::cast));
     }
 
-    private void checkFieldsForOverideAttampt(Service service) {
+    private void checkFieldsForOverideAttempt(Service service) {
         checkComponentFieldsForOverrideAttempt(service);
         if (service.getDistributionStatus() != null) {
             log.info("Distribution Status cannot be defined by user. This field will be overridden by the application");
@@ -707,7 +716,9 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
             if (service.isSubstituteCandidate() || genericTypeBusinessLogic.hasMandatorySubstitutionType(service)) {
                 final Resource genericType = fetchAndSetDerivedFromGenericType(service);
                 generatePropertiesFromGenericType(service, genericType);
-                generateAndAddInputsFromGenericTypeProperties(service, genericType);
+                if (Constants.DEFAULT_MODEL_NAME.equals(service.getModel()) || service.getModel() == null) {
+                    generateAndAddInputsFromGenericTypeProperties(service, genericType);
+                }
             }
             beforeCreate(service);
             Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service);
@@ -718,6 +729,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
                 ASDCKpiApi.countCreatedServicesKPI();
                 return Either.left(dataModelResponse.left().value());
             }
+            janusGraphDao.rollback();
             ResponseFormat responseFormat = componentsUtils
                 .getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service,
                     ComponentTypeEnum.SERVICE);
@@ -788,13 +800,13 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
             componentsUtils.auditComponentAdmin(responseFormat, user, service, AuditingActionEnum.CREATE_SERVICE, ComponentTypeEnum.SERVICE);
             throw exp;
         }
-        service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
-        service.setContactId(service.getContactId().toLowerCase());
-        // Generate invariant UUID - must be here and not in operation since it
-
-        // should stay constant during clone
-        String invariantUUID = UniqueIdBuilder.buildInvariantUUID();
-        service.setInvariantUUID(invariantUUID);
+        if (!AuditingActionEnum.UPDATE_SERVICE_TOSCA_TEMPLATE.equals(actionEnum) &&
+            !AuditingActionEnum.UPDATE_SERVICE_TOSCA_MODEL.equals(actionEnum)) {
+            service.setCreatorFullName(user.getFirstName() + " " + user.getLastName());
+            service.setContactId(service.getContactId().toLowerCase());
+            // Generate invariant UUID - must be here and not in operation since it should stay constant during clone
+            service.setInvariantUUID(UniqueIdBuilder.buildInvariantUUID());
+        }
         return Either.left(service);
     }
 
@@ -846,21 +858,42 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
             log.info("Restricted operation for user: {}, on service: {}", user.getUserId(), currentService.getCreatorUserId());
             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
         }
-        Either<Service, ResponseFormat> validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate);
-        if (validationRsponse.isRight()) {
+        List<String> subNodePropsToBeRemoved = getSubstitutionNodePropertiesToBeRemoved(currentService, serviceUpdate);
+        List<PropertyDefinition> subNodePropsToBeAdded = getSubstitutionNodePropertiesToBeAdded(currentService, serviceUpdate);
+        boolean subNodeChanged = isSubstitutionNodeChanged(currentService, serviceUpdate);
+        Either<Service, ResponseFormat> validationResponse =
+            validateAndUpdateServiceMetadata(user, currentService, serviceUpdate, subNodeChanged, ListUtils.emptyIfNull(subNodePropsToBeRemoved));
+        if (validationResponse.isRight()) {
             log.info("service update metadata: validations field.");
-            return validationRsponse;
+            return validationResponse;
         }
-        Service serviceToUpdate = validationRsponse.left().value();
+        Service serviceToUpdate = validationResponse.left().value();
         // lock resource
         lockComponent(serviceId, currentService, "Update Service Metadata");
         try {
+            if (subNodeChanged) {
+                if (!subNodePropsToBeRemoved.isEmpty()) {
+                    removePropertiesFromService(currentService, subNodePropsToBeRemoved);
+                    removeInputsFromService(currentService, subNodePropsToBeRemoved);
+                }
+                if (!subNodePropsToBeAdded.isEmpty()) {
+                    addPropertiesToService(currentService, subNodePropsToBeAdded);
+                    if (Constants.DEFAULT_MODEL_NAME.equals(currentService.getModel()) || currentService.getModel() == null) {
+                        addInputsToService(currentService, subNodePropsToBeAdded);
+                    }
+                }
+            }
             return toscaOperationFacade.updateToscaElement(serviceToUpdate).right().map(rf -> {
                 janusGraphDao.rollback();
                 BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
                 log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
                 return (componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
             }).left().bind(this::updateCatalogAndCommit);
+        } catch (ComponentException e) {
+            janusGraphDao.rollback();
+            BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata");
+            log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId());
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
         } finally {
             graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service);
         }
@@ -1031,9 +1064,18 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
     }
 
     @VisibleForTesting
-    Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) {
+    Either<Service, ResponseFormat> validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate, boolean subNodeChanged,
+                                                                     List<String> subNodePropsToBeRemoved) {
         try {
             boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion());
+            if (subNodeChanged) {
+                if (!subNodePropsToBeRemoved.isEmpty()) {
+                    areSubstitutionNodePropertiesInUse(currentService, subNodePropsToBeRemoved);
+                }
+                currentService.setDerivedFromGenericVersion(serviceUpdate.getDerivedFromGenericVersion());
+                currentService.setDerivedFromGenericType(serviceUpdate.getDerivedFromGenericType());
+            }
+
             Either<Boolean, ResponseFormat> response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified,
                 UPDATE_SERVICE_METADATA);
             if (response.isRight()) {
@@ -1100,6 +1142,168 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         }
     }
 
+    private void addPropertiesToService(Service currentService, List<PropertyDefinition> subNodePropsToBeAdded) {
+        ListUtils.emptyIfNull(subNodePropsToBeAdded).forEach(prop -> {
+            Either<PropertyDefinition, StorageOperationStatus> addPropertyEither =
+                toscaOperationFacade.addPropertyToComponent(prop, currentService);
+            if (addPropertyEither.isRight()) {
+                throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
+            }
+        });
+    }
+
+    private void addInputsToService(Service currentService, List<PropertyDefinition> subNodePropsToBeAdded) {
+        ListUtils.emptyIfNull(subNodePropsToBeAdded).forEach(prop -> {
+            InputDefinition inputDef = new InputDefinition(prop);
+            Either<InputDefinition, StorageOperationStatus> status =
+                toscaOperationFacade.addInputToComponent(prop.getName(), inputDef, currentService);
+            if (status.isRight()) {
+                throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
+            }
+        });
+    }
+
+    private void removePropertiesFromService(Service currentService, List<String> subNodePropsToBeRemoved) {
+        List<PropertyDefinition> props = currentService.getProperties();
+        List<String> propsUniqueIdsToBeRemoved =
+            props.stream().filter(prop -> subNodePropsToBeRemoved.contains(prop.getName())).map(PropertyDefinition::getUniqueId)
+                .collect(Collectors.toList());
+        ListUtils.emptyIfNull(props).stream().filter(prop -> propsUniqueIdsToBeRemoved.contains(prop.getUniqueId())).forEach(prop -> {
+            StorageOperationStatus status = toscaOperationFacade.deletePropertyOfComponent(currentService, prop.getName());
+            if (status != StorageOperationStatus.OK) {
+                throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
+            }
+        });
+    }
+
+    private void removeInputsFromService(Service currentService, List<String> subNodePropsToBeRemoved) {
+        List<PropertyDefinition> props = currentService.getProperties();
+        List<InputDefinition> inputs = currentService.getInputs();
+        List<String> propsUniqueIdsToBeRemoved =
+            props.stream().filter(prop -> subNodePropsToBeRemoved.contains(prop.getName())).map(PropertyDefinition::getUniqueId)
+                .collect(Collectors.toList());
+        ListUtils.emptyIfNull(inputs).stream().filter(input -> input.isMappedToComponentProperty() &&
+            (propsUniqueIdsToBeRemoved.contains(input.getPropertyId()) || subNodePropsToBeRemoved.contains(input.getName()))).forEach(input -> {
+            StorageOperationStatus status = toscaOperationFacade.deleteInputOfResource(currentService, input.getName());
+            if (status != StorageOperationStatus.OK) {
+                throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR);
+            }
+        });
+    }
+
+    private void areSubstitutionNodePropertiesInUse(Service service, List<String> subNodePropsToBeRemoved) {
+        Map<String, List<ComponentInstanceProperty>> componentInstancesProps = service.getComponentInstancesProperties();
+        List<String> propsUniqueIdsToBeRemoved =
+            ListUtils.emptyIfNull(service.getProperties()).stream().filter(prop -> subNodePropsToBeRemoved.contains(prop.getName()))
+                .map(PropertyDefinition::getUniqueId)
+                .collect(Collectors.toList());
+        List<String> inputsUniqueIdsToBeRemoved = ListUtils.emptyIfNull(service.getInputs()).stream()
+            .filter(input -> propsUniqueIdsToBeRemoved.contains(input.getPropertyId()) || subNodePropsToBeRemoved.contains(input.getName()))
+            .map(PropertyDefinition::getUniqueId)
+            .collect(Collectors.toList());
+        Map<String, List<String>> inUse = new HashMap<>();
+        if (componentInstancesProps != null && !componentInstancesProps.isEmpty()) {
+            componentInstancesProps.forEach((compInstanceId, listOfProps) -> {
+                List<String> propsInUse = new ArrayList<>();
+                listOfProps.stream()
+                    .filter(PropertyDataDefinition::isToscaFunction)
+                    .filter(compProp -> ToscaFunctionType.isGetFunction(compProp.getToscaFunction().getType()))
+                    .forEach(compProp -> {
+                        ToscaFunction toscaFunction = compProp.getToscaFunction();
+                        ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) toscaFunction;
+                        String propName = toscaGetFunction.getPropertyName();
+                        String propUniqueId = toscaGetFunction.getPropertyUniqueId();
+                        if (inputsUniqueIdsToBeRemoved.contains(propUniqueId) || propsUniqueIdsToBeRemoved.contains(propUniqueId) ||
+                            subNodePropsToBeRemoved.contains(propName)) {
+                            propsInUse.add(compProp.getName());
+                        }
+                    });
+                if (!propsInUse.isEmpty()) {
+                    Optional<ComponentInstance> componentInstance = service.getComponentInstanceById(compInstanceId);
+                    componentInstance.ifPresent(instance -> inUse.put(instance.getName(), propsInUse));
+                }
+
+            });
+        }
+        if (!inUse.isEmpty()) {
+            String propsInUse = inUse.entrySet().stream().map(entry -> {
+                String properties = entry.getValue().stream().map(Object::toString).collect(Collectors.joining(", "));
+                return properties + " on " + entry.getKey();
+            }).collect(Collectors.joining(", properties "));
+            throw new ByActionStatusComponentException(ActionStatus.SUBSTITUTION_NODE_TYPE_PROPERTY_IN_USE, propsInUse);
+        }
+    }
+
+
+    private boolean isSubstitutionNodeChanged(Service currentService, Service updatedService) {
+        String currentServiceType = currentService.getDerivedFromGenericType();
+        String updatedServiceType = updatedService.getDerivedFromGenericType();
+        String currentServiceVersion = currentService.getDerivedFromGenericVersion();
+        String updatedServiceVersion = updatedService.getDerivedFromGenericVersion();
+        return !(StringUtils.equals(currentServiceType, updatedServiceType) && StringUtils.equals(currentServiceVersion, updatedServiceVersion));
+    }
+
+    private List<String> getSubstitutionNodePropertiesToBeRemoved(Service currentService, Service serviceUpdate) {
+        List<PropertyDefinition> currentProps = ListUtils.emptyIfNull(fetchDerivedFromGenericType(currentService, null).getProperties());
+        List<PropertyDefinition> updatedProps = ListUtils.emptyIfNull(fetchDerivedFromGenericType(serviceUpdate, null).getProperties());
+        if (!StringUtils.equals(currentService.getDerivedFromGenericType(), serviceUpdate.getDerivedFromGenericType())) {
+            return currentProps.stream().map(PropertyDefinition::getName).collect(Collectors.toList());
+        }
+
+        Map<String, PropertyDefinition> currentPropsMap = currentProps.stream().collect(Collectors.toMap(prop -> prop.getName(), prop -> prop));
+        Map<String, PropertyDefinition> updatedPropsMap = updatedProps.stream().collect(Collectors.toMap(prop -> prop.getName(), prop -> prop));
+
+        List<String> propNamesToBeRemoved = new ArrayList<>();
+        for (String currentPropertyName : currentPropsMap.keySet()) {
+            if (updatedPropsMap.containsKey(currentPropertyName)) {
+                if (!haveSameType(currentPropsMap.get(currentPropertyName), updatedPropsMap.get(currentPropertyName))) {
+                    propNamesToBeRemoved.add(currentPropertyName);
+                }
+            } else {
+                propNamesToBeRemoved.add(currentPropertyName);
+            }
+        }
+
+        return propNamesToBeRemoved;
+    }
+
+    private boolean haveSameType(final PropertyDefinition property1, final PropertyDefinition property2) {
+        if (property1.getType().equals("list")) {
+            return property2.getType().equals("list") && property1.getSchema().equals(property2.getSchema());
+        }
+        if (property1.getType().equals("map")) {
+            return property2.getType().equals("map") && property1.getSchema().equals(property2.getSchema());
+        }
+        return property1.getType().equals(property2.getType());
+    }
+
+    private List<PropertyDefinition> getSubstitutionNodePropertiesToBeAdded(Service currentService, Service serviceUpdate) {
+        List<PropertyDefinition> propsInCurrentVersion = ListUtils.emptyIfNull(fetchDerivedFromGenericType(currentService, null).getProperties());
+        List<PropertyDefinition> propsInUpdatedVersion = ListUtils.emptyIfNull(fetchDerivedFromGenericType(serviceUpdate, null).getProperties());
+        if (!StringUtils.equals(currentService.getDerivedFromGenericType(), serviceUpdate.getDerivedFromGenericType())) {
+            return propsInUpdatedVersion;
+        }
+
+        Map<String, PropertyDefinition> mapOfPropsInCurrentVersion = propsInCurrentVersion.stream()
+            .collect(Collectors.toMap(prop -> prop.getName(), prop -> prop));
+        Map<String, PropertyDefinition> mapOfPropsInUpdatedVersion = propsInUpdatedVersion.stream()
+            .collect(Collectors.toMap(prop -> prop.getName(), prop -> prop));
+
+        List<PropertyDefinition> propsToBeAdded = new ArrayList<>();
+        for (Entry<String, PropertyDefinition> propertyInUpdatedVersion : mapOfPropsInUpdatedVersion.entrySet()) {
+            if (mapOfPropsInCurrentVersion.containsKey(propertyInUpdatedVersion.getKey())) {
+                if (!haveSameType(mapOfPropsInCurrentVersion.get(propertyInUpdatedVersion.getKey()), propertyInUpdatedVersion.getValue())) {
+                    propsToBeAdded.add(propertyInUpdatedVersion.getValue());
+                }
+            } else {
+                propsToBeAdded.add(propertyInUpdatedVersion.getValue());
+            }
+        }
+
+        return propsToBeAdded;
+    }
+
+
     private void verifyValuesAreIdentical(Object updatedValue, Object originalValue, String fieldName) {
         if (updatedValue != null && !updatedValue.equals(originalValue)) {
             log.info("update service: received request to update {} to {} the field is not updatable ignoring.", fieldName, updatedValue);
@@ -1534,14 +1738,16 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
             log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName);
             envName = configuredEnvName;
         }
-        // DE194021
-        ServletContext servletContext = request.getSession().getServletContext();
-        boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
-        if (!isDistributionEngineUp) {
-            BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
-            log.debug("Distribution Engine is DOWN");
-            response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
-            return Either.right(response);
+        if (!kafkaHandler.isKafkaActive()) {
+            // DE194021
+            ServletContext servletContext = request.getSession().getServletContext();
+            boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(); // DE
+            if (!isDistributionEngineUp) {
+                BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN");
+                log.debug("Distribution Engine is DOWN");
+                response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR);
+                return Either.right(response);
+            }
         }
         Either<Service, StorageOperationStatus> serviceRes = toscaOperationFacade.getToscaElement(serviceId);
         if (serviceRes.isRight()) {
@@ -2113,7 +2319,8 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         }
         Service service = serviceResultEither.left().value();
         if (dataParamsToReturn.contains(ComponentFieldsEnum.INPUTS.getValue())) {
-            ListUtils.emptyIfNull(service.getInputs()).forEach(input -> input.setConstraints(setInputConstraint(input)));
+            ListUtils.emptyIfNull(service.getInputs()).stream().filter(input -> CollectionUtils.isEmpty(input.getConstraints()))
+                .forEach(input -> input.setConstraints(setInputConstraint(input)));
         }
         UiComponentDataTransfer dataTransfer = uiComponentDataConverter.getUiDataTransferFromServiceByParams(service, dataParamsToReturn);
         return Either.left(dataTransfer);
@@ -2125,8 +2332,7 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
     }
 
     public boolean isServiceExist(String serviceName) {
-        Either<Service, StorageOperationStatus> latestByName = toscaOperationFacade.getLatestByServiceName(serviceName);
-        return latestByName.isLeft();
+        return toscaOperationFacade.getLatestByServiceName(serviceName).isLeft();
     }
 
     interface ArtifactGenerator<CallVal> extends Callable<Either<CallVal, ResponseFormat>> {
@@ -2134,26 +2340,16 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
     }
 
     @Getter
+    @AllArgsConstructor(access = AccessLevel.PRIVATE)
     class HeatEnvArtifactGenerator implements ArtifactGenerator<ArtifactDefinition> {
 
         private ArtifactDefinition artifactDefinition;
         private Service service;
         private String resourceInstanceName;
         private User modifier;
-        private String instanceId;
         private boolean shouldLock;
         private boolean inTransaction;
-
-        HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier,
-                                 boolean shouldLock, boolean inTransaction, String instanceId) {
-            this.artifactDefinition = artifactDefinition;
-            this.service = service;
-            this.resourceInstanceName = resourceInstanceName;
-            this.modifier = modifier;
-            this.shouldLock = shouldLock;
-            this.instanceId = instanceId;
-            this.inTransaction = inTransaction;
-        }
+        private String instanceId;
 
         @Override
         public Either<ArtifactDefinition, ResponseFormat> call() throws Exception {
@@ -2163,23 +2359,14 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         }
     }
 
+    @AllArgsConstructor(access = AccessLevel.PRIVATE)
     class VfModuleArtifactGenerator implements ArtifactGenerator<ArtifactDefinition> {
 
-        boolean shouldLock;
-        boolean inTransaction;
         private User user;
         private ComponentInstance componentInstance;
         private Service service;
-
-        private VfModuleArtifactGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock,
-                                          boolean inTransaction) {
-            super();
-            this.user = user;
-            this.componentInstance = componentInstance;
-            this.service = service;
-            this.shouldLock = shouldLock;
-            this.inTransaction = inTransaction;
-        }
+        private boolean shouldLock;
+        private boolean inTransaction;
 
         private Either<ArtifactDefinition, ResponseFormat> generateVfModuleInstanceArtifact(User modifier, ComponentInstance currVFInstance,
                                                                                             Service service, boolean shouldLock,
@@ -2198,13 +2385,11 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
                 vfModuleArtifact = fillVfModulePayload(modifier, currVFInstance, vfModuleArtifact, shouldLock, inTransaction, payloadWrapper,
                     responseWrapper, service);
             }
-            Either<ArtifactDefinition, ResponseFormat> result;
             if (responseWrapper.isEmpty()) {
-                result = Either.left(vfModuleArtifact);
+                return Either.left(vfModuleArtifact);
             } else {
-                result = Either.right(responseWrapper.getInnerElement());
+                return Either.right(responseWrapper.getInnerElement());
             }
-            return result;
         }
 
         private void fillVfModuleInstHeatEnvPayload(List<GroupInstance> groupsForCurrVF, Wrapper<String> payloadWrapper) {
@@ -2244,9 +2429,8 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
         }
 
         private List<GroupInstance> collectGroupsInstanceForCompInstance(ComponentInstance currVF) {
-            Map<String, ArtifactDefinition> deploymentArtifacts = currVF.getDeploymentArtifacts();
             if (currVF.getGroupInstances() != null) {
-                currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(deploymentArtifacts));
+                currVF.getGroupInstances().forEach(gi -> gi.alignArtifactsUuid(currVF.getDeploymentArtifacts()));
             }
             return currVF.getGroupInstances();
         }
@@ -2269,14 +2453,12 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic {
             vfModuleArtifactDefinition.setArtifactChecksum(newCheckSum);
             Either<ArtifactDefinition, StorageOperationStatus> addArtifactToComponent = artifactToscaOperation
                 .addArtifactToComponent(vfModuleArtifactDefinition, service, NodeTypeEnum.ResourceInstance, true, currVF.getUniqueId());
-            Either<ArtifactDefinition, ResponseFormat> result;
             if (addArtifactToComponent.isLeft()) {
-                result = Either.left(addArtifactToComponent.left().value());
+                return Either.left(addArtifactToComponent.left().value());
             } else {
-                result = Either
+                return Either
                     .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArtifactToComponent.right().value())));
             }
-            return result;
         }
 
         private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleArtifact,