Fix issues creating control loop model
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / ComponentInstanceBusinessLogic.java
index d0c72e5..ca4002f 100644 (file)
@@ -41,7 +41,7 @@ import java.util.UUID;
 import java.util.stream.Collectors;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException;
 import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException;
@@ -74,11 +74,13 @@ import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
 import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType;
+import org.openecomp.sdc.be.exception.BusinessException;
 import org.openecomp.sdc.be.impl.ComponentsUtils;
 import org.openecomp.sdc.be.impl.ForwardingPathUtils;
 import org.openecomp.sdc.be.impl.ServiceFilterUtils;
 import org.openecomp.sdc.be.info.CreateAndAssotiateInfo;
 import org.openecomp.sdc.be.model.ArtifactDefinition;
+import org.openecomp.sdc.be.model.AttributeDefinition;
 import org.openecomp.sdc.be.model.CapabilityDefinition;
 import org.openecomp.sdc.be.model.Component;
 import org.openecomp.sdc.be.model.ComponentInstance;
@@ -107,6 +109,7 @@ import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations;
 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ForwardingPathOperation;
 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation;
 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeFilterOperation;
+import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeTemplateOperation;
 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
 import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter;
 import org.openecomp.sdc.be.model.operations.StorageException;
@@ -129,6 +132,8 @@ import org.openecomp.sdc.common.api.Constants;
 import org.openecomp.sdc.common.datastructure.Wrapper;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
+import org.openecomp.sdc.common.log.elements.ErrorLogOptionalData;
+import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
 import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.ValidationUtils;
 import org.openecomp.sdc.exception.ResponseFormat;
@@ -152,8 +157,18 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
     private static final String FAILED_TO_COPY_COMP_INSTANCE_TO_CANVAS = "Failed to copy the component instance to the canvas";
     private static final String COPY_COMPONENT_INSTANCE_OK = "Copy component instance OK";
     private static final String CANNOT_ATTACH_RESOURCE_INSTANCES_TO_CONTAINER_RESOURCE_OF_TYPE = "Cannot attach resource instances to container resource of type {}";
+    private static final String FAILED_TO_UPDATE_COMPONENT_INSTANCE_CAPABILITY = "Failed to update component instance capability on instance {} in "
+        + "container {}";
     private static final String SERVICE_PROXY = "serviceProxy";
     private static final String ASSOCIATE_RI_TO_RI = "associateRIToRI";
+    private static final String COMPONENT_ARCHIVED = "Component is archived. Component id: {}";
+    private static final String RESTRICTED_OPERATION_ON_SERVIVE = "Restricted operation for user: {} on service {}";
+    private static final String FAILED_TO_LOCK_COMPONENT = "Failed to lock component {}";
+    private static final String RESTRICTED_OPERATION_ON_COMPONENT = "Restricted operation for user: {} on component {}";
+    private static final String RESOURCE_INSTANCE = "resource instance";
+    private static final String SERVICE = "service";
+    private static final String UPDATE_PROPERTY_CONTEXT = "UpdatePropertyValueOnComponentInstance";
+
     private ComponentInstanceOperation componentInstanceOperation;
     private ArtifactsBusinessLogic artifactBusinessLogic;
     private ComponentInstanceMergeDataBusinessLogic compInstMergeDataBL;
@@ -410,7 +425,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
     }
 
     private Component getOrigComponentForServiceProxy(org.openecomp.sdc.be.model.Component containerComponent, ComponentInstance resourceInstance) {
-        Either<Component, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade.getLatestByName(SERVICE_PROXY);
+        Either<Component, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade.getLatestByName(SERVICE_PROXY, null);
         if (isServiceProxyOrigin(serviceProxyOrigin)) {
             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(serviceProxyOrigin.right().value()));
         }
@@ -431,7 +446,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         }
         final Component service = getServiceResult.left().value();
         final Either<Component, StorageOperationStatus> getServiceDerivedFromTypeResult = toscaOperationFacade
-            .getLatestByToscaResourceName(service.getDerivedFromGenericType());
+            .getLatestByToscaResourceName(service.getDerivedFromGenericType(), service.getModel());
         if (getServiceDerivedFromTypeResult.isRight()) {
             throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getServiceResult.right().value()));
         }
