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-be/src/main/java | |
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-be/src/main/java')
7 files changed, 282 insertions, 69 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java index a1f28299a1..1f6d2a4601 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java @@ -336,29 +336,6 @@ public abstract class BaseBusinessLogic { return cmpt; } - <T extends PropertyDataDefinition> String updateInputPropertyObjectValue(T property) { - String propertyType = property.getType(); - String innerType = getInnerType(property); - // Specific Update Logic - Either<Object, Boolean> isValid = propertyOperation - .validateAndUpdatePropertyValue(propertyType, property.getValue(), true, innerType, - componentsUtils.getAllDataTypes(applicationDataTypeCache, property.getModel())); - String newValue = property.getValue(); - if (isValid.isRight()) { - Boolean res = isValid.right().value(); - if (Boolean.FALSE.equals(res)) { - throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse( - DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT))); - } - } else { - Object object = isValid.left().value(); - if (object != null) { - newValue = object.toString(); - } - } - return newValue; - } - <T extends PropertyDataDefinition> String getInnerType(T property) { ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType()); log.debug("#getInnerType - The type of the property {} is {}", property.getUniqueId(), property.getType()); 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 76db103525..577c49106c 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 @@ -48,7 +48,6 @@ import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; -import org.openecomp.sdc.be.components.impl.exceptions.ToscaFunctionExceptionSupplier; import org.openecomp.sdc.be.components.impl.exceptions.ToscaGetFunctionExceptionSupplier; import org.openecomp.sdc.be.components.impl.instance.ComponentInstanceChangeOperationOrchestrator; import org.openecomp.sdc.be.components.impl.utils.DirectivesUtil; @@ -130,6 +129,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; @@ -184,6 +184,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { private CompositionBusinessLogic compositionBusinessLogic; @Autowired private ContainerInstanceTypesData containerInstanceTypesData; + private final ToscaFunctionValidator toscaFunctionValidator; @Autowired public ComponentInstanceBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, @@ -193,7 +194,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { ComponentInstanceMergeDataBusinessLogic compInstMergeDataBL, ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator, ForwardingPathOperation forwardingPathOperation, NodeFilterOperation nodeFilterOperation, - ArtifactsOperations artifactToscaOperation) { + ArtifactsOperations artifactToscaOperation, final ToscaFunctionValidator toscaFunctionValidator) { super(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation, artifactToscaOperation); this.componentInstanceOperation = componentInstanceOperation; @@ -202,6 +203,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { this.onChangeInstanceOperationOrchestrator = onChangeInstanceOperationOrchestrator; this.forwardingPathOperation = forwardingPathOperation; this.nodeFilterOperation = nodeFilterOperation; + this.toscaFunctionValidator = toscaFunctionValidator; } public ComponentInstance createComponentInstance(String containerComponentParam, String containerComponentId, String userId, @@ -1962,12 +1964,7 @@ public class ComponentInstanceBusinessLogic extends BaseBusinessLogic { validatePropertyExistsOnComponent(property, containerComponent, foundResourceInstance); String propertyParentUniqueId = property.getParentUniqueId(); if (property.isToscaFunction()) { - if (property.getToscaFunction().getType() == null) { - throw ToscaFunctionExceptionSupplier.missingFunctionType().get(); - } - if (property.isToscaGetFunction()) { - validateToscaGetFunction(property, containerComponent); - } + toscaFunctionValidator.validate(property, containerComponent); property.setValue(property.getToscaFunction().getValue()); } Either<String, ResponseFormat> updatedPropertyValue = updatePropertyObjectValue(property, containerComponent.getModel()); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogic.java index ae9ab04a87..e24b414878 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogic.java @@ -58,6 +58,7 @@ import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; import org.openecomp.sdc.be.config.ConfigurationManager; 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.datatypes.elements.ArtifactDataDefinition; import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType; @@ -96,6 +97,8 @@ import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.jsongraph.util.CommonUtility; +import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum; import org.openecomp.sdc.common.log.elements.LoggerSupportability; import org.openecomp.sdc.common.log.enums.LogLevel; import org.openecomp.sdc.common.log.enums.LoggerSupportabilityActions; @@ -801,23 +804,29 @@ public class GroupBusinessLogic extends BaseBusinessLogic { public Either<GroupInstance, ResponseFormat> validateAndUpdateGroupInstancePropertyValues(String componentId, String instanceId, GroupInstance oldGroupInstance, List<GroupInstanceProperty> newProperties) { - Either<GroupInstance, ResponseFormat> actionResult = null; - List<GroupInstanceProperty> validatedReducedNewProperties = validateReduceGroupInstancePropertiesBeforeUpdate(oldGroupInstance, newProperties); - Either<GroupInstance, StorageOperationStatus> updateGroupInstanceResult = groupsOperation + final Either<Component, StorageOperationStatus> ownerComponentEither = + toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll); + if (ownerComponentEither.isRight()) { + CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch component {}. Status is {} ", componentId); + final ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(ownerComponentEither.right().value()); + return Either.right(componentsUtils.getResponseFormat(actionStatus, componentId)); + } + + final List<GroupInstanceProperty> validatedReducedNewProperties = + validateReduceGroupInstancePropertiesBeforeUpdate(ownerComponentEither.left().value(), oldGroupInstance, newProperties); + final Either<GroupInstance, StorageOperationStatus> updateGroupInstanceResult = groupsOperation .updateGroupInstancePropertyValuesOnGraph(componentId, instanceId, oldGroupInstance, validatedReducedNewProperties); if (updateGroupInstanceResult.isRight()) { log.debug("Failed to update group instance {} property values. ", oldGroupInstance.getName()); - actionResult = Either + return Either .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateGroupInstanceResult.right().value()))); } - if (actionResult == null) { - actionResult = Either.left(updateGroupInstanceResult.left().value()); - } - return actionResult; + return Either.left(updateGroupInstanceResult.left().value()); } - private List<GroupInstanceProperty> validateReduceGroupInstancePropertiesBeforeUpdate(GroupInstance oldGroupInstance, - List<GroupInstanceProperty> newProperties) { + private List<GroupInstanceProperty> validateReduceGroupInstancePropertiesBeforeUpdate(final Component groupOwnerComponent, + final GroupInstance oldGroupInstance, + final List<GroupInstanceProperty> newProperties) { Boolean validationRes = null; List<GroupInstanceProperty> actionResult = null; Map<String, GroupInstanceProperty> existingProperties = oldGroupInstance.convertToGroupInstancesProperties().stream() @@ -828,7 +837,8 @@ public class GroupBusinessLogic extends BaseBusinessLogic { try { for (GroupInstanceProperty currNewProperty : newProperties) { currPropertyName = currNewProperty.getName(); - validationRes = handleAndAddProperty(reducedProperties, newPropertyValues, currNewProperty, existingProperties.get(currPropertyName)); + validationRes = handleAndAddProperty(groupOwnerComponent, reducedProperties, newPropertyValues, + currNewProperty, existingProperties.get(currPropertyName)); } if (validationRes == null || validationRes) { Map<PropertyNames, String> existingPropertyValues = new EnumMap<>(PropertyNames.class); @@ -858,27 +868,25 @@ public class GroupBusinessLogic extends BaseBusinessLogic { } } - private Boolean handleAndAddProperty(List<GroupInstanceProperty> reducedProperties, Map<PropertyNames, String> newPropertyValues, - GroupInstanceProperty currNewProperty, GroupInstanceProperty currExistingProperty) { - Boolean validationRes = null; - String currPropertyName = currNewProperty.getName(); - PropertyNames propertyName = PropertyNames.findName(currPropertyName); + private boolean handleAndAddProperty(final Component groupOwner, final List<GroupInstanceProperty> reducedProperties, + final Map<PropertyNames, String> newPropertyValues, final GroupInstanceProperty currNewProperty, + final GroupInstanceProperty currExistingProperty) { + final String currPropertyName = currNewProperty.getName(); + final PropertyNames propertyName = PropertyNames.findName(currPropertyName); try { if (currExistingProperty == null) { log.warn("The value of property with the name {} cannot be updated. The property not found on group instance. ", currPropertyName); } else if (isUpdatable(propertyName)) { - validationRes = validateAndUpdatePropertyValue(currNewProperty, currExistingProperty); + validateAndUpdatePropertyValue(groupOwner, currNewProperty, currExistingProperty); addPropertyUpdatedValues(reducedProperties, propertyName, newPropertyValues, currNewProperty, currExistingProperty); } else { validateImmutableProperty(currExistingProperty, currNewProperty); } - if (validationRes == null) { - validationRes = true; - } - } catch (Exception e) { - log.error("Exception occured during handle and adding property. The message is {}", e.getMessage(), e); + } catch (final Exception e) { + log.error("Exception occurred during handle and adding property. The message is {}", e.getMessage(), e); + return false; } - return validationRes; + return true; } private boolean isUpdatable(PropertyNames updatablePropertyName) { @@ -918,7 +926,8 @@ public class GroupBusinessLogic extends BaseBusinessLogic { return result; } - private Boolean validateAndUpdatePropertyValue(GroupInstanceProperty newProperty, GroupInstanceProperty existingProperty) { + private void validateAndUpdatePropertyValue(final Component groupOwner, final GroupInstanceProperty newProperty, + final GroupInstanceProperty existingProperty) { String parentValue = existingProperty.getParentValue(); newProperty.setParentValue(parentValue); if (StringUtils.isEmpty(newProperty.getValue())) { @@ -927,13 +936,12 @@ public class GroupBusinessLogic extends BaseBusinessLogic { if (StringUtils.isEmpty(existingProperty.getValue())) { existingProperty.setValue(parentValue); } - StorageOperationStatus status = groupOperation.validateAndUpdatePropertyValue(newProperty); + StorageOperationStatus status = groupOperation.validateAndUpdatePropertyValue(groupOwner, newProperty); if (status != StorageOperationStatus.OK) { log.debug("Failed to validate property value {} of property with name {}. Status is {}. ", newProperty.getValue(), newProperty.getName(), status); throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse(status)); } - return true; } private void validateImmutableProperty(GroupProperty oldProperty, GroupProperty newProperty) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogicNew.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogicNew.java index e810999504..25b62bb44f 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogicNew.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogicNew.java @@ -86,7 +86,7 @@ public class GroupBusinessLogicNew { List<GroupProperty> newProperties) { Component component = accessValidations.validateUserCanWorkOnComponent(componentId, componentType, userId, "UPDATE GROUP PROPERTIES"); GroupDefinition currentGroup = getGroup(component, groupUniqueId); - validateUpdatedPropertiesAndSetEmptyValues(currentGroup, newProperties); + validateUpdatedPropertiesAndSetEmptyValues(component, currentGroup, newProperties); return groupsOperation.updateGroupPropertiesOnComponent(componentId, currentGroup, newProperties, PromoteVersionEnum.MINOR).left() .on(this::onUpdatePropertyError); } @@ -122,7 +122,7 @@ public class GroupBusinessLogicNew { () -> new ByActionStatusComponentException(ActionStatus.GROUP_IS_MISSING, component.getSystemName(), component.getActualComponentType())); } - private void validateUpdatedPropertiesAndSetEmptyValues(GroupDefinition originalGroup, List<GroupProperty> groupPropertiesToUpdate) { + private void validateUpdatedPropertiesAndSetEmptyValues(Component groupOwner, GroupDefinition originalGroup, List<GroupProperty> groupPropertiesToUpdate) { if (CollectionUtils.isEmpty(groupPropertiesToUpdate)) { throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, StringUtils.EMPTY); } @@ -140,13 +140,10 @@ public class GroupBusinessLogicNew { if (!isOnlyGroupPropertyValueChanged(gp, originalProperties.get(updatedPropertyName))) { throw new ByActionStatusComponentException(ActionStatus.INVALID_PROPERTY, updatedPropertyName); } - if (gp.hasToscaFunction()) { - gp.setValue(gp.getToscaFunction().getValue()); - } if (StringUtils.isEmpty(gp.getValue())) { gp.setValue(originalProperties.get(updatedPropertyName).getDefaultValue()); } - StorageOperationStatus sos = groupOperation.validateAndUpdatePropertyValue(gp); + StorageOperationStatus sos = groupOperation.validateAndUpdatePropertyValue(groupOwner, gp); if (StorageOperationStatus.OK != sos) { throw new StorageException(sos, updatedPropertyName); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PolicyBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PolicyBusinessLogic.java index 2f01ef3ecc..f536cffaba 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PolicyBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PolicyBusinessLogic.java @@ -45,6 +45,7 @@ import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; import org.openecomp.sdc.be.components.property.PropertyDeclarationOrchestrator; import org.openecomp.sdc.be.components.validation.PolicyUtils; import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.datatypes.elements.GetPolicyValueDataDefinition; import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType; @@ -67,6 +68,7 @@ import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation; import org.openecomp.sdc.be.model.operations.api.IGroupOperation; import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; import org.openecomp.sdc.common.datastructure.Wrapper; import org.openecomp.sdc.common.log.elements.LoggerSupportability; @@ -624,7 +626,10 @@ public class PolicyBusinessLogic extends BaseBusinessLogic { filter.setIgnorePolicies(false); filter.setIgnoreUsers(false); filter.setIgnoreComponentInstances(false); + filter.setIgnoreComponentInstancesAttributes(false); + filter.setIgnoreComponentInstancesProperties(false); filter.setIgnoreGroups(false); + filter.setIgnoreInputs(false); return validateComponentExists(componentId, componentType, filter); } @@ -636,7 +641,7 @@ public class PolicyBusinessLogic extends BaseBusinessLogic { private PolicyDefinition validateAndUpdatePolicyProperties(Component component, String policyId, PropertyDataDefinition[] properties) { PolicyDefinition policyById = getPolicyById(component, policyId); - policyById = validateUpdatePolicyPropertiesBeforeUpdate(policyById, properties); + policyById = validateUpdatePolicyPropertiesBeforeUpdate(component, policyById, properties); return updatePolicyOfComponent(component.getUniqueId(), policyById); } @@ -645,16 +650,16 @@ public class PolicyBusinessLogic extends BaseBusinessLogic { .on(ce -> componentExceptionPolicyDefinition(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(ce)))); } - private PolicyDefinition validateUpdatePolicyPropertiesBeforeUpdate(PolicyDefinition policy, PropertyDataDefinition[] newProperties) { + private PolicyDefinition validateUpdatePolicyPropertiesBeforeUpdate(final Component policyOwnerComponent, PolicyDefinition policy, PropertyDataDefinition[] newProperties) { if (CollectionUtils.isEmpty(policy.getProperties())) { log.error( "#validateUpdatePolicyPropertiesBeforeUpdate - failed to update properites of the policy. Properties were not found on the policy. "); throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND); } - return updatePropertyValues(policy, newProperties); + return updatePropertyValues(policyOwnerComponent, policy, newProperties); } - private PolicyDefinition updatePropertyValues(PolicyDefinition policy, PropertyDataDefinition[] newProperties) { + private PolicyDefinition updatePropertyValues(final Component policyOwnerComponent, PolicyDefinition policy, PropertyDataDefinition[] newProperties) { Map<String, PropertyDataDefinition> oldProperties = policy.getProperties().stream() .collect(toMap(PropertyDataDefinition::getName, Function.identity())); for (PropertyDataDefinition newProperty : newProperties) { @@ -663,12 +668,34 @@ public class PolicyBusinessLogic extends BaseBusinessLogic { policy.getName()); throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND, newProperty.getName()); } - String newPropertyValueEither = updateInputPropertyObjectValue(newProperty); - oldProperties.get(newProperty.getName()).setValue(newPropertyValueEither); + final String newPropertyValueEither = updatePropertyValue(policyOwnerComponent, newProperty); + final PropertyDataDefinition currentProperty = oldProperties.get(newProperty.getName()); + currentProperty.setValue(newPropertyValueEither); + currentProperty.setToscaFunction(newProperty.getToscaFunction()); } return policy; } + private <T extends PropertyDataDefinition> String updatePropertyValue(final Component policyOwnerComponent, final T property) { + Either<Object, Boolean> isValid = propertyOperation + .validateAndUpdatePropertyValue(policyOwnerComponent, property, + componentsUtils.getAllDataTypes(applicationDataTypeCache, property.getModel()) + ); + if (isValid.isRight()) { + Boolean res = isValid.right().value(); + if (Boolean.FALSE.equals(res)) { + throw new ByActionStatusComponentException(componentsUtils.convertFromStorageResponse( + DaoStatusConverter.convertJanusGraphStatusToStorageStatus(JanusGraphOperationStatus.ILLEGAL_ARGUMENT))); + } + } else { + Object object = isValid.left().value(); + if (object != null) { + return object.toString(); + } + } + return property.getValue(); + } + private PolicyDefinition deletePolicy(Component component, String policyId) { PolicyDefinition policyById = getPolicyById(component, policyId); return removePolicyFromComponent(component, policyById); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/validation/ToscaFunctionValidatorImpl.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/validation/ToscaFunctionValidatorImpl.java new file mode 100644 index 0000000000..ed37347a45 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/validation/ToscaFunctionValidatorImpl.java @@ -0,0 +1,206 @@ +/* + * - + * ============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.components.impl.validation; + +import fj.data.Either; +import java.util.List; +import java.util.Map; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.onap.sdc.tosca.datatypes.model.PropertyType; +import org.openecomp.sdc.be.components.impl.exceptions.ToscaFunctionExceptionSupplier; +import org.openecomp.sdc.be.components.impl.exceptions.ToscaGetFunctionExceptionSupplier; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.PropertySource; +import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.ToscaPropertyData; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator; + +@org.springframework.stereotype.Component +public class ToscaFunctionValidatorImpl implements ToscaFunctionValidator { + + private final ApplicationDataTypeCache applicationDataTypeCache; + + public ToscaFunctionValidatorImpl(final ApplicationDataTypeCache applicationDataTypeCache) { + this.applicationDataTypeCache = applicationDataTypeCache; + } + + @Override + public <T extends PropertyDataDefinition> void validate(T property, final Component containerComponent) { + if (property.getToscaFunction().getType() == null) { + throw ToscaFunctionExceptionSupplier.missingFunctionType().get(); + } + if (property.isToscaGetFunction()) { + validateToscaGetFunction(property, containerComponent); + } + } + + private <T extends PropertyDataDefinition> void validateToscaGetFunction(T property, 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 PropertyDataDefinition> 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; + } + + private Map<String, DataTypeDefinition> loadDataTypes(String model) { + final Either<Map<String, DataTypeDefinition>, JanusGraphOperationStatus> dataTypeEither = + applicationDataTypeCache.getAll(model); + if (dataTypeEither.isRight()) { + throw ToscaGetFunctionExceptionSupplier.couldNotLoadDataTypes(model).get(); + } + return dataTypeEither.left().value(); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/config/CatalogBESpringConfig.java b/catalog-be/src/main/java/org/openecomp/sdc/config/CatalogBESpringConfig.java index 0c78b1fdef..b38210116c 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/config/CatalogBESpringConfig.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/config/CatalogBESpringConfig.java @@ -66,6 +66,7 @@ import org.springframework.core.annotation.Order; "org.openecomp.sdc.be.filters", "org.openecomp.sdc.be.plugins", "org.openecomp.sdc.be.togglz", + "org.openecomp.sdc.be.model.cache", "org.openecomp.sdc.be.ui.mapper"}) // @formatter:on public class CatalogBESpringConfig { |