X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=catalog-be%2Fsrc%2Fmain%2Fjava%2Forg%2Fopenecomp%2Fsdc%2Fbe%2Fcomponents%2Fimpl%2FComponentInstanceBusinessLogic.java;h=01e87a134bfc7b0c8a238d945d845bf5726b7f98;hb=98826572a529d01250cf4925dc3f26ac8c35478a;hp=1fa459da806891a88a4094a4e0637260b2f14b61;hpb=b43eb22f91ffdc1e2ba5d82b3dc1a2c4250d06e0;p=sdc.git diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java index 1fa459da80..01e87a134b 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java @@ -17,6 +17,7 @@ * limitations under the License. * ============LICENSE_END========================================================= */ + package org.openecomp.sdc.be.components.impl; import static org.openecomp.sdc.be.components.attribute.GetOutputUtils.isGetOutputValueForOutput; @@ -43,6 +44,9 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.text.StringEscapeUtils; +import org.json.JSONArray; +import org.json.JSONObject; import org.onap.sdc.tosca.datatypes.model.PropertyType; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; @@ -62,6 +66,7 @@ import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datamodel.utils.PropertyValueConstraintValidationUtil; import org.openecomp.sdc.be.datatypes.elements.CINodeFilterDataDefinition; import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition; @@ -71,6 +76,7 @@ import org.openecomp.sdc.be.datatypes.elements.GetPolicyValueDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; @@ -101,12 +107,14 @@ import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.LifecycleStateEnum; import org.openecomp.sdc.be.model.OutputDefinition; import org.openecomp.sdc.be.model.PolicyDefinition; +import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.RelationshipInfo; import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; import org.openecomp.sdc.be.model.RequirementDefinition; import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.ToscaPropertyData; import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.jsonjanusgraph.config.ContainerInstanceTypesData; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; @@ -128,6 +136,7 @@ import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator; import org.openecomp.sdc.be.resources.data.ComponentInstanceData; import org.openecomp.sdc.be.user.Role; import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; @@ -142,6 +151,7 @@ import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.common.util.ValidationUtils; import org.openecomp.sdc.exception.ResponseFormat; import org.springframework.beans.factory.annotation.Autowired; +import org.yaml.snakeyaml.Yaml; @org.springframework.stereotype.Component public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { @@ -160,7 +170,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { private static final String CREATE_OR_UPDATE_PROPERTY_VALUE = "CreateOrUpdatePropertyValue"; 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 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"; @@ -178,6 +189,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { private final ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator; private final ForwardingPathOperation forwardingPathOperation; private final NodeFilterOperation nodeFilterOperation; + private final ToscaFunctionValidator toscaFunctionValidator; + private final PropertyBusinessLogic propertyBusinessLogic; @Autowired private CompositionBusinessLogic compositionBusinessLogic; @Autowired @@ -191,7 +204,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { ComponentInstanceMergeDataBusinessLogic compInstMergeDataBL, ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator, ForwardingPathOperation forwardingPathOperation, NodeFilterOperation nodeFilterOperation, - ArtifactsOperations artifactToscaOperation) { + ArtifactsOperations artifactToscaOperation, final ToscaFunctionValidator toscaFunctionValidator, + PropertyBusinessLogic propertyBusinessLogic) { super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation); this.componentInstanceOperation = componentInstanceOperation; @@ -200,6 +214,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { this.onChangeInstanceOperationOrchestrator = onChangeInstanceOperationOrchestrator; this.forwardingPathOperation = forwardingPathOperation; this.nodeFilterOperation = nodeFilterOperation; + this.toscaFunctionValidator = toscaFunctionValidator; + this.propertyBusinessLogic = propertyBusinessLogic; } public ComponentInstance createComponentInstance(String containerComponentParam, String containerComponentId, String userId, @@ -918,7 +934,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } if (CollectionUtils.isNotEmpty(filteredGroups)) { filteredGroups.stream() - .filter(g -> g.getArtifacts() != null && g.getArtifacts().stream().anyMatch(p -> p.equals(artifactDefinition.getGeneratedFromId()))).findFirst() + .filter(g -> g.getArtifacts() != null && + g.getArtifacts().stream().anyMatch(p -> p.equals(artifactDefinition.getGeneratedFromId()))).findFirst() .ifPresent(g -> fillInstanceArtifactMap(groupInstancesArtifacts, artifactDefinition, g)); } } @@ -1947,6 +1964,12 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value(); + // Validate instance property against it's constrains + Either constraintValidatorResponse = validatePropertyValueConstraint(properties, componentId); + if (constraintValidatorResponse.isRight()) { + log.error("Failed validation value and constraint of property: {}", constraintValidatorResponse.right().value()); + return Either.right(constraintValidatorResponse.right().value()); + } // lock resource StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType()); if (lockStatus != StorageOperationStatus.OK) { @@ -1957,12 +1980,31 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { try { for (ComponentInstanceProperty property : properties) { validateMandatoryFields(property); - ComponentInstanceProperty componentInstanceProperty = validatePropertyExistsOnComponent(property, containerComponent, - foundResourceInstance); + validatePropertyExistsOnComponent(property, containerComponent, foundResourceInstance); + validatePropertyConstraintsNotChanged(properties, foundResourceInstance); String propertyParentUniqueId = property.getParentUniqueId(); - if (property.isGetFunction()) { - validateToscaGetFunction(property, containerComponent); - property.setValue(property.getToscaGetFunction().generatePropertyValue()); + if (property.isToscaFunction()) { + toscaFunctionValidator.validate(property, containerComponent); + property.setValue(StringEscapeUtils.unescapeJava(property.getToscaFunction().getValue())); + if (ToscaFunctionType.GET_INPUT == property.getToscaFunction().getType()) { + property.setGetInputValues(Collections.singletonList(buildGetInputValue(property))); + } + } + if (CollectionUtils.isNotEmpty(property.getSubPropertyToscaFunctions())) { + ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType()); + if (ToscaPropertyType.LIST.equals(type)) { + final JSONArray jsonArray = property.getValue() == null ? new JSONArray() : new JSONArray(property.getValue()); + property.getSubPropertyToscaFunctions().stream().forEach(subToscaFunction -> { + addE(jsonArray, subToscaFunction.getSubPropertyPath(), subToscaFunction.getToscaFunction().getValue()); + }); + property.setValue(jsonArray.toString()); + } else { + final JSONObject jObject = property.getValue() == null ? new JSONObject() : new JSONObject(property.getValue()); + property.getSubPropertyToscaFunctions().stream().forEach(subToscaFunction -> { + addE(jObject, subToscaFunction.getSubPropertyPath(), subToscaFunction.getToscaFunction().getValue()); + }); + property.setValue(jObject.toString()); + } } Either updatedPropertyValue = updatePropertyObjectValue(property, containerComponent.getModel()); if (updatedPropertyValue.isRight()) { @@ -1979,12 +2021,10 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { capPropDefinition.get().getName()), Either::right); } else { updatedPropertyValue.bimap( - updatedValue -> { - componentInstanceProperty.setValue(updatedValue); - return updatePropertyOnContainerComponent(property, updatedValue, - containerComponent, foundResourceInstance); - }, Either::right); - updatedProperties.add(componentInstanceProperty); + updatedValue -> updatePropertyOnContainerComponent(property, updatedValue, containerComponent, foundResourceInstance), + Either::right + ); + updatedProperties.add(property); } } @@ -2011,6 +2051,78 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } } + private GetInputValueDataDefinition buildGetInputValue(final ComponentInstanceProperty property) { + final GetInputValueDataDefinition getInputValueDataDefinition = new GetInputValueDataDefinition(); + getInputValueDataDefinition.setPropName(property.getName()); + getInputValueDataDefinition.setInputName(((ToscaGetFunctionDataDefinition) property.getToscaFunction()).getPropertyName()); + getInputValueDataDefinition.setInputId(((ToscaGetFunctionDataDefinition) property.getToscaFunction()).getPropertyUniqueId()); + return getInputValueDataDefinition; + } + + private void addE(JSONArray jsonArray, List path, String value) { + Object objectForPath = jsonArray.opt(Integer.parseInt(path.get(0))); + if (objectForPath == null) { + if (path.size() > 1) { + if (StringUtils.isNumeric(path.get(1))) { + objectForPath = new JSONArray(); + } else { + objectForPath = new JSONObject(); + } + jsonArray.put(Integer.parseInt(path.get(0)), objectForPath); + } + } + + if (path.size() == 1) { + Object valueAsObject = new Yaml().loadAs(value, Object.class); + jsonArray.put(Integer.parseInt(path.get(0)), valueAsObject); + } else { + if (objectForPath instanceof JSONObject) { + addE((JSONObject) objectForPath, path.subList(1, path.size()), value); + } else { + addE((JSONArray) objectForPath, path.subList(1, path.size()), value); + } + } + } + + private void addE(JSONObject jsonObject, List path, String value) { + + Object objectForPath = null; + if (jsonObject.has(path.get(0))) { + objectForPath = jsonObject.get(path.get(0)); + } else { + if (path.size() > 1 && StringUtils.isNumeric(path.get(1))) { + objectForPath = new JSONArray(); + } else { + objectForPath = new JSONObject(); + } + jsonObject.put(path.get(0), objectForPath); + } + + if (path.size() == 1) { + Object valueAsObject = new Yaml().loadAs(value, Object.class); + jsonObject.put(path.get(0), valueAsObject); + } else { + if (objectForPath instanceof JSONObject) { + addE((JSONObject) objectForPath, path.subList(1, path.size()), value); + } else { + addE((JSONArray) objectForPath, path.subList(1, path.size()), value); + } + } + } + + private void setJsonObjectForSubProperty(final JSONObject jObject, final List path, String value) { + if (path.size() == 1) { + Object valueAsObject = new Yaml().loadAs(value, Object.class); + jObject.put(path.get(0), valueAsObject); + } else { + if (!jObject.has(path.get(0))) { + jObject.put(path.get(0), new JSONObject()); + } + final JSONObject jsonObject = jObject.getJSONObject(path.get(0)); + setJsonObjectForSubProperty(jsonObject, path.subList(1, path.size()), value); + } + } + public Either, ResponseFormat> createOrUpdateAttributeValues(final ComponentTypeEnum componentTypeEnum, final String componentId, final String resourceInstanceId, @@ -2052,6 +2164,22 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } final ComponentInstance foundResourceInstance = resourceInstanceStatus.left().value(); + // Validate instance attributes against it's constraints + List attributesToValidate = new ArrayList<>(); + attributes.forEach((componentInstanceAttribute) -> { + PropertyDefinition propertyDefinition = new PropertyDefinition(); + propertyDefinition.setValue(componentInstanceAttribute.getValue()); + propertyDefinition.setType(componentInstanceAttribute.getType()); + propertyDefinition.setName(componentInstanceAttribute.getName()); + propertyDefinition.setUniqueId(componentInstanceAttribute.getUniqueId()); + attributesToValidate.add(propertyDefinition); + }); + Either constraintValidatorResponse = validatePropertyValueConstraint(attributesToValidate, componentId); + if (constraintValidatorResponse.isRight()) { + log.error("Failed validation value and constraint of attribute: {}", constraintValidatorResponse.right().value()); + return Either.right(constraintValidatorResponse.right().value()); + } + // lock resource final StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType()); if (lockStatus != StorageOperationStatus.OK) { @@ -2107,16 +2235,14 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } } - private ComponentInstanceProperty validatePropertyExistsOnComponent(ComponentInstanceProperty property, Component containerComponent, - ComponentInstance foundResourceInstance) { + private void validatePropertyExistsOnComponent(ComponentInstanceProperty property, Component containerComponent, + ComponentInstance foundResourceInstance) { List instanceProperties = containerComponent.getComponentInstancesProperties() .get(foundResourceInstance.getUniqueId()); - Optional instanceProperty = instanceProperties.stream().filter(p -> p.getName().equals(property.getName())) - .findAny(); - if (instanceProperty.isEmpty()) { + final boolean hasProperty = instanceProperties.stream().anyMatch(p -> p.getName().equals(property.getName())); + if (!hasProperty) { throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, property.getName()); } - return instanceProperty.get(); } private ComponentInstanceAttribute validateAttributeExistsOnComponent(final ComponentInstanceAttribute attribute, @@ -2301,7 +2427,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { // Specific Update Logic String newValue = property.getValue(); - if (property.hasGetFunction()) { + if (property.hasToscaFunction() || CollectionUtils.isNotEmpty(property.getSubPropertyToscaFunctions())) { return Either.left(newValue); } @@ -2373,32 +2499,53 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } private void validateToscaGetFunction(T property, Component parentComponent) { - final ToscaGetFunctionDataDefinition toscaGetFunction = property.getToscaGetFunction(); + final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) property.getToscaFunction(); + validateGetToscaFunctionAttributes(toscaGetFunction); + validateGetPropertySource(toscaGetFunction.getFunctionType(), toscaGetFunction.getPropertySource()); if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_INPUT) { validateGetFunction(property, parentComponent.getInputs(), parentComponent.getModel()); return; } if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_PROPERTY) { - validateGetFunction(property, parentComponent.getProperties(), parentComponent.getModel()); + if (toscaGetFunction.getPropertySource() == PropertySource.SELF) { + validateGetFunction(property, parentComponent.getProperties(), parentComponent.getModel()); + } else if (toscaGetFunction.getPropertySource() == PropertySource.INSTANCE) { + final ComponentInstance componentInstance = + parentComponent.getComponentInstanceById(toscaGetFunction.getSourceUniqueId()) + .orElseThrow(ToscaGetFunctionExceptionSupplier.instanceNotFound(toscaGetFunction.getSourceName())); + validateGetFunction(property, componentInstance.getProperties(), parentComponent.getModel()); + } + + return; + } + if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_ATTRIBUTE) { + if (toscaGetFunction.getPropertySource() == PropertySource.SELF) { + validateGetFunction(property, parentComponent.getAttributes(), parentComponent.getModel()); + } else if (toscaGetFunction.getPropertySource() == PropertySource.INSTANCE) { + final ComponentInstance componentInstance = + parentComponent.getComponentInstanceById(toscaGetFunction.getSourceUniqueId()) + .orElseThrow(ToscaGetFunctionExceptionSupplier.instanceNotFound(toscaGetFunction.getSourceName())); + validateGetFunction(property, componentInstance.getAttributes(), parentComponent.getModel()); + } + return; } throw ToscaGetFunctionExceptionSupplier.functionNotSupported(toscaGetFunction.getFunctionType()).get(); } - private void validateGetFunction(final T property, - final List parentProperties, - final String model) { - final ToscaGetFunctionDataDefinition toscaGetFunction = property.getToscaGetFunction(); + private void validateGetFunction(final T property, + final List parentProperties, + final String model) { + final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) property.getToscaFunction(); if (CollectionUtils.isEmpty(parentProperties)) { throw ToscaGetFunctionExceptionSupplier .propertyNotFoundOnTarget(toscaGetFunction.getPropertyName(), toscaGetFunction.getPropertySource(), toscaGetFunction.getFunctionType() ).get(); } - validateGetPropertySource(toscaGetFunction.getFunctionType(), toscaGetFunction.getPropertySource()); final String getFunctionPropertyUniqueId = toscaGetFunction.getPropertyUniqueId(); - T referredProperty = (T) parentProperties.stream() + ToscaPropertyData referredProperty = parentProperties.stream() .filter(property1 -> getFunctionPropertyUniqueId.equals(property1.getUniqueId())) .findFirst() .orElseThrow(ToscaGetFunctionExceptionSupplier @@ -2409,18 +2556,20 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { referredProperty = findSubProperty(referredProperty, toscaGetFunction, model); } - if (!property.getType().equals(referredProperty.getType())) { + if (!property.getType().equals(referredProperty.getType()) && !"list".equalsIgnoreCase(referredProperty.getType())) { throw ToscaGetFunctionExceptionSupplier - .propertyTypeDiverge(toscaGetFunction.getFunctionType(), referredProperty.getType(), property.getType()).get(); + .propertyTypeDiverge(toscaGetFunction.getType(), referredProperty.getType(), property.getType()).get(); } - if (PropertyType.typeHasSchema(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getSchemaType())) { + if (PropertyType.typeHasSchema(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getType()) + && !"list".equalsIgnoreCase(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getSchemaType())) { throw ToscaGetFunctionExceptionSupplier - .propertySchemaDiverge(toscaGetFunction.getFunctionType(), referredProperty.getSchemaType(), property.getSchemaType()).get(); + .propertySchemaDiverge(toscaGetFunction.getType(), referredProperty.getSchemaType(), property.getSchemaType()).get(); } } - private T findSubProperty(final T referredProperty, final ToscaGetFunctionDataDefinition toscaGetFunction, - final String model) { + private ToscaPropertyData findSubProperty(final ToscaPropertyData referredProperty, + final ToscaGetFunctionDataDefinition toscaGetFunction, + final String model) { final Map dataTypeMap = loadDataTypes(model); final List propertyPathFromSource = toscaGetFunction.getPropertyPathFromSource(); DataTypeDefinition dataType = dataTypeMap.get(referredProperty.getType()); @@ -2428,10 +2577,10 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { throw ToscaGetFunctionExceptionSupplier .propertyDataTypeNotFound(propertyPathFromSource.get(0), referredProperty.getType(), toscaGetFunction.getFunctionType()).get(); } - T foundProperty = referredProperty; + ToscaPropertyData foundProperty = referredProperty; for (int i = 1; i < propertyPathFromSource.size(); i++) { final String currentPropertyName = propertyPathFromSource.get(i); - foundProperty = (T) dataType.getProperties().stream() + foundProperty = dataType.getProperties().stream() .filter(propertyDefinition -> currentPropertyName.equals(propertyDefinition.getName())).findFirst() .orElseThrow( ToscaGetFunctionExceptionSupplier @@ -2458,10 +2607,39 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } private void validateGetPropertySource(final ToscaGetFunctionType functionType, final PropertySource propertySource) { - if (propertySource != PropertySource.SELF) { + if (functionType == ToscaGetFunctionType.GET_INPUT && propertySource != PropertySource.SELF) { throw ToscaGetFunctionExceptionSupplier .targetSourceNotSupported(functionType, propertySource).get(); } + if (functionType == ToscaGetFunctionType.GET_PROPERTY && !List.of(PropertySource.SELF, PropertySource.INSTANCE).contains(propertySource)) { + throw ToscaGetFunctionExceptionSupplier + .targetSourceNotSupported(functionType, propertySource).get(); + } + } + + private void validateGetToscaFunctionAttributes(final ToscaGetFunctionDataDefinition toscaGetFunction) { + if (toscaGetFunction.getFunctionType() == null) { + throw ToscaGetFunctionExceptionSupplier.targetFunctionTypeNotFound().get(); + } + if (toscaGetFunction.getPropertySource() == null) { + throw ToscaGetFunctionExceptionSupplier.targetPropertySourceNotFound(toscaGetFunction.getFunctionType()).get(); + } + if (CollectionUtils.isEmpty(toscaGetFunction.getPropertyPathFromSource())) { + throw ToscaGetFunctionExceptionSupplier + .targetSourcePathNotFound(toscaGetFunction.getFunctionType()).get(); + } + if (StringUtils.isEmpty(toscaGetFunction.getSourceName()) || StringUtils.isBlank(toscaGetFunction.getSourceName())) { + throw ToscaGetFunctionExceptionSupplier.sourceNameNotFound(toscaGetFunction.getPropertySource()).get(); + } + if (StringUtils.isEmpty(toscaGetFunction.getSourceUniqueId()) || StringUtils.isBlank(toscaGetFunction.getSourceUniqueId())) { + throw ToscaGetFunctionExceptionSupplier.sourceIdNotFound(toscaGetFunction.getPropertySource()).get(); + } + if (StringUtils.isEmpty(toscaGetFunction.getPropertyName()) || StringUtils.isBlank(toscaGetFunction.getPropertyName())) { + throw ToscaGetFunctionExceptionSupplier.propertyNameNotFound(toscaGetFunction.getPropertySource()).get(); + } + if (StringUtils.isEmpty(toscaGetFunction.getPropertyUniqueId()) || StringUtils.isBlank(toscaGetFunction.getPropertyUniqueId())) { + throw ToscaGetFunctionExceptionSupplier.propertyIdNotFound(toscaGetFunction.getPropertySource()).get(); + } } private ResponseFormat updateInputOnContainerComponent(ComponentInstanceInput input, String newValue, Component containerComponent, @@ -2924,13 +3102,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } else { origComponent = getOriginComponentFromComponentInstance(newComponentInstance); newComponentInstance.setName(resResourceInfo.getName()); - final Either getComponentRes = toscaOperationFacade - .getToscaFullElement(newComponentInstance.getComponentUid()); - if (getComponentRes.isRight()) { - throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(getComponentRes.right().value())); - } - final Component component = getComponentRes.left().value(); - final Map componentInterfaces = component.getInterfaces(); + final Map componentInterfaces = origComponent.getInterfaces(); if (MapUtils.isNotEmpty(componentInterfaces)) { componentInterfaces.forEach(newComponentInstance::addInterface); } @@ -2943,6 +3115,8 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { newComponentInstance.setInstanceCount(resResourceInfo.getInstanceCount()); newComponentInstance.setMaxOccurrences(resResourceInfo.getMaxOccurrences()); newComponentInstance.setMinOccurrences(resResourceInfo.getMinOccurrences()); + newComponentInstance.setDirectives(resResourceInfo.getDirectives()); + checkForExternalReqAndCapabilities(origComponent, resResourceInfo); ComponentInstance updatedComponentInstance = createComponentInstanceOnGraph(containerComponent, origComponent, newComponentInstance, user); @@ -2966,6 +3140,9 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { log.debug("Component with id {} was not found", containerComponentId); throw new ByActionStatusComponentException(actionStatus, Constants.EMPTY_STRING); } + + maintainNodeFilters(currentResourceInstance, newComponentInstance, containerComponentId); + resourceInstanceStatus = getResourceInstanceById(updatedComponentRes.left().value(), updatedComponentInstance.getUniqueId()); if (resourceInstanceStatus.isRight()) { @@ -2982,6 +3159,53 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } } + private void maintainNodeFilters( + ComponentInstance currentResourceInstance, + ComponentInstance newComponentInstance, + String containerComponentId) { + CINodeFilterDataDefinition filterToMaintain = currentResourceInstance.getNodeFilter(); + if (null != filterToMaintain) { + nodeFilterOperation.addNodeFilterData( + containerComponentId.toLowerCase(), + newComponentInstance.getUniqueId(), + filterToMaintain); + } + } + + private void checkForExternalReqAndCapabilities(Component component, ComponentInstance resResourceInfo) { + if (MapUtils.isNotEmpty(component.getRequirements())) { + component.getRequirements().entrySet().forEach(requirementsMap -> { + if (MapUtils.isNotEmpty(resResourceInfo.getRequirements()) && + resResourceInfo.getRequirements().containsKey(requirementsMap.getKey())) { + List resourceReqList = resResourceInfo.getRequirements().get(requirementsMap.getKey()); + for (RequirementDefinition requirements : requirementsMap.getValue()) { + String requirementName = requirements.getName(); + resourceReqList.forEach(requirementDefinition -> { + if (requirementName.equals(requirementDefinition.getName()) && requirementDefinition.isExternal()) { + requirements.setExternal(requirementDefinition.isExternal()); + } + }); + } + } + }); + } + if (MapUtils.isNotEmpty(component.getCapabilities())) { + component.getCapabilities().entrySet().forEach(capabilityMap -> { + if (MapUtils.isNotEmpty(resResourceInfo.getCapabilities()) && resResourceInfo.getCapabilities().containsKey(capabilityMap.getKey())) { + List resourceCapList = resResourceInfo.getCapabilities().get(capabilityMap.getKey()); + capabilityMap.getValue().forEach(capabilities -> { + String capabilityName = capabilities.getName(); + for (CapabilityDefinition capDef : resourceCapList) { + if (capabilityName.equals(capDef.getName()) && capDef.isExternal()) { + capabilities.setExternal(capDef.isExternal()); + } + } + }); + } + }); + } + } + private boolean isFillProxyRes(StorageOperationStatus fillProxyRes) { if (fillProxyRes != StorageOperationStatus.OK) { log.debug("Failed to fill service proxy resource data with data from service, error {}", fillProxyRes); @@ -3014,9 +3238,10 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { containerComponentId); } - List instanceProperties = containerComponent.getComponentInstancesProperties().get(componentInstanceUniqueId); - if (CollectionUtils.isEmpty(instanceProperties)) { - instanceProperties = new ArrayList<>(); + List instanceProperties = new ArrayList<>(); + if (MapUtils.isNotEmpty(containerComponent.getComponentInstancesProperties())) { + instanceProperties = containerComponent.getComponentInstancesProperties() + .get(componentInstanceUniqueId); } return instanceProperties; } catch (ComponentException e) { @@ -3605,7 +3830,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { if (sourceAttributeName.equals(destAttribute.getName())) { log.debug("Start to copy the attribute exists {}", sourceAttributeName); sourceAttribute.setUniqueId( - UniqueIdBuilder.buildResourceInstanceUniuqeId("attribute", destComponentInstanceId.split("\\.")[1], sourceAttributeName)); + UniqueIdBuilder.buildResourceInstanceUniqueId("attribute", destComponentInstanceId.split("\\.")[1], sourceAttributeName)); Either updateAttributeValueEither = createOrUpdateAttributeValueForCopyPaste( ComponentTypeEnum.SERVICE, destComponent.getUniqueId(), destComponentInstanceId, sourceAttribute, userId); if (updateAttributeValueEither.isRight()) { @@ -3789,6 +4014,32 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { } } + private void validatePropertyConstraintsNotChanged(List newProperties, ComponentInstance originalResourceInstance) { + for (ComponentInstanceProperty newProperty : newProperties) { + Optional originalProperty = originalResourceInstance.getProperties().stream() + .filter(prop -> prop.getUniqueId().equals(newProperty.getUniqueId())).findAny(); + if (originalProperty.isPresent()) { + List originalConstraints = originalProperty.get().getConstraints(); + List newConstraints = newProperty.getConstraints(); + if (!Objects.equals(originalConstraints, newConstraints)) { + throw new ByActionStatusComponentException(ActionStatus.CANNOT_CHANGE_CONSTRAINTS); + } + } else { + throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, newProperty.getUniqueId()); + } + } + } + + private Either validatePropertyValueConstraint(List properties, final String componentId) { + try { + String propertyModel = propertyBusinessLogic.getComponentModelByComponentId(componentId); + PropertyValueConstraintValidationUtil propertyValueConstraintValidationUtil = new PropertyValueConstraintValidationUtil(); + return propertyValueConstraintValidationUtil.validatePropertyConstraints(properties, applicationDataTypeCache, propertyModel); + } catch (BusinessLogicException e) { + return Either.right(e.getResponseFormat()); + } + } + public void validateUser(final String userId) { final User user = userValidations.validateUserExists(userId); userValidations.validateUserRole(user, Arrays.asList(Role.DESIGNER, Role.ADMIN));