@@ -512,7 +527,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
                 validateInstanceName(resourceInstance);
                 if (originType == OriginTypeEnum.ServiceProxy) {
                     log.debug("enter createRealComponentInstance,originType equals ServiceProxy");
-                    Either<Component, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade.getLatestByName(SERVICE_PROXY);
+                    Either<Component, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade.getLatestByName(SERVICE_PROXY, null);
                     if (isServiceProxyOrigin(serviceProxyOrigin)) {
                         throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(serviceProxyOrigin.right().value()));
                     }
@@ -622,7 +637,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
     private void validateOriginComponentIsValidForContainer(Component containerComponent, ResourceTypeEnum resourceType) {
         switch (containerComponent.getComponentType()) {
             case SERVICE:
-                if (!containerInstanceTypesData.isAllowedForServiceComponent(resourceType)) {
+                if (!containerInstanceTypesData.isAllowedForServiceComponent(resourceType, containerComponent.getModel())) {
                     throw new ByActionStatusComponentException(ActionStatus.CONTAINER_CANNOT_CONTAIN_INSTANCE,
                         containerComponent.getComponentType().toString(), resourceType.name());
                 }
@@ -997,7 +1012,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND, componentInstance.getName(),
                 instanceType.getValue().toLowerCase());
         }
-        if (!validateParentStatus.left().value()) {
+        if (!Boolean.TRUE.equals(validateParentStatus.left().value())) {
             throw new ByActionStatusComponentException(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstance.getName(),
                 instanceType.getValue().toLowerCase(), containerComponentType.getValue().toLowerCase(), containerComponentId);
         }
@@ -1062,7 +1077,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
                         ComponentInstance updatedCi = op.get();
                         updatedCi = buildComponentInstance(updatedCi, origInst);
                         Boolean isUniqueName = validateInstanceNameUniquenessUponUpdate(containerComponent, origInst, updatedCi.getName());
-                        if (!isUniqueName) {
+                        if (!Boolean.TRUE.equals(isUniqueName)) {
                             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
                                 "Failed to update the name of the component instance {} to {}. A component instance with the same name already exists. ",
                                 origInst.getName(), updatedCi.getName());
@@ -1137,7 +1152,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
             isNameChanged = true;
         }
         Boolean isUniqueName = validateInstanceNameUniquenessUponUpdate(containerComponent, oldComponentInstance, newInstanceName);
-        if (!isUniqueName) {
+        if (!Boolean.TRUE.equals(isUniqueName)) {
             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
                 "Failed to update the name of the component instance {} to {}. A component instance with the same name already exists. ",
                 oldComponentInstance.getName(), newInstanceName);
@@ -1911,18 +1926,18 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         Component containerComponent = getResourceResult.left().value();
 
         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
-            if (containerComponent.isArchived()) {
-                log.info("Component is archived. Component id: {}", componentId);
+            if (Boolean.TRUE.equals(containerComponent.isArchived())) {
+                log.info(COMPONENT_ARCHIVED, componentId);
                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, containerComponent.getName()));
             }
-            log.info("Restricted operation for user: {} on service {}", userId, componentId);
+            log.info(RESTRICTED_OPERATION_ON_SERVIVE, userId, componentId);
             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
         }
 
         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent, resourceInstanceId);
         if (resourceInstanceStatus.isRight()) {
             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER,
-                resourceInstanceId, "resource instance", "service", componentId));
+                resourceInstanceId, RESOURCE_INSTANCE, SERVICE, componentId));
         }
         ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
 
@@ -1939,7 +1954,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
                 ComponentInstanceProperty componentInstanceProperty = validatePropertyExistsOnComponent(property, containerComponent,
                     foundResourceInstance);
                 String propertyParentUniqueId = property.getParentUniqueId();
-                Either<String, ResponseFormat> updatedPropertyValue = updatePropertyObjectValue(property, false);
+                Either<String, ResponseFormat> updatedPropertyValue = updatePropertyObjectValue(property, false, containerComponent.getModel());
                 if (updatedPropertyValue.isRight()) {
                     log.error("Failed to update property object value of property: {}",
                         property);
@@ -1986,6 +2001,96 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         }
     }
 
