diff options
author | andre.schmid <andre.schmid@est.tech> | 2022-07-25 10:41:31 +0100 |
---|---|---|
committer | Michael Morris <michael.morris@est.tech> | 2022-07-29 20:09:49 +0000 |
commit | 7be04e3e3bdc899c52ffea1f6e11731771903f93 (patch) | |
tree | f18c4579d22587a8efd904b62d8d1878b2de8a2b /catalog-model/src | |
parent | 3f9669fdae5f7c6cb1bfe34742df35dfe3a14aa7 (diff) |
Centralize TOSCA function validation
The validation happening in the component instance properties,
should also be applied for the Group instance properties and
Policy instance properties.
Fixes some other problems related to the TOSCA function.
Change-Id: I4b69da57a8444b78c72561f49146d32c6911482e
Issue-ID: SDC-4114
Signed-off-by: andre.schmid <andre.schmid@est.tech>
Diffstat (limited to 'catalog-model/src')
12 files changed, 373 insertions, 137 deletions
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/config/CatalogModelSpringConfig.java b/catalog-model/src/main/java/org/openecomp/sdc/be/config/CatalogModelSpringConfig.java index 19914380a6..eb26d59775 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/config/CatalogModelSpringConfig.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/config/CatalogModelSpringConfig.java @@ -29,6 +29,7 @@ import org.springframework.context.annotation.Configuration; // @formatter:off "org.openecomp.sdc.be.model.operations.impl", "org.openecomp.sdc.be.model.cache", + "org.openecomp.sdc.be.model.validation", "org.openecomp.sdc.be.client", "org.openecomp.sdc.be.model.jsonjanusgraph.utils", "org.openecomp.sdc.be.model.jsonjanusgraph.operations", diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/GroupsOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/GroupsOperation.java index d346d9364a..67eaae74ea 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/GroupsOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/GroupsOperation.java @@ -225,12 +225,7 @@ public class GroupsOperation extends BaseOperation { result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value())); } if (result == null) { - groups.forEach(gr -> { - updateVersion(promoteVersion, gr); - // String groupUUID = UniqueIdBuilder.generateUUID(); - - // gr.setGroupUUID(groupUUID); - }); + groups.forEach(gr -> updateVersion(promoteVersion, gr)); status = updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, groups, JsonPresentationFields.CI_INVARIANT_NAME); if (status != StorageOperationStatus.OK) { @@ -297,46 +292,36 @@ public class GroupsOperation extends BaseOperation { public Either<List<GroupProperty>, StorageOperationStatus> updateGroupPropertiesOnComponent(String componentId, GroupDefinition group, List<GroupProperty> newGroupProperties, PromoteVersionEnum promoteMinorVersion) { - Either<List<GroupProperty>, StorageOperationStatus> result = null; - Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = null; - GraphVertex componentVertex = null; - getComponentVertex = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata); + Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata); if (getComponentVertex.isRight()) { CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId); - result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value())); - } - if (result == null) { - componentVertex = getComponentVertex.left().value(); - //update - List<PropertyDataDefinition> properties = group.getProperties(); - newGroupProperties.forEach(np -> { - Optional<PropertyDataDefinition> currentProp = properties.stream().filter(p -> p.getName().equals(np.getName())).findAny(); - if (currentProp.isPresent()) { - currentProp.get().setValue(np.getValue()); - currentProp.get().setToscaFunction(np.getToscaFunction()); - } - }); - updateVersion(promoteMinorVersion, group); - StorageOperationStatus updateDataRes = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, group, - JsonPresentationFields.CI_INVARIANT_NAME); - if (updateDataRes != StorageOperationStatus.OK) { - log.debug("Failed to update properties for group {} error {}", group.getName(), updateDataRes); - result = Either.right(updateDataRes); - } + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value())); } - if (result == null) { - componentVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis()); - Either<GraphVertex, JanusGraphOperationStatus> updateRes = janusGraphDao.updateVertex(componentVertex); - if (updateRes.isRight()) { - CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the component {}. Status is {} ", componentId, - updateRes.right().value()); - result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateRes.right().value())); + GraphVertex componentVertex = getComponentVertex.left().value(); + //update + List<PropertyDataDefinition> properties = group.getProperties(); + newGroupProperties.forEach(np -> { + Optional<PropertyDataDefinition> currentProp = properties.stream().filter(p -> p.getName().equals(np.getName())).findAny(); + if (currentProp.isPresent()) { + currentProp.get().setValue(np.getValue()); + currentProp.get().setToscaFunction(np.getToscaFunction()); } + }); + updateVersion(promoteMinorVersion, group); + StorageOperationStatus updateDataRes = updateToscaDataOfToscaElement(componentVertex, EdgeLabelEnum.GROUPS, VertexTypeEnum.GROUPS, group, + JsonPresentationFields.CI_INVARIANT_NAME); + if (updateDataRes != StorageOperationStatus.OK) { + log.debug("Failed to update properties for group {} error {}", group.getName(), updateDataRes); + return Either.right(updateDataRes); } - if (result == null) { - result = Either.left(newGroupProperties); + componentVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis()); + Either<GraphVertex, JanusGraphOperationStatus> updateRes = janusGraphDao.updateVertex(componentVertex); + if (updateRes.isRight()) { + CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update the component {}. Status is {} ", componentId, + updateRes.right().value()); + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateRes.right().value())); } - return result; + return Either.left(newGroupProperties); } public Either<List<GroupInstance>, StorageOperationStatus> updateGroupInstances(Component component, String instanceId, @@ -402,17 +387,10 @@ public class GroupsOperation extends BaseOperation { public Either<GroupInstance, StorageOperationStatus> updateGroupInstancePropertyValuesOnGraph(String componentId, String instanceId, GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties) { - Either<GraphVertex, JanusGraphOperationStatus> getComponentVertex = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseMetadata); - if (getComponentVertex.isRight()) { - CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId); - return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getComponentVertex.right().value())); - } List<PropertyDataDefinition> propertiesOld = oldGroupInstance.getProperties(); newProperties.forEach(np -> { Optional<PropertyDataDefinition> prop = propertiesOld.stream().filter(p -> p.getName().equals(np.getName())).findFirst(); - if (prop.isPresent()) { - prop.get().setValue(np.getValue()); - } + prop.ifPresent(propertyDataDefinition -> propertyDataDefinition.setValue(np.getValue())); }); GroupInstanceDataDefinition groupInstanceDataDefinition = new GroupInstanceDataDefinition(oldGroupInstance); List<String> pathKeys = new ArrayList<>(); diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.java index ccf7148f84..04d3a0bebe 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.java @@ -23,19 +23,26 @@ import fj.data.Either; import java.util.List; import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.GroupProperty; import org.openecomp.sdc.be.resources.data.ArtifactData; public interface IGroupOperation { - public Either<List<GraphRelation>, StorageOperationStatus> dissociateAllGroupsFromArtifactOnGraph(String componentId, - NodeTypeEnum componentTypeEnum, - String artifactId); + Either<List<GraphRelation>, StorageOperationStatus> dissociateAllGroupsFromArtifactOnGraph(String componentId, NodeTypeEnum componentTypeEnum, + String artifactId); - public StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, - ArtifactData newArtifact, boolean inTransaction); + StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, String oldArtifactId, + ArtifactData newArtifact, boolean inTransaction); - public boolean isGroupExist(String groupName, boolean inTransaction); + boolean isGroupExist(String groupName, boolean inTransaction); - public StorageOperationStatus validateAndUpdatePropertyValue(GroupProperty property); + /** + * Validates and updates the given property value based on the property type + * + * @param groupOwner the container component that owns the group instance that has the property + * @param property the group instance property to validate + * @return the status of the operation + */ + StorageOperationStatus validateAndUpdatePropertyValue(Component groupOwner, GroupProperty property); } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupInstanceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupInstanceOperation.java index c463af691c..67d9755808 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupInstanceOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupInstanceOperation.java @@ -56,6 +56,7 @@ import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator; import org.openecomp.sdc.be.resources.data.ArtifactData; import org.openecomp.sdc.be.resources.data.GroupInstanceData; import org.openecomp.sdc.be.resources.data.PropertyData; @@ -71,12 +72,20 @@ public class GroupInstanceOperation extends AbstractOperation implements IGroupI private static final String UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE = "UpdatePropertyValueOnComponentInstance"; private static final String FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS = "Failed to update property value on instance. Status is "; private static final Logger log = Logger.getLogger(GroupInstanceOperation.class.getName()); + private final GroupOperation groupOperation; + private final PropertyOperation propertyOperation; + private final ToscaFunctionValidator toscaFunctionValidator; + private final ApplicationDataTypeCache applicationDataTypeCache; + @Autowired - GroupOperation groupOperation; - @Autowired - PropertyOperation propertyOperation; - @javax.annotation.Resource - private ApplicationDataTypeCache applicationDataTypeCache; + public GroupInstanceOperation(final GroupOperation groupOperation, final PropertyOperation propertyOperation, + final ToscaFunctionValidator toscaFunctionValidator, + final ApplicationDataTypeCache applicationDataTypeCache) { + this.groupOperation = groupOperation; + this.propertyOperation = propertyOperation; + this.toscaFunctionValidator = toscaFunctionValidator; + this.applicationDataTypeCache = applicationDataTypeCache; + } public Either<List<GroupInstance>, StorageOperationStatus> getAllGroupInstances(String parentId, NodeTypeEnum parentType) { Either<List<GroupInstance>, StorageOperationStatus> result = null; @@ -358,46 +367,47 @@ public class GroupInstanceOperation extends AbstractOperation implements IGroupI * * @return */ - public Either<PropertyValueData, JanusGraphOperationStatus> updatePropertyOfGroupInstance(ComponentInstanceProperty groupInstanceProerty, + public Either<PropertyValueData, JanusGraphOperationStatus> updatePropertyOfGroupInstance(ComponentInstanceProperty groupInstanceProperty, String groupInstanceId) { Wrapper<JanusGraphOperationStatus> errorWrapper = new Wrapper<>(); UpdateDataContainer<PropertyData, PropertyValueData> updateDataContainer = new UpdateDataContainer<>(GraphEdgeLabels.PROPERTY_IMPL, (() -> PropertyData.class), (() -> PropertyValueData.class), NodeTypeEnum.Property, NodeTypeEnum.PropertyValue); - preUpdateElementOfResourceInstanceValidations(updateDataContainer, groupInstanceProerty, groupInstanceId, errorWrapper); + preUpdateElementOfResourceInstanceValidations(updateDataContainer, groupInstanceProperty, groupInstanceId, errorWrapper); if (!errorWrapper.isEmpty()) { return Either.right(errorWrapper.getInnerElement()); + } + + String value = groupInstanceProperty.getValue(); + // Specific Validation Logic + PropertyData propertyData = updateDataContainer.getDataWrapper().getInnerElement(); + PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition(); + String propertyType = propDataDef.getType(); + final ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType); + final Either<String, JanusGraphOperationStatus> innerTypeEither = propertyOperation.getInnerType(type, propDataDef::getSchema); + if (innerTypeEither.isRight()) { + return Either.right(innerTypeEither.right().value()); + } + // Specific Update Logic + Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes = + applicationDataTypeCache.getAll(groupInstanceProperty.getModel()); + if (allDataTypes.isRight()) { + JanusGraphOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance() + .logInternalFlowError(UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE, FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS + status, + ErrorSeverity.ERROR); + return Either.right(status); + } + PropertyValueData propertyValueData = updateDataContainer.getValueDataWrapper().getInnerElement(); + if (propDataDef.isToscaFunction()) { + Either<GroupInstanceData, JanusGraphOperationStatus> findResInstanceRes = janusGraphGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupInstance), groupInstanceId, GroupInstanceData.class); + final GroupInstanceData groupInstanceData = findResInstanceRes.left().value(); + //TODO fix + toscaFunctionValidator.validate(propDataDef, null); + propertyValueData.setValue(propDataDef.getToscaFunction().getValue()); } else { - String value = groupInstanceProerty.getValue(); - // Specific Validation Logic - PropertyData propertyData = updateDataContainer.getDataWrapper().getInnerElement(); - String innerType = null; - PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition(); - String propertyType = propDataDef.getType(); - ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); - log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType); - if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { - SchemaDefinition def = propDataDef.getSchema(); - if (def == null) { - log.debug("Schema doesn't exists for property of type {}", type); - return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT); - } - PropertyDataDefinition propDef = def.getProperty(); - if (propDef == null) { - log.debug("Property in Schema Definition inside property of type {} doesn't exist", type); - return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT); - } - innerType = propDef.getType(); - } - // Specific Update Logic - Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes = - applicationDataTypeCache.getAll(groupInstanceProerty.getModel()); - if (allDataTypes.isRight()) { - JanusGraphOperationStatus status = allDataTypes.right().value(); - BeEcompErrorManager.getInstance() - .logInternalFlowError(UPDATE_PROPERTY_VALUE_ON_COMPONENT_INSTANCE, FAILED_TO_UPDATE_PROPERTY_VALUE_ON_INSTANCE_STATUS_IS + status, - ErrorSeverity.ERROR); - return Either.right(status); - } + final String innerType = innerTypeEither.left().value(); Either<Object, Boolean> isValid = propertyOperation .validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes.left().value()); String newValue = value; @@ -412,25 +422,25 @@ public class GroupInstanceOperation extends AbstractOperation implements IGroupI newValue = object.toString(); } } - PropertyValueData propertyValueData = updateDataContainer.getValueDataWrapper().getInnerElement(); log.debug("Going to update property value from {} to {}", propertyValueData.getValue(), newValue); propertyValueData.setValue(newValue); ImmutablePair<String, Boolean> pair = propertyOperation - .validateAndUpdateRules(propertyType, groupInstanceProerty.getRules(), innerType, allDataTypes.left().value(), true); + .validateAndUpdateRules(propertyType, groupInstanceProperty.getRules(), innerType, allDataTypes.left().value(), true); if (pair.getRight() != null && !pair.getRight()) { BeEcompErrorManager.getInstance() - .logBeInvalidValueError("Add property value", pair.getLeft(), groupInstanceProerty.getName(), propertyType); + .logBeInvalidValueError("Add property value", pair.getLeft(), groupInstanceProperty.getName(), propertyType); return Either.right(JanusGraphOperationStatus.ILLEGAL_ARGUMENT); } - propertyOperation.updateRulesInPropertyValue(propertyValueData, groupInstanceProerty, groupInstanceId); - Either<PropertyValueData, JanusGraphOperationStatus> updateRes = janusGraphGenericDao - .updateNode(propertyValueData, PropertyValueData.class); - if (updateRes.isRight()) { - JanusGraphOperationStatus status = updateRes.right().value(); - return Either.right(status); - } else { - return Either.left(updateRes.left().value()); - } + } + + propertyOperation.updateRulesInPropertyValue(propertyValueData, groupInstanceProperty, groupInstanceId); + Either<PropertyValueData, JanusGraphOperationStatus> updateRes = janusGraphGenericDao + .updateNode(propertyValueData, PropertyValueData.class); + if (updateRes.isRight()) { + JanusGraphOperationStatus status = updateRes.right().value(); + return Either.right(status); + } else { + return Either.left(updateRes.left().value()); } } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java index a57f32d336..ce4696fa9f 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java @@ -34,9 +34,9 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; -import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; @@ -44,6 +44,7 @@ import org.openecomp.sdc.be.dao.utils.MapUtil; import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.GroupDefinition; import org.openecomp.sdc.be.model.GroupProperty; @@ -62,9 +63,8 @@ import org.openecomp.sdc.be.resources.data.PropertyData; import org.openecomp.sdc.be.resources.data.PropertyValueData; import org.openecomp.sdc.be.resources.data.UniqueIdData; import org.openecomp.sdc.common.log.wrappers.Logger; -import org.springframework.stereotype.Component; -@Component +@org.springframework.stereotype.Component public class GroupOperation extends AbstractOperation implements IGroupOperation { private static final Logger log = Logger.getLogger(GroupOperation.class.getName()); @@ -481,33 +481,20 @@ public class GroupOperation extends AbstractOperation implements IGroupOperation return result; } - public StorageOperationStatus validateAndUpdatePropertyValue(GroupProperty property) { - StorageOperationStatus result = null; - String innerType = - property.getSchema() == null ? null : property.getSchema().getProperty() == null ? null : property.getSchema().getProperty().getType(); + public StorageOperationStatus validateAndUpdatePropertyValue(final Component groupOwner, final GroupProperty property) { Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> allDataTypes = applicationDataTypeCache.getAll(property.getModel()); - Either<Object, Boolean> isValid = null; if (allDataTypes.isRight()) { JanusGraphOperationStatus status = allDataTypes.right().value(); log.debug("Failed to fetch data types from cache. Status is {}. ", status); - result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status); - } - if (result == null) { - isValid = propertyOperation.validateAndUpdatePropertyValue(property.getType(), property.getValue(), innerType, - allDataTypes.left().value()); - if (isValid.isRight()) { - log.debug("Failed to validate property value {}. Status is {}. ", property.getValue(), StorageOperationStatus.INVALID_PROPERTY); - result = StorageOperationStatus.INVALID_PROPERTY; - } + return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status); } - if (result == null) { - if (isValid.left().value() != null) { - String validValue = String.valueOf(isValid.left().value()); - property.setValue(validValue); - } - result = StorageOperationStatus.OK; + + Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(groupOwner, property, allDataTypes.left().value()); + if (isValid.isRight()) { + log.debug("Failed to validate property value {}. Status is {}. ", property.getValue(), StorageOperationStatus.INVALID_PROPERTY); + return StorageOperationStatus.INVALID_PROPERTY; } - return result; + return StorageOperationStatus.OK; } public StorageOperationStatus updateGroupProperties(org.openecomp.sdc.be.model.Component containerComponent, String groupId, diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java index 931d5993ea..b66f6c9433 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java @@ -76,11 +76,13 @@ import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyRule; import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.IComplexDefaultValue; import org.openecomp.sdc.be.model.PropertyConstraint; import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator; import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation; import org.openecomp.sdc.be.model.operations.api.IPropertyOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; @@ -103,9 +105,8 @@ import org.openecomp.sdc.be.resources.data.ResourceMetadataData; import org.openecomp.sdc.be.resources.data.UniqueIdData; import org.openecomp.sdc.common.log.wrappers.Logger; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; -@Component("property-operation") +@org.springframework.stereotype.Component("property-operation") public class PropertyOperation extends AbstractOperation implements IPropertyOperation { private static final String AFTER_RETRIEVING_DERIVED_FROM_NODE_OF_STATUS_IS = "After retrieving DERIVED_FROM node of {}. status is {}"; @@ -121,6 +122,7 @@ public class PropertyOperation extends AbstractOperation implements IPropertyOpe private static final String UPDATE_DATA_TYPE = "UpdateDataType"; private static final Logger log = Logger.getLogger(PropertyOperation.class.getName()); private final DerivedFromOperation derivedFromOperation; + private ToscaFunctionValidator toscaFunctionValidator; private DataTypeOperation dataTypeOperation; @Autowired @@ -129,6 +131,11 @@ public class PropertyOperation extends AbstractOperation implements IPropertyOpe this.derivedFromOperation = derivedFromOperation; } + @Autowired + public void setToscaFunctionValidator(final ToscaFunctionValidator toscaFunctionValidator) { + this.toscaFunctionValidator = toscaFunctionValidator; + } + //circular dependency DataTypeOperation->ModelOperation->ModelElementOperation->PropertyOperation @Autowired public void setDataTypeOperation(DataTypeOperation dataTypeOperation) { @@ -1645,7 +1652,7 @@ public class PropertyOperation extends AbstractOperation implements IPropertyOpe public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> dataTypes) { log.trace("Going to validate property value and its type. type = {}, value = {}", propertyType, value); - ToscaPropertyType type = getType(propertyType); + final ToscaPropertyType type = getType(propertyType); if (isValidate) { if (type == null) { DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType); @@ -1679,6 +1686,155 @@ public class PropertyOperation extends AbstractOperation implements IPropertyOpe return validateAndUpdatePropertyValue(propertyType, value, true, innerType, dataTypes); } + public Either<Object, Boolean> validateAndUpdatePropertyValue(final Component containerComponent, final PropertyDataDefinition property, + final Map<String, DataTypeDefinition> dataTypes) { + if (property.isToscaFunction()) { + toscaFunctionValidator.validate(property, containerComponent); + property.setValue(property.getToscaFunction().getValue()); + return Either.left(property.getValue()); + } + Either<String, JanusGraphOperationStatus> checkInnerType = checkInnerType(property); + if (checkInnerType.isRight()) { + return Either.right(false); + } + final String innerType = checkInnerType.left().value(); + return validateAndUpdatePropertyValue(property.getType(), property.getValue(), true, innerType, dataTypes); + } + +// private <T extends PropertyDefinition> void validateToscaGetFunction(T property, org.openecomp.sdc.be.model.Component parentComponent) { +// 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) { +// 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 <T extends PropertyDefinition> void validateGetFunction(final T property, +// final List<? extends ToscaPropertyData> parentProperties, +// final String model) { +// final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) property.getToscaFunction(); +// if (CollectionUtils.isEmpty(parentProperties)) { +// throw ToscaGetFunctionExceptionSupplier +// .propertyNotFoundOnTarget(toscaGetFunction.getPropertyName(), toscaGetFunction.getPropertySource(), +// toscaGetFunction.getFunctionType() +// ).get(); +// } +// final String getFunctionPropertyUniqueId = toscaGetFunction.getPropertyUniqueId(); +// ToscaPropertyData referredProperty = parentProperties.stream() +// .filter(property1 -> getFunctionPropertyUniqueId.equals(property1.getUniqueId())) +// .findFirst() +// .orElseThrow(ToscaGetFunctionExceptionSupplier +// .propertyNotFoundOnTarget(toscaGetFunction.getPropertyName(), toscaGetFunction.getPropertySource() +// , toscaGetFunction.getFunctionType()) +// ); +// if (toscaGetFunction.isSubProperty()) { +// referredProperty = findSubProperty(referredProperty, toscaGetFunction, model); +// } +// +// if (!property.getType().equals(referredProperty.getType())) { +// throw ToscaGetFunctionExceptionSupplier +// .propertyTypeDiverge(toscaGetFunction.getType(), referredProperty.getType(), property.getType()).get(); +// } +// if (PropertyType.typeHasSchema(referredProperty.getType()) && !referredProperty.getSchemaType().equals(property.getSchemaType())) { +// throw ToscaGetFunctionExceptionSupplier +// .propertySchemaDiverge(toscaGetFunction.getType(), referredProperty.getSchemaType(), property.getSchemaType()).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 void validateGetPropertySource(final ToscaGetFunctionType functionType, final PropertySource propertySource) { +// 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 ToscaPropertyData findSubProperty(final ToscaPropertyData referredProperty, +// final ToscaGetFunctionDataDefinition toscaGetFunction, +// final String model) { +// final Map<String, DataTypeDefinition> dataTypeMap = loadDataTypes(model); +// final List<String> propertyPathFromSource = toscaGetFunction.getPropertyPathFromSource(); +// DataTypeDefinition dataType = dataTypeMap.get(referredProperty.getType()); +// if (dataType == null) { +// throw ToscaGetFunctionExceptionSupplier +// .propertyDataTypeNotFound(propertyPathFromSource.get(0), referredProperty.getType(), toscaGetFunction.getFunctionType()).get(); +// } +// ToscaPropertyData foundProperty = referredProperty; +// for (int i = 1; i < propertyPathFromSource.size(); i++) { +// final String currentPropertyName = propertyPathFromSource.get(i); +// foundProperty = dataType.getProperties().stream() +// .filter(propertyDefinition -> currentPropertyName.equals(propertyDefinition.getName())).findFirst() +// .orElseThrow( +// ToscaGetFunctionExceptionSupplier +// .propertyNotFoundOnTarget(propertyPathFromSource.subList(0, i), toscaGetFunction.getPropertySource(), +// toscaGetFunction.getFunctionType()) +// ); +// dataType = dataTypeMap.get(foundProperty.getType()); +// if (dataType == null) { +// throw ToscaGetFunctionExceptionSupplier +// .propertyDataTypeNotFound(propertyPathFromSource.subList(0, i), foundProperty.getType(), +// toscaGetFunction.getFunctionType()).get(); +// } +// } +// return foundProperty; +// } + public <T extends GraphNode> Either<List<PropertyDefinition>, StorageOperationStatus> getAllPropertiesRec(String uniqueId, NodeTypeEnum nodeType, Class<T> clazz) { return this.findPropertiesOfNode(nodeType, uniqueId).right().bind(this::handleNotFoundProperties).left() diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.java index d773f03e56..13a6302c5c 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.java @@ -31,7 +31,6 @@ import org.openecomp.sdc.common.util.GsonFactory; public class JsonConverter implements PropertyValueConverter { private static JsonConverter jsonConverter = new JsonConverter(); - private static JsonParser jsonParser = new JsonParser(); private static Gson gson = GsonFactory.getGson(); private JsonConverter() { @@ -46,7 +45,7 @@ public class JsonConverter implements PropertyValueConverter { StringReader reader = new StringReader(value); JsonReader jsonReader = new JsonReader(reader); jsonReader.setLenient(true); - JsonElement jsonElement = jsonParser.parse(jsonReader); + JsonElement jsonElement = JsonParser.parseReader(jsonReader); if (jsonElement.isJsonPrimitive()) { return value; } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java index fb4e12c6a4..0a537a5445 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java @@ -212,9 +212,9 @@ public class DataTypeValidatorConverter { if (value == null || value.isEmpty()) { return trueEmptyResult; } - JsonElement jsonElement = null; + final JsonElement jsonElement; try { - jsonElement = jsonParser.parse(value); + jsonElement = JsonParser.parseString(value); } catch (JsonSyntaxException e) { return falseResult; } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/validation/ToscaFunctionValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/validation/ToscaFunctionValidator.java new file mode 100644 index 0000000000..b667e6367a --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/validation/ToscaFunctionValidator.java @@ -0,0 +1,41 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.validation; + +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.model.Component; + +/** + * Represents a validator for a property that has a TOSCA function value + */ +@org.springframework.stereotype.Component +public interface ToscaFunctionValidator { + + /** + * Validates the given property that has a TOSCA function value. Should throw a RuntimeException in case of failure. + * + * @param property the property with a tosca function to validate + * @param containerComponent the component that is the container for the instance that has the property + * @param <T> a property data definition + */ + <T extends PropertyDataDefinition> void validate(T property, Component containerComponent); +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/config/ModelOperationsSpringConfig.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/config/ModelOperationsSpringConfig.java index 28e17b5075..f8bbd0aac0 100644 --- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/config/ModelOperationsSpringConfig.java +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/config/ModelOperationsSpringConfig.java @@ -20,6 +20,9 @@ package org.openecomp.sdc.be.model.config; +import org.mockito.Mockito; +import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; @@ -32,4 +35,11 @@ import org.springframework.context.annotation.PropertySource; "org.openecomp.sdc.be.model.jsonjanusgraph.config", "org.openecomp.sdc.be.model.operations.impl"}) @PropertySource("classpath:dao.properties") -public class ModelOperationsSpringConfig { } +public class ModelOperationsSpringConfig { + + @Bean + public ToscaFunctionValidator toscaFunctionValidator() { + return Mockito.mock(ToscaFunctionValidator.class); + } + +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/config/ToscaValidationMockSpringConfig.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/config/ToscaValidationMockSpringConfig.java new file mode 100644 index 0000000000..ba834b1c1a --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/config/ToscaValidationMockSpringConfig.java @@ -0,0 +1,45 @@ +/* + * - + * ============LICENSE_START======================================================= + * Copyright (C) 2022 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.config; + +import org.mockito.Mockito; +import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Configure a {@link ToscaFunctionValidator} mock as a Spring Bean for Spring tests + */ +@Configuration +public class ToscaValidationMockSpringConfig { + + /** + * Configures the {@link ToscaFunctionValidator} mock as Sprint Bean + * + * @return the {@link ToscaFunctionValidator} mock + */ + @Bean + public ToscaFunctionValidator toscaFunctionValidator() { + return Mockito.mock(ToscaFunctionValidator.class); + } + +} diff --git a/catalog-model/src/test/resources/application-context-test.xml b/catalog-model/src/test/resources/application-context-test.xml index 7f4ada2696..47c41bd62a 100644 --- a/catalog-model/src/test/resources/application-context-test.xml +++ b/catalog-model/src/test/resources/application-context-test.xml @@ -11,6 +11,8 @@ org.openecomp.sdc.be.dao.jsongraph, org.openecomp.sdc.be.model.cache, org.openecomp.sdc.be.client, + org.openecomp.sdc.be.model.validation, + org.openecomp.sdc.be.model.config, org.openecomp.sdc.be.dao.janusgraph, org.openecomp.sdc.be.dao.cassandra, org.openecomp.sdc.be.model.jsonjanusgraph.utils, |