diff options
Diffstat (limited to 'catalog-model')
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, |