+    public Either<List<ComponentInstanceAttribute>, ResponseFormat> createOrUpdateAttributeValues(final ComponentTypeEnum componentTypeEnum,
+                                                                                                  final String componentId,
+                                                                                                  final String resourceInstanceId,
+                                                                                                  final List<ComponentInstanceAttribute> attributes,
+                                                                                                  final String userId) {
+        Either<List<ComponentInstanceAttribute>, ResponseFormat> resultOp = null;
+        /*-------------------------------Validations---------------------------------*/
+        validateUserExists(userId);
+
+        if (componentTypeEnum == null) {
+            BeEcompErrorManager.getInstance().logInvalidInputError("CreateOrUpdatePropertiesValues", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
+            resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
+            return resultOp;
+        }
+        final Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade
+            .getToscaElement(componentId, JsonParseFlagEnum.ParseAll);
+
+        if (getResourceResult.isRight()) {
+            log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, componentId);
+            final ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(getResourceResult.right().value(), componentTypeEnum);
+            return Either.right(componentsUtils.getResponseFormat(actionStatus, componentId));
+        }
+        final Component containerComponent = getResourceResult.left().value();
+
+        if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
+            if (Boolean.TRUE.equals(containerComponent.isArchived())) {
+                log.info(COMPONENT_ARCHIVED, componentId);
+                return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, containerComponent.getName()));
+            }
+            log.info(RESTRICTED_OPERATION_ON_SERVIVE, userId, componentId);
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
+        }
+
+        final Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent,
+            resourceInstanceId);
+        if (resourceInstanceStatus.isRight()) {
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER,
+                resourceInstanceId, RESOURCE_INSTANCE, SERVICE, componentId));
+        }
+        final ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
+
+        // lock resource
+        final StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType());
+        if (lockStatus != StorageOperationStatus.OK) {
+            log.debug(FAILED_TO_LOCK_SERVICE, componentId);
+            return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
+        }
+        final List<ComponentInstanceAttribute> updatedProperties = new ArrayList<>();
+        try {
+            for (final ComponentInstanceAttribute attribute : attributes) {
+                final ComponentInstanceAttribute componentInstanceProperty = validateAttributeExistsOnComponent(attribute, containerComponent,
+                    foundResourceInstance);
+                final Either<String, ResponseFormat> updatedPropertyValue = updateAttributeObjectValue(attribute);
+                if (updatedPropertyValue.isRight()) {
+                    log.error("Failed to update attribute object value of attribute: {}", attribute);
+                    throw new ByResponseFormatComponentException(updatedPropertyValue.right().value());
+                }
+                updatedPropertyValue.bimap(
+                    updatedValue -> {
+                        componentInstanceProperty.setValue(updatedValue);
+                        return updateAttributeOnContainerComponent(attribute, updatedValue,
+                            containerComponent, foundResourceInstance);
+                    }, Either::right);
+                updatedProperties.add(componentInstanceProperty);
+            }
+
+            final Either<Component, StorageOperationStatus> updateContainerRes = toscaOperationFacade
+                .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
+            if (updateContainerRes.isRight()) {
+                final ActionStatus actionStatus = componentsUtils
+                    .convertFromStorageResponseForResourceInstanceProperty(updateContainerRes.right().value());
+                resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, ""));
+                return resultOp;
+            }
+            resultOp = Either.left(updatedProperties);
+            return resultOp;
+
+        } catch (final ComponentException e) {
+            return Either.right(e.getResponseFormat());
+        } finally {
+            if (resultOp == null || resultOp.isRight()) {
+                janusGraphDao.rollback();
+            } else {
+                janusGraphDao.commit();
+            }
+            // unlock resource
+            graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType());
+        }
+    }
+
     private void validateMandatoryFields(PropertyDataDefinition property) {
         if (StringUtils.isEmpty(property.getName())) {
             throw new ByActionStatusComponentException(ActionStatus.MISSING_PROPERTY_NAME);
@@ -2004,6 +2109,19 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         return instanceProperty.get();
     }
 
+    private ComponentInstanceAttribute validateAttributeExistsOnComponent(final ComponentInstanceAttribute attribute,
+                                                                          final Component containerComponent,
+                                                                          final ComponentInstance foundResourceInstance) {
+        final List<ComponentInstanceAttribute> instanceProperties =
+            containerComponent.getComponentInstancesAttributes().get(foundResourceInstance.getUniqueId());
+        final Optional<ComponentInstanceAttribute> instanceAttribute =
+            instanceProperties.stream().filter(p -> p.getName().equals(attribute.getName())).findAny();
+        if (!instanceAttribute.isPresent()) {
+            throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, attribute.getName());
+        }
+        return instanceAttribute.get();
+    }
+
     private ResponseFormat updateCapabilityPropertyOnContainerComponent(ComponentInstanceProperty property,
                                                                         String newValue, Component containerComponent,
                                                                         ComponentInstance foundResourceInstance,
@@ -2092,17 +2210,24 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         return componentsUtils.getResponseFormat(ActionStatus.OK);
     }
 
-    private <T extends PropertyDefinition> Either<String, ResponseFormat> validatePropertyObjectValue(T property, String newValue, boolean isInput) {
-        Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypesEither = dataTypeCache.getAll();
-        if (allDataTypesEither.isRight()) {
-            JanusGraphOperationStatus status = allDataTypesEither.right().value();
-            BeEcompErrorManager.getInstance()
-                .logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status,
-                    ErrorSeverity.ERROR);
-            return Either.right(componentsUtils
-                .getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status))));
+    private ResponseFormat updateAttributeOnContainerComponent(final ComponentInstanceAttribute instanceAttribute,
+                                                               final String newValue,
+                                                               final Component containerComponent,
+                                                               final ComponentInstance foundResourceInstance) {
+
+        instanceAttribute.setValue(newValue);
+        final StorageOperationStatus status =
+            toscaOperationFacade.updateComponentInstanceAttribute(containerComponent, foundResourceInstance.getUniqueId(), instanceAttribute);
+        if (status != StorageOperationStatus.OK) {
+            final ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status);
+            return componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "");
         }
-        Map<String, DataTypeDefinition> allDataTypes = allDataTypesEither.left().value();
+        foundResourceInstance.setCustomizationUUID(UUID.randomUUID().toString());
+        return componentsUtils.getResponseFormat(ActionStatus.OK);
+    }
+
+    private <T extends PropertyDefinition> Either<String, ResponseFormat> validatePropertyObjectValue(T property, String newValue, boolean isInput) {
+        final Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, property.getModel());
         String propertyType = property.getType();
         String innerType = getInnerType(property);
 
@@ -2110,8 +2235,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         Either<Object, Boolean> isValid = propertyOperation
             .validateAndUpdatePropertyValue(property.getType(), newValue, true, innerType, allDataTypes);
         if (isValid.isRight()) {
-            Boolean res = isValid.right().value();
-            if (!res) {
+            if (!Boolean.TRUE.equals(isValid.right().value())) {
                 log.error("Invalid value {} of property {} ", newValue, property.getName());
                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT));
             }
@@ -2141,17 +2265,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         return false;
     }
 
-    private <T extends PropertyDefinition> Either<String, ResponseFormat> updatePropertyObjectValue(T property, boolean isInput) {
-        Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypesEither = dataTypeCache.getAll();
-        if (allDataTypesEither.isRight()) {
-            JanusGraphOperationStatus status = allDataTypesEither.right().value();
-            BeEcompErrorManager.getInstance()
-                .logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status,
-                    ErrorSeverity.ERROR);
-            return Either.right(componentsUtils
-                .getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status))));
-        }
-        Map<String, DataTypeDefinition> allDataTypes = allDataTypesEither.left().value();
+    private <T extends PropertyDefinition> Either<String, ResponseFormat> updatePropertyObjectValue(T property, boolean isInput, final String model) {
+        final Map<String, DataTypeDefinition> allDataTypes = componentsUtils.getAllDataTypes(applicationDataTypeCache, model);
         String innerType = null;
         String propertyType = property.getType();
         ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType);
@@ -2184,8 +2299,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         Either<Object, Boolean> isValid = propertyOperation
             .validateAndUpdatePropertyValue(propertyType, property.getValue(), true, innerType, allDataTypes);
         if (isValid.isRight()) {
-            Boolean res = isValid.right().value();
-            if (!res) {
+            if (!Boolean.TRUE.equals(isValid.right().value())) {
                 log.debug("validate and update property value has failed with value: {}", property.getValue());
                 throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(
                     DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)));
@@ -2199,7 +2313,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         if (!isInput) {
             ImmutablePair<String, Boolean> pair = propertyOperation
                 .validateAndUpdateRules(propertyType, ((ComponentInstanceProperty) property).getRules(), innerType, allDataTypes, true);
-            if (pair.getRight() != null && pair.getRight() == false) {
+            if (pair.getRight() != null && Boolean.FALSE.equals(pair.getRight())) {
                 BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), property.getName(), propertyType);
                 return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(
                     DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT))));
@@ -2208,6 +2322,49 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         return Either.left(newValue);
     }
 
+    private <T extends AttributeDefinition> Either<String, ResponseFormat> updateAttributeObjectValue(final T attribute) {
+        String innerType = null;
+        final String attributeType = attribute.getType();
+        final ToscaPropertyType type = ToscaPropertyType.isValidType(attributeType);
+        log.debug("The type of the attribute {} is {}", attribute.getUniqueId(), attributeType);
+
+        if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
+            final SchemaDefinition def = attribute.getSchema();
+            if (def == null) {
+                log.debug("Schema doesn't exists for attribute of type {}", type);
+                return Either
+                    .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
+            }
+            PropertyDataDefinition propDef = def.getProperty();
+            if (propDef == null) {
+                log.debug("Property in Schema Definition inside attribute of type {} doesn't exist", type);
+                return Either
+                    .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(StorageOperationStatus.INVALID_VALUE)));
+            }
+            innerType = propDef.getType();
+        }
+
+        // Specific Update Logic
+        String newValue = attribute.getValue();
+
+        final var isValid = attributeOperation.validateAndUpdateAttributeValue(attribute, innerType,
+            componentsUtils.getAllDataTypes(applicationDataTypeCache, attribute.getModel()));
+        if (isValid.isRight()) {
+            final Boolean res = isValid.right().value();
+            if (!Boolean.TRUE.equals(res)) {
+                log.debug("validate and update attribute value has failed with value: {}", newValue);
+                throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(
+                    DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT)));
+            }
+        } else {
+            final Object object = isValid.left().value();
+            if (object != null) {
+                newValue = object.toString();
+            }
+        }
+        return Either.left(newValue);
+    }
+
     private <T extends PropertyDefinition> void validateToscaGetFunction(T property) {
         if (property.getToscaGetFunctionType() == ToscaGetFunctionType.GET_INPUT) {
             final List<GetInputValueDataDefinition> getInputValues = property.getGetInputValues();
@@ -2270,18 +2427,18 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         Component containerComponent = getResourceResult.left().value();
 
         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
-            if (containerComponent.isArchived()) {
-                log.info("Component is archived. Component id: {}", componentId);
+            if (Boolean.TRUE.equals(containerComponent.isArchived())) {
+                log.info(COMPONENT_ARCHIVED, componentId);
                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_IS_ARCHIVED, containerComponent.getName()));
             }
-            log.info("Restricted operation for user: {} on service {}", userId, componentId);
+            log.info(RESTRICTED_OPERATION_ON_SERVIVE, userId, componentId);
             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
             return resultOp;
         }
         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent, resourceInstanceId);
         if (resourceInstanceStatus.isRight()) {
             return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER,
-                resourceInstanceId, "resource instance", "service", componentId));
+                resourceInstanceId, RESOURCE_INSTANCE, SERVICE, componentId));
         }
 
         ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value();
@@ -2513,7 +2670,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
             ActionStatus actionStatus = ActionStatus.CONTAINER_CANNOT_CONTAIN_COMPONENT_IN_STATE;
             throw new ByActionStatusComponentException(actionStatus, containerComponent.getComponentType().toString(), resourceCurrState.toString());
         }
-        if (component.isArchived() == true) {
+        if (Boolean.TRUE.equals(component.isArchived())) {
             ActionStatus actionStatus = ActionStatus.COMPONENT_IS_ARCHIVED;
             throw new ByActionStatusComponentException(actionStatus, component.getName());
         }
@@ -2553,7 +2710,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
             resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse
                 (componentExistsRes.right().value()), resourceId));
             return resultOp;
-        } else if (!componentExistsRes.left().value()) {
+        } else if (!Boolean.TRUE.equals(componentExistsRes.left().value())) {
             log.debug("The resource {} not found ", resourceId);
             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceId));
             return resultOp;
@@ -2636,7 +2793,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
                 log.debug("Failed to validate existing of the component {}. Status is {} ", resourceId, errorStatus);
                 throw new ByActionStatusComponentException(
                     componentsUtils.convertFromStorageResponse(errorStatus), resourceId);
-            } else if (!componentExistsRes.left().value()) {
+            } else if (!Boolean.TRUE.equals(componentExistsRes.left().value())) {
                 log.debug("The resource {} not found ", resourceId);
                 throw new ByActionStatusComponentException(ActionStatus.RESOURCE_NOT_FOUND, resourceId);
             }
@@ -2656,7 +2813,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
                 newComponentInstance.setOriginType(originType);
                 if (originType == OriginTypeEnum.ServiceProxy) {
                     Either<Component, StorageOperationStatus> serviceProxyOrigin = toscaOperationFacade
-                        .getLatestByName(SERVICE_PROXY);
+                        .getLatestByName(SERVICE_PROXY, null);
                     if (isServiceProxyOrigin(serviceProxyOrigin)) {
                         throw new ByActionStatusComponentException(
                             componentsUtils.convertFromStorageResponse(serviceProxyOrigin.right().value()));
@@ -2678,7 +2835,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
                     final Component service = getServiceResult.left().value();
 
                     final Either<Component, StorageOperationStatus> getServiceDerivedFromTypeResult = toscaOperationFacade
-                        .getLatestByToscaResourceName(service.getDerivedFromGenericType());
+                        .getLatestByToscaResourceName(service.getDerivedFromGenericType(), service.getModel());
                     if (getServiceDerivedFromTypeResult.isRight()) {
                         throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getServiceResult.right().value()));
                     }
@@ -3025,7 +3182,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         }
         Component containerComponent = getResourceResult.left().value();
         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
-            log.info("Restricted operation for user: {} on component {}", userId, containerComponentId);
+            log.info(RESTRICTED_OPERATION_ON_COMPONENT, userId, containerComponentId);
             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
         }
         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent,
@@ -3037,7 +3194,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         // lock resource
         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(containerComponentId, componentTypeEnum.getNodeType());
         if (lockStatus != StorageOperationStatus.OK) {
-            log.debug("Failed to lock component {}", containerComponentId);
+            log.debug(FAILED_TO_LOCK_COMPONENT, containerComponentId);
             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
         }
         try {
@@ -3068,6 +3225,69 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         }
     }
 
+    public Either<CapabilityDefinition, ResponseFormat> updateInstanceCapability(final ComponentTypeEnum containerComponentType,
+                                                                                 final String containerComponentId,
+                                                                                 final String componentInstanceUniqueId,
+                                                                                 final CapabilityDefinition capabilityDefinition,
+                                                                                 final String userId) {
+        if (containerComponentType == null) {
+            BeEcompErrorManager.getInstance().logInvalidInputError("updateInstanceCapability", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
+        }
+        validateUserExists(userId);
+        final Either<Component, StorageOperationStatus> getResourceResult = toscaOperationFacade.getToscaFullElement(containerComponentId);
+        if (getResourceResult.isRight()) {
+            log.debug(FAILED_TO_RETRIEVE_COMPONENT_COMPONENT_ID, containerComponentId);
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NOT_FOUND, containerComponentId));
+        }
+        final Component containerComponent = getResourceResult.left().value();
+        if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
+            log.info(RESTRICTED_OPERATION_ON_COMPONENT, userId, containerComponentId);
+            return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
+        }
+        final Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus =
+            getResourceInstanceById(containerComponent, componentInstanceUniqueId);
+        if (resourceInstanceStatus.isRight()) {
+            return Either.right(componentsUtils
+                .getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceUniqueId, containerComponentId));
+        }
+        // lock resource
+        final StorageOperationStatus lockStatus = graphLockOperation.lockComponent(containerComponentId, containerComponentType.getNodeType());
+        if (lockStatus != StorageOperationStatus.OK) {
+            log.debug(FAILED_TO_LOCK_COMPONENT, containerComponentId);
+            return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
+        }
+        var success = false;
+        try {
+            final CapabilityDataDefinition updatedCapabilityDefinition = toscaOperationFacade
+                .updateComponentInstanceCapability(containerComponentId, componentInstanceUniqueId, capabilityDefinition);
+            final Either<Component, StorageOperationStatus> updateContainerEither = toscaOperationFacade
+                .updateComponentInstanceMetadataOfTopologyTemplate(containerComponent);
+            if (updateContainerEither.isRight()) {
+                var actionStatus = componentsUtils.convertFromStorageResponse(updateContainerEither.right().value(), containerComponentType);
+                return Either.right(componentsUtils.getResponseFormat(actionStatus));
+            }
+            success = true;
+            return Either.left(new CapabilityDefinition(updatedCapabilityDefinition));
+        } catch (final BusinessException e) {
+            log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, NodeTemplateOperation.class.getName(), (ErrorLogOptionalData) null,
+                FAILED_TO_UPDATE_COMPONENT_INSTANCE_CAPABILITY, componentInstanceUniqueId, containerComponentId);
+            throw e;
+        } catch (final Exception e) {
+            log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, NodeTemplateOperation.class.getName(), (ErrorLogOptionalData) null,
+                FAILED_TO_UPDATE_COMPONENT_INSTANCE_CAPABILITY, componentInstanceUniqueId, containerComponentId);
+            throw new ByResponseFormatComponentException(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR));
+        } finally {
+            if (success) {
+                janusGraphDao.commit();
+            } else {
+                janusGraphDao.rollback();
+            }
+            // unlock resource
+            graphLockOperation.unlockComponent(containerComponentId, containerComponentType.getNodeType());
+        }
+    }
+
     public Either<List<ComponentInstanceProperty>, ResponseFormat> updateInstanceCapabilityProperties(ComponentTypeEnum componentTypeEnum,
                                                                                                       String containerComponentId,
                                                                                                       String componentInstanceUniqueId,
@@ -3087,7 +3307,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         }
         Component containerComponent = getResourceResult.left().value();
         if (!ComponentValidationUtils.canWorkOnComponent(containerComponent, userId)) {
-            log.info("Restricted operation for user: {} on component {}", userId, containerComponentId);
+            log.info(RESTRICTED_OPERATION_ON_COMPONENT, userId, containerComponentId);
             return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION));
         }
         Either<ComponentInstance, StorageOperationStatus> resourceInstanceStatus = getResourceInstanceById(containerComponent,
@@ -3100,7 +3320,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         // lock resource
         StorageOperationStatus lockStatus = graphLockOperation.lockComponent(containerComponentId, componentTypeEnum.getNodeType());
         if (lockStatus != StorageOperationStatus.OK) {
-            log.debug("Failed to lock component {}", containerComponentId);
+            log.debug(FAILED_TO_LOCK_COMPONENT, containerComponentId);
             return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus)));
         }
         try {
@@ -3325,7 +3545,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic {
         Either<ComponentInstanceAttribute, ResponseFormat> resultOp = null;
         validateUserExists(userId);
         if (componentTypeEnum == null) {
-            BeEcompErrorManager.getInstance().logInvalidInputError("createOrUpdateAttributeValue", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
+            BeEcompErrorManager.getInstance()
+                .logInvalidInputError("createOrUpdateAttributeValueForCopyPaste", INVALID_COMPONENT_TYPE, ErrorSeverity.INFO);
             resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED));
             return resultOp;
         }