diff options
29 files changed, 1270 insertions, 835 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 { diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java index 96c6762d74..3a5f40cb8c 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java @@ -49,13 +49,9 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Optional; import java.util.Set; -import java.util.stream.Stream; import mockit.Deencapsulation; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.assertj.core.util.Lists; @@ -64,17 +60,12 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestFactory; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; 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.validation.UserValidations; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.api.ActionStatus; @@ -129,6 +120,7 @@ import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.OperationE import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.GraphLockOperation; import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator; import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; import org.openecomp.sdc.common.api.ArtifactTypeEnum; import org.openecomp.sdc.common.api.ConfigurationSource; @@ -196,6 +188,8 @@ class ComponentInstanceBusinessLogicTest { private ContainerInstanceTypesData containerInstanceTypeData; @Mock private CompositionBusinessLogic compositionBusinessLogic; + @Mock + private ToscaFunctionValidator toscaFunctionValidator; private Component service; private Component resource; @@ -222,7 +216,7 @@ class ComponentInstanceBusinessLogicTest { void init() { MockitoAnnotations.openMocks(this); componentInstanceBusinessLogic = new ComponentInstanceBusinessLogic(null, null, null, null, null, null, null, artifactsBusinessLogic, null, - null, forwardingPathOperation, null, null); + null, forwardingPathOperation, null, null, toscaFunctionValidator); componentInstanceBusinessLogic.setComponentsUtils(componentsUtils); componentInstanceBusinessLogic.setToscaOperationFacade(toscaOperationFacade); componentInstanceBusinessLogic.setUserValidations(userValidations); @@ -369,408 +363,7 @@ class ComponentInstanceBusinessLogicTest { assertThat(responseFormatEither.left().value()).isEqualTo(properties); } - @Test - void testToscaGetFunctionValidation() { - final String userId = "userId"; - final String containerComponentId = "containerComponentId"; - final String containerComponentName = "containerComponentName"; - final String resourceInstanceId = "resourceInstanceId"; - final String inputName = "myInputToGet"; - final String inputId = String.format("%s.%s", containerComponentId, inputName); - final String schemaType = "string"; - //creating instance list of string property with get_input value - final ComponentInstanceProperty propertyGetInput = new ComponentInstanceProperty(); - propertyGetInput.setName("getInputProperty"); - propertyGetInput.setPropertyId(String.format("%s.%s", containerComponentId, "getInputProperty")); - propertyGetInput.setValue(String.format("get_input: [\"%s\"]", inputName)); - propertyGetInput.setType("list"); - final SchemaDefinition listStringPropertySchema = createSchema(schemaType); - propertyGetInput.setSchema(listStringPropertySchema); - propertyGetInput.setToscaFunction( - createGetToscaFunction(inputName, inputId, List.of(propertyGetInput.getName()), PropertySource.SELF, ToscaGetFunctionType.GET_INPUT, - containerComponentId, containerComponentName) - ); - //creating instance map of string property with get_input value to a second level property: - // get_input: ["property1", "subProperty1", "subProperty2"] - final String getPropertyPropertyName = "getPropertyProperty"; - final List<String> containerPropertyPath = List.of("property1", "subProperty1", "subProperty2"); - final String containerPropertyId = String.format("%s.%s", containerComponentId, containerPropertyPath.get(0)); - final String mapToscaType = "map"; - final ComponentInstanceProperty propertyGetProperty = createComponentInstanceProperty( - String.format("%s.%s", containerComponentId, getPropertyPropertyName), - getPropertyPropertyName, - mapToscaType, - "string", - String.format("\"get_property\": [\"%s\", \"%s\"]", PropertySource.SELF, String.join("\", \"", containerPropertyPath)), - createGetToscaFunction(containerPropertyPath.get(containerPropertyPath.size() - 1), containerPropertyId, - containerPropertyPath, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, containerComponentId, containerComponentName) - ); - - //creating component that has the instance properties - final Component component = new Service(); - component.setUniqueId(containerComponentId); - component.setName(containerComponentName); - component.setLastUpdaterUserId(userId); - component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); - //adding instance properties to the component - final List<ComponentInstanceProperty> resourceInstanceProperties = List.of(propertyGetInput, propertyGetProperty); - final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>(); - componentInstanceProps.put(resourceInstanceId, resourceInstanceProperties); - component.setComponentInstancesProperties(componentInstanceProps); - - //creating component input that will be gotten by the get_input instance property - final var inputDefinition = new InputDefinition(); - inputDefinition.setName(inputName); - inputDefinition.setUniqueId(inputId); - inputDefinition.setType(propertyGetInput.getType()); - inputDefinition.setSchema(listStringPropertySchema); - component.setInputs(List.of(inputDefinition)); - - //creating component property that contains the sub property that will be gotten by the get_property instance property - final var propertyDefinition = new PropertyDefinition(); - propertyDefinition.setName(containerPropertyPath.get(0)); - propertyDefinition.setUniqueId(containerPropertyId); - final String property1Type = "property1.datatype"; - propertyDefinition.setType(property1Type); - component.setProperties(List.of(propertyDefinition)); - //creating resource instance to be added to the component - final ComponentInstance resourceInstance = createComponentInstance("resourceInstance"); - resourceInstance.setUniqueId(resourceInstanceId); - component.setComponentInstances(List.of(resourceInstance)); - - mockComponentForToscaGetFunctionValidation(component); - - //creating data types for "map", and sub properties - final Map<String, DataTypeDefinition> allDataTypesMap = new HashMap<>(); - allDataTypesMap.put(mapToscaType, new DataTypeDefinition()); - - final String subProperty1Type = "subProperty1.datatype"; - allDataTypesMap.put(property1Type, createDataType(property1Type, Map.of(containerPropertyPath.get(1), subProperty1Type))); - - final var subProperty2Property = new PropertyDefinition(); - subProperty2Property.setName(containerPropertyPath.get(2)); - subProperty2Property.setType(propertyGetProperty.getType()); - subProperty2Property.setSchema(propertyGetProperty.getSchema()); - allDataTypesMap.put(subProperty1Type, createDataType(subProperty1Type, List.of(subProperty2Property))); - - when(applicationDataTypeCache.getAll(component.getModel())).thenReturn(Either.left(allDataTypesMap)); - //when - final Either<List<ComponentInstanceProperty>, ResponseFormat> actualResponseFormat = componentInstanceBusinessLogic - .createOrUpdatePropertiesValues( - ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentId, resourceInstanceId, resourceInstanceProperties, userId); - //then - assertTrue(actualResponseFormat.isLeft()); - assertThat(actualResponseFormat.left().value()).isEqualTo(resourceInstanceProperties); - } - - @Test - void testToscaGetPropertyOnInstanceValidation() { - final String userId = "userId"; - final String containerComponentId = "containerComponentId"; - final String containerComponentName = "containerComponentName"; - final String instanceUniqueId = String.format("%s.%s", containerComponentId, "instanceId"); - - final List<String> parentPropertyPath = List.of("property1"); - final String containerPropertyId = String.format("%s.%s", containerComponentId, parentPropertyPath.get(0)); - final ComponentInstanceProperty getPropertyOnInstanceProperty = createComponentInstanceProperty( - String.format("%s.%s", containerComponentId, "getPropertyOnInstanceProperty"), - "getPropertyOnInstanceProperty", - "string", - null, - String.format("\"get_property\": [\"%s\", \"%s\"]", PropertySource.INSTANCE, parentPropertyPath.get(0)), - createGetToscaFunction(parentPropertyPath.get(0), containerPropertyId, parentPropertyPath, PropertySource.INSTANCE, - ToscaGetFunctionType.GET_PROPERTY, instanceUniqueId, containerComponentName) - ); - - //creating component that has the instance properties - final Component component = new Service(); - component.setUniqueId(containerComponentId); - component.setName(containerComponentName); - component.setLastUpdaterUserId(userId); - component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); - //adding instance properties to the component - final List<ComponentInstanceProperty> resourceInstanceProperties = List.of(getPropertyOnInstanceProperty); - final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>(); - componentInstanceProps.put(instanceUniqueId, resourceInstanceProperties); - component.setComponentInstancesProperties(componentInstanceProps); - - //creating resource property that will be get - final var propertyDefinition = new PropertyDefinition(); - propertyDefinition.setName(parentPropertyPath.get(0)); - propertyDefinition.setUniqueId(containerPropertyId); - final String property1Type = "string"; - propertyDefinition.setType(property1Type); - //creating resource instance to be added to the component - final ComponentInstance resourceInstance = createComponentInstance("resourceInstance"); - resourceInstance.setUniqueId(instanceUniqueId); - resourceInstance.setProperties(List.of(propertyDefinition)); - component.setComponentInstances(List.of(resourceInstance)); - - mockComponentForToscaGetFunctionValidation(component); - - //when - final Either<List<ComponentInstanceProperty>, ResponseFormat> actualResponseFormat = componentInstanceBusinessLogic - .createOrUpdatePropertiesValues( - ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentId, instanceUniqueId, resourceInstanceProperties, userId); - //then - assertTrue(actualResponseFormat.isLeft()); - assertThat(actualResponseFormat.left().value()).isEqualTo(resourceInstanceProperties); - } - - private DataTypeDefinition createDataType(final String name, final Map<String, String> propertyNameAndTypeMap) { - final var dataTypeDefinition = new DataTypeDefinition(); - dataTypeDefinition.setName(name); - if (MapUtils.isNotEmpty(propertyNameAndTypeMap)) { - for (final Entry<String, String> propertyEntry : propertyNameAndTypeMap.entrySet()) { - final var propertyDefinition = new PropertyDefinition(); - propertyDefinition.setName(propertyEntry.getKey()); - propertyDefinition.setType(propertyEntry.getValue()); - dataTypeDefinition.setProperties(List.of(propertyDefinition)); - } - } - return dataTypeDefinition; - } - - private DataTypeDefinition createDataType(final String name, final List<PropertyDefinition> propertyList) { - final var dataTypeDefinition = new DataTypeDefinition(); - dataTypeDefinition.setName(name); - if (CollectionUtils.isNotEmpty(propertyList)) { - dataTypeDefinition.setProperties(propertyList); - } - return dataTypeDefinition; - } - - private ComponentInstanceProperty createComponentInstanceProperty(final String uniqueId, final String name, final String type, - final String schemaType, final String value, - final ToscaGetFunctionDataDefinition toscaGetFunction) { - final var componentInstanceProperty = new ComponentInstanceProperty(); - componentInstanceProperty.setName(name); - componentInstanceProperty.setUniqueId(uniqueId); - componentInstanceProperty.setType(type); - componentInstanceProperty.setValue(value); - if (schemaType != null) { - final SchemaDefinition schemaDefinition = createSchema(schemaType); - componentInstanceProperty.setSchema(schemaDefinition); - } - if (toscaGetFunction != null) { - componentInstanceProperty.setToscaFunction(toscaGetFunction); - } - - return componentInstanceProperty; - } - - @Test - void testToscaGetFunctionValidation_schemaDivergeTest() { - final String userId = "userId"; - final String containerComponentId = "containerComponentId"; - final String containerComponentName = "containerComponentName"; - final String resourceInstanceId = "resourceInstanceId"; - final String inputName = "myInputToGet"; - final String inputId = String.format("%s.%s", containerComponentId, inputName); - final String propertyName = "getInputProperty"; - final String propertyId = String.format("%s.%s", containerComponentId, propertyName); - final String propertyType = "list"; - final List<ComponentInstanceProperty> properties = new ArrayList<>(); - final ComponentInstanceProperty propertyGetInput = createComponentInstanceProperty( - propertyId, - "getInputProperty", - propertyType, - "string", - String.format("get_input: [\"%s\"]", inputName), - createGetToscaFunction(inputName, inputId, List.of(propertyName), PropertySource.SELF, ToscaGetFunctionType.GET_INPUT, - containerComponentId, containerComponentName) - ); - properties.add(propertyGetInput); - - final Component component = new Service(); - component.setUniqueId(containerComponentId); - component.setName(containerComponentName); - component.setLastUpdaterUserId(userId); - component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); - - var inputDefinition = new InputDefinition(); - inputDefinition.setName(inputName); - inputDefinition.setUniqueId(inputId); - inputDefinition.setType(propertyType); - inputDefinition.setSchema(createSchema("integer")); - component.setInputs(List.of(inputDefinition)); - - final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>(); - componentInstanceProps.put(resourceInstanceId, properties); - component.setComponentInstancesProperties(componentInstanceProps); - - final ComponentInstance resourceInstance = createComponentInstance("componentInstance1"); - resourceInstance.setUniqueId(resourceInstanceId); - component.setComponentInstances(List.of(resourceInstance)); - - mockComponentForToscaGetFunctionValidation(component); - //when - final Either<List<ComponentInstanceProperty>, ResponseFormat> responseFormatEither = - componentInstanceBusinessLogic - .createOrUpdatePropertiesValues(ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentId, resourceInstanceId, properties, userId); - //then - assertTrue(responseFormatEither.isRight(), "Expecting an error"); - final ResponseFormat actualResponse = responseFormatEither.right().value(); - final ResponseFormat expectedResponse = - ToscaGetFunctionExceptionSupplier - .propertySchemaDiverge(propertyGetInput.getToscaFunction().getType(), inputDefinition.getSchemaType(), - propertyGetInput.getSchemaType()) - .get().getResponseFormat(); - assertEquals(expectedResponse.getFormattedMessage(), actualResponse.getFormattedMessage()); - assertEquals(expectedResponse.getStatus(), actualResponse.getStatus()); - } - - @Test - void testToscaGetFunctionValidation_propertyTypeDivergeTest() { - final String userId = "userId"; - final String containerComponentId = "containerComponentId"; - final String containerComponentName = "containerComponentName"; - final String resourceInstanceId = "resourceInstanceId"; - final String inputName = "myInputToGet"; - final String inputId = String.format("%s.%s", containerComponentId, inputName); - final String propertyName = "getInputProperty"; - final String propertyId = String.format("%s.%s", containerComponentId, propertyName); - final String propertyType = "string"; - final List<ComponentInstanceProperty> properties = new ArrayList<>(); - final ComponentInstanceProperty propertyGetInput = createComponentInstanceProperty( - propertyId, - "getInputProperty", - propertyType, - "string", - String.format("get_input: [\"%s\"]", inputName), - createGetToscaFunction(inputName, inputId, List.of(propertyName), PropertySource.SELF, ToscaGetFunctionType.GET_INPUT, - containerComponentId, containerComponentName) - ); - properties.add(propertyGetInput); - - final Component component = new Service(); - component.setName(containerComponentName); - component.setUniqueId(containerComponentId); - component.setLastUpdaterUserId(userId); - component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); - - var inputDefinition = new InputDefinition(); - inputDefinition.setName(inputName); - inputDefinition.setUniqueId(inputId); - inputDefinition.setType("integer"); - component.setInputs(List.of(inputDefinition)); - - final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>(); - componentInstanceProps.put(resourceInstanceId, properties); - component.setComponentInstancesProperties(componentInstanceProps); - - final ComponentInstance resourceInstance = createComponentInstance("componentInstance1"); - resourceInstance.setUniqueId(resourceInstanceId); - component.setComponentInstances(List.of(resourceInstance)); - - mockComponentForToscaGetFunctionValidation(component); - //when - final Either<List<ComponentInstanceProperty>, ResponseFormat> responseFormatEither = - componentInstanceBusinessLogic - .createOrUpdatePropertiesValues(ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentId, resourceInstanceId, properties, userId); - //then - assertTrue(responseFormatEither.isRight(), "Expecting an error"); - final ResponseFormat actualResponse = responseFormatEither.right().value(); - final ResponseFormat expectedResponse = - ToscaGetFunctionExceptionSupplier - .propertyTypeDiverge(propertyGetInput.getToscaFunction().getType(), inputDefinition.getType(), propertyGetInput.getType()) - .get().getResponseFormat(); - assertEquals(expectedResponse.getFormattedMessage(), actualResponse.getFormattedMessage()); - assertEquals(expectedResponse.getStatus(), actualResponse.getStatus()); - } - - @ParameterizedTest - @MethodSource("getToscaFunctionForValidation") - void testToscaGetFunctionValidation_AttributesNotFoundTest(final ToscaGetFunctionDataDefinition toscaGetFunction, - final ResponseFormat expectedValidationResponse) { - final String userId = "userId"; - final String containerComponentId = "containerComponentId"; - final String containerComponentName = "containerComponentName"; - final String resourceInstanceId = "resourceInstanceId"; - final List<ComponentInstanceProperty> properties = new ArrayList<>(); - final ComponentInstanceProperty propertyGetInput = new ComponentInstanceProperty(); - propertyGetInput.setName("anyName"); - propertyGetInput.setToscaFunction(toscaGetFunction); - properties.add(propertyGetInput); - - final Component component = new Service(); - component.setName(containerComponentName); - component.setUniqueId(containerComponentId); - component.setLastUpdaterUserId(userId); - component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); - - final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>(); - componentInstanceProps.put(resourceInstanceId, properties); - component.setComponentInstancesProperties(componentInstanceProps); - - final ComponentInstance resourceInstance = createComponentInstance("componentInstance1"); - resourceInstance.setUniqueId(resourceInstanceId); - component.setComponentInstances(List.of(resourceInstance)); - - mockComponentForToscaGetFunctionValidation(component); - //when - final Either<List<ComponentInstanceProperty>, ResponseFormat> responseFormatEither = - componentInstanceBusinessLogic - .createOrUpdatePropertiesValues(ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentId, resourceInstanceId, properties, userId); - //then - assertTrue(responseFormatEither.isRight(), "Expecting an error"); - final ResponseFormat actualResponse = responseFormatEither.right().value(); - assertEquals(expectedValidationResponse.getFormattedMessage(), actualResponse.getFormattedMessage()); - assertEquals(expectedValidationResponse.getStatus(), actualResponse.getStatus()); - } - - @Test - void testToscaGetFunctionValidation_propertyNotFoundTest() { - final String userId = "userId"; - final String containerComponentId = "containerComponentId"; - final String containerComponentName = "containerComponentName"; - final String resourceInstanceId = "resourceInstanceId"; - final String inputName = "myInputToGet"; - final String inputId = String.format("%s.%s", containerComponentId, inputName); - final String propertyName = "getInputProperty"; - final String propertyId = String.format("%s.%s", containerComponentId, propertyName); - final String propertyType = "string"; - final List<ComponentInstanceProperty> properties = new ArrayList<>(); - final ComponentInstanceProperty propertyGetInput = createComponentInstanceProperty( - propertyId, - "getInputProperty", - propertyType, - "string", - String.format("get_input: [\"%s\"]", inputName), - createGetToscaFunction(inputName, inputId, List.of(propertyName), PropertySource.SELF, ToscaGetFunctionType.GET_INPUT, - containerComponentId, containerComponentName) - ); - properties.add(propertyGetInput); - - final Component component = new Service(); - component.setName(containerComponentName); - component.setUniqueId(containerComponentId); - component.setLastUpdaterUserId(userId); - component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); - - final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>(); - componentInstanceProps.put(resourceInstanceId, properties); - component.setComponentInstancesProperties(componentInstanceProps); - - final ComponentInstance resourceInstance = createComponentInstance("componentInstance1"); - resourceInstance.setUniqueId(resourceInstanceId); - component.setComponentInstances(List.of(resourceInstance)); - mockComponentForToscaGetFunctionValidation(component); - //when - final Either<List<ComponentInstanceProperty>, ResponseFormat> responseFormatEither = - componentInstanceBusinessLogic - .createOrUpdatePropertiesValues(ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentId, resourceInstanceId, properties, userId); - //then - assertTrue(responseFormatEither.isRight(), "Expecting an error"); - final ResponseFormat actualResponse = responseFormatEither.right().value(); - final ResponseFormat expectedResponse = - ToscaGetFunctionExceptionSupplier - .propertyNotFoundOnTarget(inputName, PropertySource.SELF, ToscaGetFunctionType.GET_INPUT) - .get().getResponseFormat(); - assertEquals(expectedResponse.getFormattedMessage(), actualResponse.getFormattedMessage()); - assertEquals(expectedResponse.getStatus(), actualResponse.getStatus()); - } @Test void testCreateOrUpdatePropertiesValuesPropertyNotExists() { @@ -2622,102 +2215,5 @@ class ComponentInstanceBusinessLogicTest { return component; } - private void mockComponentForToscaGetFunctionValidation(final Component component) { - when(toscaOperationFacade.getToscaElement(component.getUniqueId(), JsonParseFlagEnum.ParseAll)) - .thenReturn(Either.left(component)); - when(graphLockOperation.lockComponent(component.getUniqueId(), NodeTypeEnum.ResourceInstance)) - .thenReturn(StorageOperationStatus.OK); - when(toscaOperationFacade.updateComponentInstanceMetadataOfTopologyTemplate(component)) - .thenReturn(Either.left(component)); - when(janusGraphDao.commit()).thenReturn(JanusGraphOperationStatus.OK); - when(graphLockOperation.unlockComponent(component.getUniqueId(), NodeTypeEnum.ResourceInstance)) - .thenReturn(StorageOperationStatus.OK); - } - - private ToscaGetFunctionDataDefinition createGetToscaFunction(final String propertyName, final String propertyUniqueId, - final List<String> propertyPathFromSource, - final PropertySource propertySource, final ToscaGetFunctionType functionType, - final String sourceUniqueId, - final String sourceName) { - final var toscaGetFunction = new ToscaGetFunctionDataDefinition(); - toscaGetFunction.setFunctionType(functionType); - toscaGetFunction.setPropertyUniqueId(propertyUniqueId); - toscaGetFunction.setPropertyName(propertyName); - toscaGetFunction.setPropertyPathFromSource(propertyPathFromSource); - toscaGetFunction.setPropertySource(propertySource); - toscaGetFunction.setSourceName(sourceName); - toscaGetFunction.setSourceUniqueId(sourceUniqueId); - return toscaGetFunction; - } - - private SchemaDefinition createSchema(final String schemaType) { - final var schemaDefinition = new SchemaDefinition(); - final var schemaProperty = new PropertyDefinition(); - schemaProperty.setType(schemaType); - schemaDefinition.setProperty(schemaProperty); - return schemaDefinition; - } - - private static Stream<Arguments> getToscaFunctionForValidation() { - final var toscaGetFunction1 = new ToscaGetFunctionDataDefinition(); - final ResponseFormat expectedResponse1 = ToscaFunctionExceptionSupplier - .missingFunctionType().get().getResponseFormat(); - - final var toscaGetFunction2 = new ToscaGetFunctionDataDefinition(); - toscaGetFunction2.setFunctionType(ToscaGetFunctionType.GET_INPUT); - final ResponseFormat expectedResponse2 = ToscaGetFunctionExceptionSupplier - .targetPropertySourceNotFound(toscaGetFunction2.getFunctionType()).get().getResponseFormat(); - - final var toscaGetFunction3 = new ToscaGetFunctionDataDefinition(); - toscaGetFunction3.setFunctionType(ToscaGetFunctionType.GET_INPUT); - toscaGetFunction3.setPropertySource(PropertySource.SELF); - final ResponseFormat expectedResponse3 = ToscaGetFunctionExceptionSupplier - .targetSourcePathNotFound(toscaGetFunction3.getFunctionType()).get().getResponseFormat(); - - final var toscaGetFunction4 = new ToscaGetFunctionDataDefinition(); - toscaGetFunction4.setFunctionType(ToscaGetFunctionType.GET_INPUT); - toscaGetFunction4.setPropertySource(PropertySource.SELF); - toscaGetFunction4.setPropertyPathFromSource(List.of("sourcePath")); - final ResponseFormat expectedResponse4 = ToscaGetFunctionExceptionSupplier - .sourceNameNotFound(toscaGetFunction4.getPropertySource()).get().getResponseFormat(); - - final var toscaGetFunction5 = new ToscaGetFunctionDataDefinition(); - toscaGetFunction5.setFunctionType(ToscaGetFunctionType.GET_INPUT); - toscaGetFunction5.setPropertySource(PropertySource.SELF); - toscaGetFunction5.setPropertyPathFromSource(List.of("sourcePath")); - toscaGetFunction5.setSourceName("sourceName"); - final ResponseFormat expectedResponse5 = ToscaGetFunctionExceptionSupplier - .sourceIdNotFound(toscaGetFunction5.getPropertySource()).get().getResponseFormat(); - - final var toscaGetFunction6 = new ToscaGetFunctionDataDefinition(); - toscaGetFunction6.setFunctionType(ToscaGetFunctionType.GET_PROPERTY); - toscaGetFunction6.setPropertySource(PropertySource.SELF); - toscaGetFunction6.setPropertyPathFromSource(List.of("sourcePath")); - toscaGetFunction6.setSourceName("sourceName"); - toscaGetFunction6.setSourceUniqueId("sourceUniqueId"); - final ResponseFormat expectedResponse6 = ToscaGetFunctionExceptionSupplier - .propertyNameNotFound(toscaGetFunction6.getPropertySource()).get().getResponseFormat(); - - final var toscaGetFunction7 = new ToscaGetFunctionDataDefinition(); - toscaGetFunction7.setFunctionType(ToscaGetFunctionType.GET_PROPERTY); - toscaGetFunction7.setPropertySource(PropertySource.SELF); - toscaGetFunction7.setPropertyPathFromSource(List.of("sourcePath")); - toscaGetFunction7.setSourceName("sourceName"); - toscaGetFunction7.setSourceUniqueId("sourceUniqueId"); - toscaGetFunction7.setPropertyName("propertyName"); - final ResponseFormat expectedResponse7 = ToscaGetFunctionExceptionSupplier - .propertyIdNotFound(toscaGetFunction7.getPropertySource()).get().getResponseFormat(); - - return Stream.of( - Arguments.of(toscaGetFunction1, expectedResponse1), - Arguments.of(toscaGetFunction2, expectedResponse2), - Arguments.of(toscaGetFunction3, expectedResponse3), - Arguments.of(toscaGetFunction4, expectedResponse4), - Arguments.of(toscaGetFunction5, expectedResponse5), - Arguments.of(toscaGetFunction6, expectedResponse6), - Arguments.of(toscaGetFunction7, expectedResponse7) - ); - } - } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogicTest.java index ac994f0797..141aae7a5a 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogicTest.java @@ -31,6 +31,7 @@ package org.openecomp.sdc.be.components.impl; import static java.util.Arrays.asList; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyList; @@ -60,8 +61,9 @@ import org.openecomp.sdc.be.components.validation.AccessValidations; import org.openecomp.sdc.be.config.Configuration; 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.janusgraph.JanusGraphDao; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; +import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.impl.ComponentsUtils; @@ -174,7 +176,6 @@ class GroupBusinessLogicTest { @Test void testValidAndUpdateGrpInstancePropValues_fail() { - Either<GroupInstance, ResponseFormat> result; String componentId = "id"; String instanceId = "id"; GroupInstance oldGroupInstance = new GroupInstance(); @@ -182,11 +183,10 @@ class GroupBusinessLogicTest { List<PropertyDataDefinition> properties = new LinkedList<>(); properties.add(new PropertyDataDefinition()); oldGroupInstance.setProperties(properties); - try { - result = test.validateAndUpdateGroupInstancePropertyValues(componentId, instanceId, oldGroupInstance, newProperties); - } catch (ComponentException e) { - assertThat(e.getActionStatus()).isEqualTo(ActionStatus.GENERAL_ERROR); - } + when(toscaOperationFacade.getToscaElement(componentId, JsonParseFlagEnum.ParseAll)).thenReturn(Either.left(new Resource())); + final ComponentException actualException = assertThrows(ComponentException.class, + () -> test.validateAndUpdateGroupInstancePropertyValues(componentId, instanceId, oldGroupInstance, newProperties)); + assertEquals(ActionStatus.GENERAL_ERROR, actualException.getActionStatus()); } @Test diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/PolicyBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/PolicyBusinessLogicTest.java index 15b7706598..f54a70d3d7 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/PolicyBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/PolicyBusinessLogicTest.java @@ -23,7 +23,6 @@ import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.when; @@ -250,8 +249,8 @@ class PolicyBusinessLogicTest { when(toscaOperationFacade.getToscaFullElement(COMPONENT_ID)).thenReturn(Either.left(newResource)); when(toscaOperationFacade.updatePolicyOfComponent(eq(COMPONENT_ID), any(PolicyDefinition.class), any(PromoteVersionEnum.class))).thenReturn( Either.left(policy)); - when(propertyOperation.validateAndUpdatePropertyValue(eq(null), eq(prop1), anyBoolean(), eq(null), anyMap())).thenReturn(Either.left(prop1)); - when(propertyOperation.validateAndUpdatePropertyValue(eq(null), eq(prop2), anyBoolean(), eq(null), anyMap())).thenReturn(Either.left(prop2)); + when(propertyOperation.validateAndUpdatePropertyValue(eq(newResource), eq(properties[0]), anyMap())).thenReturn(Either.left(prop1)); + when(propertyOperation.validateAndUpdatePropertyValue(eq(newResource), eq(properties[1]), anyMap())).thenReturn(Either.left(prop2)); Map<String, PolicyDefinition> createdPolicy = businessLogic.createPolicies(newResource, policies); @@ -292,8 +291,8 @@ class PolicyBusinessLogicTest { when(toscaOperationFacade.getToscaFullElement(COMPONENT_ID)).thenReturn(Either.left(newService)); when(toscaOperationFacade.updatePolicyOfComponent(eq(COMPONENT_ID), any(PolicyDefinition.class), any(PromoteVersionEnum.class))).thenReturn( Either.left(policy)); - when(propertyOperation.validateAndUpdatePropertyValue(eq(null), eq(prop1), anyBoolean(), eq(null), anyMap())).thenReturn(Either.left(prop1)); - when(propertyOperation.validateAndUpdatePropertyValue(eq(null), eq(prop2), anyBoolean(), eq(null), anyMap())).thenReturn(Either.left(prop2)); + when(propertyOperation.validateAndUpdatePropertyValue(eq(newService), eq(properties[0]), anyMap())).thenReturn(Either.left(prop1)); + when(propertyOperation.validateAndUpdatePropertyValue(eq(newService), eq(properties[1]), anyMap())).thenReturn(Either.left(prop2)); Map<String, PolicyDefinition> createdPolicy = businessLogic.createPolicies(newService, policies); @@ -408,16 +407,16 @@ class PolicyBusinessLogicTest { stubValidateAndLockSuccess(); String prop1 = "Name"; String prop2 = "Type"; - when(propertyOperation.validateAndUpdatePropertyValue(eq(null), eq(prop1), anyBoolean(), eq(null), anyMap())).thenReturn(Either.left(prop1)); - when(propertyOperation.validateAndUpdatePropertyValue(eq(null), eq(prop2), anyBoolean(), eq(null), anyMap())).thenReturn(Either.left(prop2)); + when(toscaOperationFacade.updatePolicyOfComponent(eq(COMPONENT_ID), any(PolicyDefinition.class), any(PromoteVersionEnum.class))).thenReturn( policySuccessEither); stubUnlockAndCommit(); PropertyDataDefinition[] properties = getProperties(prop1, prop2); + when(propertyOperation.validateAndUpdatePropertyValue(any(Resource.class), eq(properties[0]), anyMap())).thenReturn(Either.left(prop1)); + when(propertyOperation.validateAndUpdatePropertyValue(any(Resource.class), eq(properties[1]), anyMap())).thenReturn(Either.left(prop2)); policy.setProperties(Arrays.asList(properties)); - List<PropertyDataDefinition> response = businessLogic.updatePolicyProperties(ComponentTypeEnum.RESOURCE, COMPONENT_ID, POLICY_ID, properties, - USER_ID, true); - List<PropertyDataDefinition> updatedProperties = response; + List<PropertyDataDefinition> updatedProperties = + businessLogic.updatePolicyProperties(ComponentTypeEnum.RESOURCE, COMPONENT_ID, POLICY_ID, properties, USER_ID, true); assertEquals(2, updatedProperties.size()); } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceInstanceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceInstanceBusinessLogicTest.java index b5037179cf..8bd39af919 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceInstanceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceInstanceBusinessLogicTest.java @@ -22,10 +22,24 @@ package org.openecomp.sdc.be.components.impl; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import fj.data.Either; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mockito; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.MockitoAnnotations; import org.openecomp.sdc.be.components.impl.instance.ComponentInstanceChangeOperationOrchestrator; import org.openecomp.sdc.be.components.merge.instance.ComponentInstanceMergeDataBusinessLogic; @@ -48,6 +62,7 @@ import org.openecomp.sdc.be.model.operations.api.IGroupInstanceOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.ComponentInstanceOperation; import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo; import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo; @@ -55,19 +70,7 @@ import org.openecomp.sdc.be.user.UserBusinessLogic; import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; import org.openecomp.sdc.exception.ResponseFormat; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - -public class ResourceInstanceBusinessLogicTest extends BaseBusinessLogicMock { +class ResourceInstanceBusinessLogicTest extends BaseBusinessLogicMock { private static final String RESOURCE_ID_WITH_HEAT_PARAMS = "MyResourceId"; private static final String RESOURCE_ID_NO_PAYLOAD = "NoHeatPayload"; @@ -79,77 +82,93 @@ public class ResourceInstanceBusinessLogicTest extends BaseBusinessLogicMock { private static final String USER_ID = "jh0003"; private static final long ARTIFACT_CREATION_TIME = System.currentTimeMillis(); - private final ComponentInstanceOperation componentInstanceOperation = Mockito.mock(ComponentInstanceOperation.class); - private final ArtifactsBusinessLogic artifactBusinessLogic = Mockito.mock(ArtifactsBusinessLogic.class); - private final ComponentInstanceMergeDataBusinessLogic compInstMergeDataBL = Mockito.mock(ComponentInstanceMergeDataBusinessLogic.class); - private final ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator = Mockito.mock(ComponentInstanceChangeOperationOrchestrator.class); - private final ForwardingPathOperation forwardingPathOperation = Mockito.mock(ForwardingPathOperation.class); - private final NodeFilterOperation serviceFilterOperation = Mockito.mock(NodeFilterOperation.class); + private final ComponentInstanceOperation componentInstanceOperation = mock(ComponentInstanceOperation.class); + private final ArtifactsBusinessLogic artifactBusinessLogic = mock(ArtifactsBusinessLogic.class); + private final ComponentInstanceMergeDataBusinessLogic compInstMergeDataBL = mock(ComponentInstanceMergeDataBusinessLogic.class); + private final ComponentInstanceChangeOperationOrchestrator onChangeInstanceOperationOrchestrator = + mock(ComponentInstanceChangeOperationOrchestrator.class); + private final ForwardingPathOperation forwardingPathOperation = mock(ForwardingPathOperation.class); + private final NodeFilterOperation serviceFilterOperation = mock(NodeFilterOperation.class); + private final ToscaFunctionValidator toscaFunctionValidator = mock(ToscaFunctionValidator.class); - private static final UserBusinessLogic userAdminManager = Mockito.mock(UserBusinessLogic.class); - public static final ComponentsUtils componentsUtils = Mockito.mock(ComponentsUtils.class); - public static final IGroupInstanceOperation groupInstanceOperation = Mockito.mock(IGroupInstanceOperation.class); - public static final ToscaOperationFacade toscaOperationFacade = Mockito.mock(ToscaOperationFacade.class); + private static final UserBusinessLogic userAdminManager = mock(UserBusinessLogic.class); + public static final ComponentsUtils componentsUtils = mock(ComponentsUtils.class); + public static final IGroupInstanceOperation groupInstanceOperation = mock(IGroupInstanceOperation.class); + public static final ToscaOperationFacade toscaOperationFacade = mock(ToscaOperationFacade.class); static User adminUser = new User("John", "Doh", USER_ID, "", "ADMIN", null); - private ComponentInstanceBusinessLogic bl = new ComponentInstanceBusinessLogic(elementDao, groupOperation, groupInstanceOperation, + private final ComponentInstanceBusinessLogic bl = new ComponentInstanceBusinessLogic(elementDao, groupOperation, groupInstanceOperation, groupTypeOperation, interfaceOperation, interfaceLifecycleTypeOperation, componentInstanceOperation, artifactBusinessLogic, compInstMergeDataBL, onChangeInstanceOperationOrchestrator, - forwardingPathOperation, serviceFilterOperation, artifactToscaOperation); + forwardingPathOperation, serviceFilterOperation, artifactToscaOperation, toscaFunctionValidator); - @Before - public void setUp() throws Exception { + @BeforeEach + void setUp() throws Exception { MockitoAnnotations.openMocks(this); - Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getDeploymentResourceInstanceArtifacts(); + Map<String, Object> deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration() + .getDeploymentResourceInstanceArtifacts(); Map<String, Object> placeHolderData = (Map<String, Object>) deploymentResourceArtifacts.get(ArtifactsBusinessLogic.HEAT_ENV_NAME); - ArtifactDefinition heatArtifact = getHeatArtifactDefinition(USER_ID, RESOURCE_ID_WITH_HEAT_PARAMS, HEAT_LABEL, ARTIFACT_CREATION_TIME, false, true); + ArtifactDefinition heatArtifact = getHeatArtifactDefinition(USER_ID, RESOURCE_ID_WITH_HEAT_PARAMS, HEAT_LABEL, ARTIFACT_CREATION_TIME, false, + true); Map<String, ArtifactDefinition> artifacts = new HashMap<>(); artifacts.put(HEAT_LABEL.toLowerCase(), heatArtifact); Either<Map<String, ArtifactDefinition>, StorageOperationStatus> eitherGetResourceArtifact = Either.left(artifacts); - when(artifactBusinessLogic.getArtifacts(RESOURCE_ID_WITH_HEAT_PARAMS, NodeTypeEnum.Resource, ArtifactGroupTypeEnum.DEPLOYMENT, null)).thenReturn(eitherGetResourceArtifact); + when(artifactBusinessLogic.getArtifacts(RESOURCE_ID_WITH_HEAT_PARAMS, NodeTypeEnum.Resource, ArtifactGroupTypeEnum.DEPLOYMENT, + null)).thenReturn(eitherGetResourceArtifact); - ArtifactDefinition heatArtifactNoPayload = getHeatArtifactDefinition(USER_ID, RESOURCE_ID_NO_PAYLOAD, HEAT_LABEL, ARTIFACT_CREATION_TIME, true, false); + ArtifactDefinition heatArtifactNoPayload = getHeatArtifactDefinition(USER_ID, RESOURCE_ID_NO_PAYLOAD, HEAT_LABEL, ARTIFACT_CREATION_TIME, + true, false); Map<String, ArtifactDefinition> artifactsNoPayload = new HashMap<>(); artifactsNoPayload.put(HEAT_LABEL.toLowerCase(), heatArtifactNoPayload); Either<Map<String, ArtifactDefinition>, StorageOperationStatus> eitherGetResourceArtifactNoPayload = Either.left(artifactsNoPayload); - when(artifactBusinessLogic.getArtifacts(RESOURCE_ID_NO_PAYLOAD, NodeTypeEnum.Resource, ArtifactGroupTypeEnum.DEPLOYMENT, null)).thenReturn(eitherGetResourceArtifactNoPayload); + when(artifactBusinessLogic.getArtifacts(RESOURCE_ID_NO_PAYLOAD, NodeTypeEnum.Resource, ArtifactGroupTypeEnum.DEPLOYMENT, null)).thenReturn( + eitherGetResourceArtifactNoPayload); - ArtifactDefinition heatArtifactNoParams = getHeatArtifactDefinition(USER_ID, RESOURCE_ID_NO_HEAT_PARAMS, HEAT_LABEL, ARTIFACT_CREATION_TIME, false, false); + ArtifactDefinition heatArtifactNoParams = getHeatArtifactDefinition(USER_ID, RESOURCE_ID_NO_HEAT_PARAMS, HEAT_LABEL, ARTIFACT_CREATION_TIME, + false, false); Map<String, ArtifactDefinition> artifactsNoParams = new HashMap<>(); artifactsNoParams.put(HEAT_LABEL.toLowerCase(), heatArtifactNoParams); Either<Map<String, ArtifactDefinition>, StorageOperationStatus> eitherGetResourceArtifactNoParams = Either.left(artifactsNoParams); - when(artifactBusinessLogic.getArtifacts(RESOURCE_ID_NO_HEAT_PARAMS, NodeTypeEnum.Resource, ArtifactGroupTypeEnum.DEPLOYMENT, null)).thenReturn(eitherGetResourceArtifactNoParams); + when( + artifactBusinessLogic.getArtifacts(RESOURCE_ID_NO_HEAT_PARAMS, NodeTypeEnum.Resource, ArtifactGroupTypeEnum.DEPLOYMENT, null)).thenReturn( + eitherGetResourceArtifactNoParams); ArtifactDefinition eitherPlaceHolder = getArtifactPlaceHolder(RESOURCE_INSTANCE_ID, HEAT_ENV_LABEL); - when(artifactBusinessLogic.createArtifactPlaceHolderInfo(RESOURCE_INSTANCE_ID, HEAT_ENV_LABEL.toLowerCase(), placeHolderData, USER_ID, ArtifactGroupTypeEnum.DEPLOYMENT, false)).thenReturn(eitherPlaceHolder); - - // Mockito.when(artifactBusinessLogic.createArtifactAuditingFields(Mockito.any(ArtifactDefinition.class), Mockito.anyString(), Mockito.anyString())).thenReturn(new EnumMap<AuditingFieldsKey, Object>(AuditingFieldsKey.class)); + when(artifactBusinessLogic.createArtifactPlaceHolderInfo(RESOURCE_INSTANCE_ID, HEAT_ENV_LABEL.toLowerCase(), placeHolderData, USER_ID, + ArtifactGroupTypeEnum.DEPLOYMENT, false)).thenReturn(eitherPlaceHolder); when(userAdminManager.getUser(USER_ID, false)).thenReturn(adminUser); - Mockito.doNothing().when(componentsUtils).auditComponent(any(ResponseFormat.class), any(User.class), any(Component.class), any(AuditingActionEnum.class), + doNothing().when(componentsUtils) + .auditComponent(any(ResponseFormat.class), any(User.class), any(Component.class), any(AuditingActionEnum.class), any(ResourceCommonInfo.class), any(ResourceVersionInfo.class)); - ArtifactDefinition heatEnvEither = getHeatArtifactDefinition(USER_ID, RESOURCE_INSTANCE_ID, HEAT_ENV_LABEL, ARTIFACT_CREATION_TIME, true, false); + ArtifactDefinition heatEnvEither = getHeatArtifactDefinition(USER_ID, RESOURCE_INSTANCE_ID, HEAT_ENV_LABEL, ARTIFACT_CREATION_TIME, true, + false); - when(artifactBusinessLogic.createHeatEnvPlaceHolder(any(ArrayList.class),any(ArtifactDefinition.class), Mockito.anyString(), Mockito.anyString(), any(NodeTypeEnum.class), Mockito.anyString(), any(User.class), - any(Component.class), any())).thenReturn(heatEnvEither); + when(artifactBusinessLogic.createHeatEnvPlaceHolder(any(ArrayList.class), any(ArtifactDefinition.class), anyString(), + anyString(), any(NodeTypeEnum.class), anyString(), any(User.class), + any(Component.class), any())).thenReturn(heatEnvEither); - Either<List<GroupInstance>, StorageOperationStatus> groupInstanceEitherLeft = Either.left(new ArrayList<>()); - when(groupInstanceOperation.getAllGroupInstances(Mockito.anyString(), any(NodeTypeEnum.class))).thenReturn(groupInstanceEitherLeft); + Either<List<GroupInstance>, StorageOperationStatus> groupInstanceEitherLeft = Either.left(new ArrayList<>()); + when(groupInstanceOperation.getAllGroupInstances(anyString(), any(NodeTypeEnum.class))).thenReturn(groupInstanceEitherLeft); bl.setToscaOperationFacade(toscaOperationFacade); StorageOperationStatus status = StorageOperationStatus.OK; - Mockito.when(toscaOperationFacade.addDeploymentArtifactsToInstance(Mockito.any(String.class), Mockito.any(ComponentInstance.class), Mockito.any(Map.class))).thenReturn(status); - Mockito.when(toscaOperationFacade.addInformationalArtifactsToInstance(Mockito.any(String.class), Mockito.any(ComponentInstance.class), Mockito.any())).thenReturn(status); - Mockito.when(toscaOperationFacade.addGroupInstancesToComponentInstance(Mockito.any(Component.class), Mockito.any(ComponentInstance.class), Mockito.any(), Mockito.any(Map.class))).thenReturn(status); + when(toscaOperationFacade.addDeploymentArtifactsToInstance(any(String.class), any(ComponentInstance.class), + any(Map.class))).thenReturn(status); + when( + toscaOperationFacade.addInformationalArtifactsToInstance(any(String.class), any(ComponentInstance.class), any())) + .thenReturn(status); + when(toscaOperationFacade.addGroupInstancesToComponentInstance(any(Component.class), any(ComponentInstance.class), + any(), any(Map.class))).thenReturn(status); } @Test - public void testAddResourceInstanceArtifacts() throws Exception { + void testAddResourceInstanceArtifacts() { ComponentInstance resourceInstance = new ComponentInstance(); resourceInstance.setName(RESOURCE_INSTANCE_ID); resourceInstance.setComponentUid(RESOURCE_ID_WITH_HEAT_PARAMS); @@ -161,18 +180,17 @@ public class ResourceInstanceBusinessLogicTest extends BaseBusinessLogicMock { Resource originResource = new Resource(); originResource.setUniqueId(RESOURCE_ID_NO_PAYLOAD); ActionStatus addArtifactsRes = bl.addComponentInstanceArtifacts(service, resourceInstance, originResource, adminUser, existingEnvVersions); - assertTrue(addArtifactsRes.equals(ActionStatus.OK)); + assertEquals(ActionStatus.OK, addArtifactsRes); Map<String, ArtifactDefinition> deploymentArtifacts = resourceInstance.getDeploymentArtifacts(); assertNotNull(deploymentArtifacts); -// assertTrue(deploymentArtifacts.size() == 2); ArtifactDefinition heatDefinition = deploymentArtifacts.get(HEAT_LABEL.toLowerCase()); assertNotNull(heatDefinition); } - @Test - public void testAddResourceInstanceArtifactsNoParams() throws Exception { + @Test + void testAddResourceInstanceArtifactsNoParams() { ComponentInstance resourceInstance = new ComponentInstance(); resourceInstance.setName(RESOURCE_INSTANCE_ID); resourceInstance.setComponentUid(RESOURCE_ID_NO_HEAT_PARAMS); @@ -183,30 +201,21 @@ public class ResourceInstanceBusinessLogicTest extends BaseBusinessLogicMock { Resource originResource = new Resource(); originResource.setUniqueId(RESOURCE_ID_NO_PAYLOAD); ActionStatus addArtifactsRes = bl.addComponentInstanceArtifacts(service, resourceInstance, originResource, adminUser, existingEnvVersions); - assertTrue(addArtifactsRes.equals(ActionStatus.OK)); + assertEquals(ActionStatus.OK, addArtifactsRes); Map<String, ArtifactDefinition> deploymentArtifacts = resourceInstance.getDeploymentArtifacts(); assertNotNull(deploymentArtifacts); -// assertTrue(deploymentArtifacts.size() == 2); ArtifactDefinition heatDefinition = deploymentArtifacts.get(HEAT_LABEL.toLowerCase()); assertNotNull(heatDefinition); -// assertEquals(getHeatArtifactDefinition(USER_ID, RESOURCE_ID_NO_HEAT_PARAMS, HEAT_LABEL, ARTIFACT_CREATION_TIME, false, false), heatDefinition); - -// ArtifactDefinition heatEnvDefinition = deploymentArtifacts.get(HEAT_ENV_LABEL.toLowerCase()); -// assertNotNull(heatEnvDefinition); List<HeatParameterDefinition> heatParameters = heatDefinition.getListHeatParameters(); assertNull(heatParameters); - -// List<HeatParameterDefinition> heatEnvParameters = heatEnvDefinition.getListHeatParameters(); -// assertNull(heatEnvParameters); - } @SuppressWarnings("unchecked") @Test - public void testAddResourceInstanceArtifactsNoArtifacts() throws Exception { + void testAddResourceInstanceArtifactsNoArtifacts() { ComponentInstance resourceInstance = new ComponentInstance(); resourceInstance.setName(RESOURCE_INSTANCE_ID); resourceInstance.setComponentUid(RESOURCE_ID_NO_PAYLOAD); @@ -218,16 +227,18 @@ public class ResourceInstanceBusinessLogicTest extends BaseBusinessLogicMock { originResource.setUniqueId(RESOURCE_ID_NO_PAYLOAD); ActionStatus addArtifactsRes = bl.addComponentInstanceArtifacts(service, resourceInstance, originResource, adminUser, existingEnvVersions); - assertTrue(addArtifactsRes.equals(ActionStatus.OK)); + assertEquals(ActionStatus.OK, addArtifactsRes); Map<String, ArtifactDefinition> deploymentArtifacts = resourceInstance.getDeploymentArtifacts(); assertNotNull(deploymentArtifacts); assertEquals(0, deploymentArtifacts.size()); - Mockito.verify(artifactBusinessLogic, Mockito.times(0)).addHeatEnvArtifact(any(ArtifactDefinition.class), any(ArtifactDefinition.class), any(Service.class), any(NodeTypeEnum.class), Mockito.anyString()); + verify(artifactBusinessLogic, never()).addHeatEnvArtifact(any(ArtifactDefinition.class), any(ArtifactDefinition.class), any(Service.class), + any(NodeTypeEnum.class), anyString()); } - private static ArtifactDefinition getHeatArtifactDefinition(String userId, String resourceId, String artifactName, long time, boolean placeholderOnly, boolean withHeatParams) { + private static ArtifactDefinition getHeatArtifactDefinition(String userId, String resourceId, String artifactName, long time, + boolean placeholderOnly, boolean withHeatParams) { ArtifactDefinition artifactInfo = new ArtifactDefinition(); artifactInfo.setArtifactName(artifactName + ".yml"); @@ -238,7 +249,6 @@ public class ResourceInstanceBusinessLogicTest extends BaseBusinessLogicMock { artifactInfo.setUserIdCreator(userId); String fullName = "Jim H"; artifactInfo.setUpdaterFullName(fullName); - // long time = System.currentTimeMillis(); artifactInfo.setCreatorFullName(fullName); artifactInfo.setCreationDate(time); artifactInfo.setLastUpdateDate(time); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/validation/ToscaFunctionValidatorImplTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/validation/ToscaFunctionValidatorImplTest.java new file mode 100644 index 0000000000..3b86d9db78 --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/validation/ToscaFunctionValidatorImplTest.java @@ -0,0 +1,498 @@ +/* + * - + * ============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 static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import fj.data.Either; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Stream; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.collections4.MapUtils; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; +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.config.ConfigurationManager; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +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.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.common.api.ConfigurationSource; +import org.openecomp.sdc.common.impl.ExternalConfiguration; +import org.openecomp.sdc.common.impl.FSConfigurationSource; + +class ToscaFunctionValidatorImplTest { + + @Mock + private ApplicationDataTypeCache applicationDataTypeCache; + + private ToscaFunctionValidatorImpl toscaFunctionValidator; + + @BeforeAll + static void beforeAll() { + initConfig(); + } + + private static void initConfig() { + final ConfigurationSource configurationSource = new FSConfigurationSource( + ExternalConfiguration.getChangeListener(), + "src/test/resources/config/catalog-be" + ); + new ConfigurationManager(configurationSource); + } + + @BeforeEach + void setUp() { + MockitoAnnotations.openMocks(this); + toscaFunctionValidator = new ToscaFunctionValidatorImpl(applicationDataTypeCache); + } + + @Test + void testToscaGetFunctionValidation() { + final String containerComponentId = "containerComponentId"; + final String containerComponentName = "containerComponentName"; + final String resourceInstanceId = "resourceInstanceId"; + final String inputName = "myInputToGet"; + final String inputId = String.format("%s.%s", containerComponentId, inputName); + final String schemaType = "string"; + //creating instance list of string property with get_input value + final ComponentInstanceProperty propertyGetInput = new ComponentInstanceProperty(); + propertyGetInput.setName("getInputProperty"); + propertyGetInput.setPropertyId(String.format("%s.%s", containerComponentId, "getInputProperty")); + propertyGetInput.setValue(String.format("get_input: [\"%s\"]", inputName)); + propertyGetInput.setType("list"); + final SchemaDefinition listStringPropertySchema = createSchema(schemaType); + propertyGetInput.setSchema(listStringPropertySchema); + propertyGetInput.setToscaFunction( + createGetToscaFunction(inputName, inputId, List.of(propertyGetInput.getName()), PropertySource.SELF, ToscaGetFunctionType.GET_INPUT, + containerComponentId, containerComponentName) + ); + //creating instance map of string property with get_input value to a second level property: + // get_input: ["property1", "subProperty1", "subProperty2"] + final String getPropertyPropertyName = "getPropertyProperty"; + final List<String> containerPropertyPath = List.of("property1", "subProperty1", "subProperty2"); + final String containerPropertyId = String.format("%s.%s", containerComponentId, containerPropertyPath.get(0)); + final String mapToscaType = "map"; + final ComponentInstanceProperty propertyGetProperty = createComponentInstanceProperty( + String.format("%s.%s", containerComponentId, getPropertyPropertyName), + getPropertyPropertyName, + mapToscaType, + "string", + String.format("\"get_property\": [\"%s\", \"%s\"]", PropertySource.SELF, String.join("\", \"", containerPropertyPath)), + createGetToscaFunction(containerPropertyPath.get(containerPropertyPath.size() - 1), containerPropertyId, + containerPropertyPath, PropertySource.SELF, ToscaGetFunctionType.GET_PROPERTY, containerComponentId, containerComponentName) + ); + + //creating component that has the instance properties + final Component component = new Service(); + component.setUniqueId(containerComponentId); + component.setName(containerComponentName); + //adding instance properties to the component + final List<ComponentInstanceProperty> resourceInstanceProperties = List.of(propertyGetInput, propertyGetProperty); + final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>(); + componentInstanceProps.put(resourceInstanceId, resourceInstanceProperties); + component.setComponentInstancesProperties(componentInstanceProps); + + //creating component input that will be gotten by the get_input instance property + final var inputDefinition = new InputDefinition(); + inputDefinition.setName(inputName); + inputDefinition.setUniqueId(inputId); + inputDefinition.setType(propertyGetInput.getType()); + inputDefinition.setSchema(listStringPropertySchema); + component.setInputs(List.of(inputDefinition)); + + //creating component property that contains the sub property that will be gotten by the get_property instance property + final var propertyDefinition = new PropertyDefinition(); + propertyDefinition.setName(containerPropertyPath.get(0)); + propertyDefinition.setUniqueId(containerPropertyId); + final String property1Type = "property1.datatype"; + propertyDefinition.setType(property1Type); + component.setProperties(List.of(propertyDefinition)); + //creating resource instance to be added to the component + final ComponentInstance resourceInstance = createComponentInstance("resourceInstance", resourceInstanceId); + component.setComponentInstances(List.of(resourceInstance)); + + //creating data types for "map", and sub properties + final Map<String, DataTypeDefinition> allDataTypesMap = new HashMap<>(); + allDataTypesMap.put(mapToscaType, new DataTypeDefinition()); + + final String subProperty1Type = "subProperty1.datatype"; + allDataTypesMap.put(property1Type, createDataType(property1Type, Map.of(containerPropertyPath.get(1), subProperty1Type))); + + final var subProperty2Property = new PropertyDefinition(); + subProperty2Property.setName(containerPropertyPath.get(2)); + subProperty2Property.setType(propertyGetProperty.getType()); + subProperty2Property.setSchema(propertyGetProperty.getSchema()); + allDataTypesMap.put(subProperty1Type, createDataType(subProperty1Type, List.of(subProperty2Property))); + + when(applicationDataTypeCache.getAll(component.getModel())).thenReturn(Either.left(allDataTypesMap)); + //when/then + assertDoesNotThrow(() -> toscaFunctionValidator.validate(propertyGetProperty, component)); + verify(applicationDataTypeCache).getAll(component.getModel()); + } + + @Test + void testToscaGetPropertyOnInstanceValidation() { + final String userId = "userId"; + final String containerComponentId = "containerComponentId"; + final String containerComponentName = "containerComponentName"; + final String instanceUniqueId = String.format("%s.%s", containerComponentId, "instanceId"); + + final List<String> parentPropertyPath = List.of("property1"); + final String containerPropertyId = String.format("%s.%s", containerComponentId, parentPropertyPath.get(0)); + final ComponentInstanceProperty getPropertyOnInstanceProperty = createComponentInstanceProperty( + String.format("%s.%s", containerComponentId, "getPropertyOnInstanceProperty"), + "getPropertyOnInstanceProperty", + "string", + null, + String.format("\"get_property\": [\"%s\", \"%s\"]", PropertySource.INSTANCE, parentPropertyPath.get(0)), + createGetToscaFunction(parentPropertyPath.get(0), containerPropertyId, parentPropertyPath, PropertySource.INSTANCE, + ToscaGetFunctionType.GET_PROPERTY, instanceUniqueId, containerComponentName) + ); + + //creating component that has the instance properties + final Component component = new Service(); + component.setUniqueId(containerComponentId); + component.setName(containerComponentName); + component.setLastUpdaterUserId(userId); + component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + //adding instance properties to the component + final List<ComponentInstanceProperty> resourceInstanceProperties = List.of(getPropertyOnInstanceProperty); + final Map<String, List<ComponentInstanceProperty>> componentInstanceProps = new HashMap<>(); + componentInstanceProps.put(instanceUniqueId, resourceInstanceProperties); + component.setComponentInstancesProperties(componentInstanceProps); + + //creating resource property that will be get + final var propertyDefinition = new PropertyDefinition(); + propertyDefinition.setName(parentPropertyPath.get(0)); + propertyDefinition.setUniqueId(containerPropertyId); + final String property1Type = "string"; + propertyDefinition.setType(property1Type); + //creating resource instance to be added to the component + final ComponentInstance resourceInstance = createComponentInstance("resourceInstance", instanceUniqueId); + resourceInstance.setProperties(List.of(propertyDefinition)); + component.setComponentInstances(List.of(resourceInstance)); + + assertDoesNotThrow(() -> toscaFunctionValidator.validate(getPropertyOnInstanceProperty, component)); + verify(applicationDataTypeCache, never()).getAll(component.getModel()); + } + + @ParameterizedTest + @MethodSource("getToscaFunctionForValidation") + void validateToscaGetFunctionFailures(final ToscaGetFunctionDataDefinition toscaGetFunction, + final ByActionStatusComponentException expectedException) { + final ComponentInstanceProperty propertyGetInput = new ComponentInstanceProperty(); + propertyGetInput.setName("anyName"); + propertyGetInput.setToscaFunction(toscaGetFunction); + final Component component = new Service(); + final ComponentException actualException = assertThrows(ComponentException.class, + () -> toscaFunctionValidator.validate(propertyGetInput, component)); + assertEquals(expectedException.getActionStatus(), actualException.getActionStatus()); + assertArrayEquals(expectedException.getParams(), actualException.getParams()); + } + + @Test + void validate_propertyNotFoundTest() { + //given + final String containerComponentId = "containerComponentId"; + final String containerComponentName = "containerComponentName"; + final String inputName = "myInputToGet"; + final String inputId = String.format("%s.%s", containerComponentId, inputName); + final String propertyName = "getInputProperty"; + final String propertyId = String.format("%s.%s", containerComponentId, propertyName); + final String propertyType = "string"; + final ComponentInstanceProperty propertyGetInput = createComponentInstanceProperty( + propertyId, + "getInputProperty", + propertyType, + null, + String.format("get_input: [\"%s\"]", inputName), + createGetToscaFunction(inputName, inputId, List.of(propertyName), PropertySource.SELF, ToscaGetFunctionType.GET_INPUT, + containerComponentId, containerComponentName) + ); + + final Component component = new Service(); + final InputDefinition inputDefinition = new InputDefinition(); + inputDefinition.setUniqueId(inputId + "1"); + component.setInputs(List.of(inputDefinition)); + + //when/then + final ByActionStatusComponentException actualException = assertThrows(ByActionStatusComponentException.class, + () -> toscaFunctionValidator.validate(propertyGetInput, component)); + + final ByActionStatusComponentException expectedException = + ToscaGetFunctionExceptionSupplier + .propertyNotFoundOnTarget(inputName, PropertySource.SELF, ToscaGetFunctionType.GET_INPUT) + .get(); + assertEquals(expectedException.getActionStatus(), actualException.getActionStatus()); + assertArrayEquals(expectedException.getParams(), actualException.getParams()); + } + + @Test + void validate_schemaDivergeTest() { + //given + final String containerComponentId = "containerComponentId"; + final String containerComponentName = "containerComponentName"; + final String inputName = "myInputToGet"; + final String inputId = String.format("%s.%s", containerComponentId, inputName); + final String propertyName = "getInputProperty"; + final String propertyId = String.format("%s.%s", containerComponentId, propertyName); + final String propertyType = "list"; + final ComponentInstanceProperty propertyGetInput = createComponentInstanceProperty( + propertyId, + "getInputProperty", + propertyType, + "string", + String.format("get_input: [\"%s\"]", inputName), + createGetToscaFunction(inputName, inputId, List.of(propertyName), PropertySource.SELF, ToscaGetFunctionType.GET_INPUT, + containerComponentId, containerComponentName) + ); + + final Component component = new Service(); + component.setUniqueId(containerComponentId); + component.setName(containerComponentName); + + var inputDefinition = new InputDefinition(); + inputDefinition.setName(inputName); + inputDefinition.setUniqueId(inputId); + inputDefinition.setType(propertyType); + inputDefinition.setSchema(createSchema("integer")); + component.setInputs(List.of(inputDefinition)); + + //when/then + final ByActionStatusComponentException actualException = assertThrows(ByActionStatusComponentException.class, + () -> toscaFunctionValidator.validate(propertyGetInput, component)); + + final ByActionStatusComponentException expectedException = + ToscaGetFunctionExceptionSupplier + .propertySchemaDiverge(propertyGetInput.getToscaFunction().getType(), inputDefinition.getSchemaType(), + propertyGetInput.getSchemaType()) + .get(); + assertEquals(expectedException.getActionStatus(), actualException.getActionStatus()); + assertArrayEquals(expectedException.getParams(), actualException.getParams()); + } + + @Test + void validate_propertyTypeDivergeTest() { + //given + final String containerComponentId = "containerComponentId"; + final String containerComponentName = "containerComponentName"; + final String inputName = "myInputToGet"; + final String inputId = String.format("%s.%s", containerComponentId, inputName); + final String propertyName = "getInputProperty"; + final String propertyId = String.format("%s.%s", containerComponentId, propertyName); + final String propertyType = "string"; + + final ComponentInstanceProperty propertyGetInput = createComponentInstanceProperty( + propertyId, + "getInputProperty", + propertyType, + "string", + String.format("get_input: [\"%s\"]", inputName), + createGetToscaFunction(inputName, inputId, List.of(propertyName), PropertySource.SELF, ToscaGetFunctionType.GET_INPUT, + containerComponentId, containerComponentName) + ); + + final Component component = new Service(); + component.setName(containerComponentName); + component.setUniqueId(containerComponentId); + + var inputDefinition = new InputDefinition(); + inputDefinition.setName(inputName); + inputDefinition.setUniqueId(inputId); + inputDefinition.setType("integer"); + component.setInputs(List.of(inputDefinition)); + + //when/then + final ByActionStatusComponentException actualException = assertThrows(ByActionStatusComponentException.class, + () -> toscaFunctionValidator.validate(propertyGetInput, component)); + + final ByActionStatusComponentException expectedException = + ToscaGetFunctionExceptionSupplier + .propertyTypeDiverge(propertyGetInput.getToscaFunction().getType(), inputDefinition.getType(), propertyGetInput.getType()) + .get(); + assertEquals(expectedException.getActionStatus(), actualException.getActionStatus()); + assertArrayEquals(expectedException.getParams(), actualException.getParams()); + } + + private static Stream<Arguments> getToscaFunctionForValidation() { + final var toscaGetFunction1 = new ToscaGetFunctionDataDefinition(); + final ByActionStatusComponentException expectedResponse1 = ToscaFunctionExceptionSupplier + .missingFunctionType().get(); + + final var toscaGetFunction2 = new ToscaGetFunctionDataDefinition(); + toscaGetFunction2.setFunctionType(ToscaGetFunctionType.GET_INPUT); + final ByActionStatusComponentException expectedResponse2 = ToscaGetFunctionExceptionSupplier + .targetPropertySourceNotFound(toscaGetFunction2.getFunctionType()).get(); + + final var toscaGetFunction3 = new ToscaGetFunctionDataDefinition(); + toscaGetFunction3.setFunctionType(ToscaGetFunctionType.GET_INPUT); + toscaGetFunction3.setPropertySource(PropertySource.SELF); + final ByActionStatusComponentException expectedResponse3 = ToscaGetFunctionExceptionSupplier + .targetSourcePathNotFound(toscaGetFunction3.getFunctionType()).get(); + + final var toscaGetFunction4 = new ToscaGetFunctionDataDefinition(); + toscaGetFunction4.setFunctionType(ToscaGetFunctionType.GET_INPUT); + toscaGetFunction4.setPropertySource(PropertySource.SELF); + toscaGetFunction4.setPropertyPathFromSource(List.of("sourcePath")); + final ByActionStatusComponentException expectedResponse4 = ToscaGetFunctionExceptionSupplier + .sourceNameNotFound(toscaGetFunction4.getPropertySource()).get(); + + final var toscaGetFunction5 = new ToscaGetFunctionDataDefinition(); + toscaGetFunction5.setFunctionType(ToscaGetFunctionType.GET_INPUT); + toscaGetFunction5.setPropertySource(PropertySource.SELF); + toscaGetFunction5.setPropertyPathFromSource(List.of("sourcePath")); + toscaGetFunction5.setSourceName("sourceName"); + final ByActionStatusComponentException expectedResponse5 = ToscaGetFunctionExceptionSupplier + .sourceIdNotFound(toscaGetFunction5.getPropertySource()).get(); + + final var toscaGetFunction6 = new ToscaGetFunctionDataDefinition(); + toscaGetFunction6.setFunctionType(ToscaGetFunctionType.GET_PROPERTY); + toscaGetFunction6.setPropertySource(PropertySource.SELF); + toscaGetFunction6.setPropertyPathFromSource(List.of("sourcePath")); + toscaGetFunction6.setSourceName("sourceName"); + toscaGetFunction6.setSourceUniqueId("sourceUniqueId"); + final ByActionStatusComponentException expectedResponse6 = ToscaGetFunctionExceptionSupplier + .propertyNameNotFound(toscaGetFunction6.getPropertySource()).get(); + + final var toscaGetFunction7 = new ToscaGetFunctionDataDefinition(); + toscaGetFunction7.setFunctionType(ToscaGetFunctionType.GET_PROPERTY); + toscaGetFunction7.setPropertySource(PropertySource.SELF); + toscaGetFunction7.setPropertyPathFromSource(List.of("sourcePath")); + toscaGetFunction7.setSourceName("sourceName"); + toscaGetFunction7.setSourceUniqueId("sourceUniqueId"); + toscaGetFunction7.setPropertyName("propertyName"); + final ByActionStatusComponentException expectedResponse7 = ToscaGetFunctionExceptionSupplier + .propertyIdNotFound(toscaGetFunction7.getPropertySource()).get(); + + return Stream.of( + Arguments.of(toscaGetFunction1, expectedResponse1), + Arguments.of(toscaGetFunction2, expectedResponse2), + Arguments.of(toscaGetFunction3, expectedResponse3), + Arguments.of(toscaGetFunction4, expectedResponse4), + Arguments.of(toscaGetFunction5, expectedResponse5), + Arguments.of(toscaGetFunction6, expectedResponse6), + Arguments.of(toscaGetFunction7, expectedResponse7) + ); + } + + private ComponentInstanceProperty createComponentInstanceProperty(final String uniqueId, final String name, final String type, + final String schemaType, final String value, + final ToscaGetFunctionDataDefinition toscaGetFunction) { + final var componentInstanceProperty = new ComponentInstanceProperty(); + componentInstanceProperty.setName(name); + componentInstanceProperty.setUniqueId(uniqueId); + componentInstanceProperty.setType(type); + componentInstanceProperty.setValue(value); + if (schemaType != null) { + final SchemaDefinition schemaDefinition = createSchema(schemaType); + componentInstanceProperty.setSchema(schemaDefinition); + } + if (toscaGetFunction != null) { + componentInstanceProperty.setToscaFunction(toscaGetFunction); + } + + return componentInstanceProperty; + } + + private SchemaDefinition createSchema(final String schemaType) { + final var schemaDefinition = new SchemaDefinition(); + final var schemaProperty = new PropertyDefinition(); + schemaProperty.setType(schemaType); + schemaDefinition.setProperty(schemaProperty); + return schemaDefinition; + } + + private ToscaGetFunctionDataDefinition createGetToscaFunction(final String propertyName, final String propertyUniqueId, + final List<String> propertyPathFromSource, + final PropertySource propertySource, final ToscaGetFunctionType functionType, + final String sourceUniqueId, + final String sourceName) { + final var toscaGetFunction = new ToscaGetFunctionDataDefinition(); + toscaGetFunction.setFunctionType(functionType); + toscaGetFunction.setPropertyUniqueId(propertyUniqueId); + toscaGetFunction.setPropertyName(propertyName); + toscaGetFunction.setPropertyPathFromSource(propertyPathFromSource); + toscaGetFunction.setPropertySource(propertySource); + toscaGetFunction.setSourceName(sourceName); + toscaGetFunction.setSourceUniqueId(sourceUniqueId); + return toscaGetFunction; + } + + private DataTypeDefinition createDataType(final String name, final Map<String, String> propertyNameAndTypeMap) { + final var dataTypeDefinition = new DataTypeDefinition(); + dataTypeDefinition.setName(name); + if (MapUtils.isNotEmpty(propertyNameAndTypeMap)) { + for (final Entry<String, String> propertyEntry : propertyNameAndTypeMap.entrySet()) { + final var propertyDefinition = new PropertyDefinition(); + propertyDefinition.setName(propertyEntry.getKey()); + propertyDefinition.setType(propertyEntry.getValue()); + dataTypeDefinition.setProperties(List.of(propertyDefinition)); + } + } + return dataTypeDefinition; + } + + private DataTypeDefinition createDataType(final String name, final List<PropertyDefinition> propertyList) { + final var dataTypeDefinition = new DataTypeDefinition(); + dataTypeDefinition.setName(name); + if (CollectionUtils.isNotEmpty(propertyList)) { + dataTypeDefinition.setProperties(propertyList); + } + return dataTypeDefinition; + } + + private ComponentInstance createComponentInstance(String name, String uniqueId) { + ComponentInstance componentInstance = new ComponentInstance(); + componentInstance.setName(name); + componentInstance.setUniqueId(uniqueId); + return componentInstance; + } + +}
\ No newline at end of file diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/GroupEndpointTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/GroupEndpointTest.java index c7886e36eb..8b58702c08 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/GroupEndpointTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/GroupEndpointTest.java @@ -35,6 +35,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import fj.data.Either; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Optional; import javax.ws.rs.client.Entity; @@ -63,6 +64,7 @@ import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.PromoteVersionEnum; import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstance; import org.openecomp.sdc.be.model.GroupDefinition; import org.openecomp.sdc.be.model.GroupProperty; @@ -191,17 +193,14 @@ class GroupEndpointTest extends JerseySpringBaseTest { when(componentValidations.getComponentInstance(cr, A)).thenReturn(Optional.of(ci)); doNothing().when(groupsOperation) .updateGroupOnComponent(eq(VALID_COMPONENT_ID), isA(GroupDefinition.class), any(PromoteVersionEnum.class)); - when(groupOperation.validateAndUpdatePropertyValue(isA(GroupProperty.class))) + when(groupOperation.validateAndUpdatePropertyValue(any(Component.class), isA(GroupProperty.class))) .thenReturn(StorageOperationStatus.OK); when(groupsOperation .updateGroupPropertiesOnComponent(eq(VALID_COMPONENT_ID), isA(GroupDefinition.class), anyList(), - any(PromoteVersionEnum.class))).thenAnswer(new Answer<Either>() { - @Override - public Either answer(InvocationOnMock invocationOnMock) throws Throwable { - Object[] args = invocationOnMock.getArguments(); - return Either.left(Arrays.asList(args[2])); - } - }); + any(PromoteVersionEnum.class))).thenAnswer((Answer<Either>) invocationOnMock -> { + Object[] args = invocationOnMock.getArguments(); + return Either.left(Collections.singletonList(args[2])); + }); } @Test 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, diff --git a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts index 5ea1106a8f..fbd9408ea8 100644 --- a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts +++ b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view-model.ts @@ -32,6 +32,7 @@ import {Observable} from "rxjs"; import {TopologyTemplateService} from "app/ng2/services/component-services/topology-template.service"; import {InstanceFeDetails} from "../../../../models/instance-fe-details"; import {ToscaGetFunction} from "../../../../models/tosca-get-function"; +import {ToscaFunctionValidationEvent} from "../../../../ng2/pages/properties-assignment/tosca-function/tosca-function.component"; export interface IEditPropertyModel { property:PropertyModel; @@ -457,8 +458,8 @@ export class PropertyFormViewModel { this.$scope.editPropertyModel.property.toscaFunction = toscaGetFunction; } - this.$scope.onGetFunctionValidityChange = (isValid): void => { - if (isValid.isValid) { + this.$scope.onToscaFunctionValidityChange = (validationEvent: ToscaFunctionValidationEvent): void => { + if (validationEvent.isValid) { this.$scope.editPropertyModel.isGetFunctionValid = true; return; } diff --git a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html index cb46abee56..67fce08311 100644 --- a/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html +++ b/catalog-ui/src/app/view-models/forms/property-forms/component-property-form/property-form-view.html @@ -156,7 +156,7 @@ [component-instance-map]="componentInstanceMap" [allow-clear]="false" (on-valid-function)="onGetFunctionValidFunction($event)" - (on-validity-change)="onGetFunctionValidityChange($event)" + (on-validity-change)="onToscaFunctionValidityChange($event)" > </tosca-function> </div> diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinition.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinition.java index f88514ac49..adfef9c426 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinition.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinition.java @@ -173,11 +173,8 @@ public class PropertyDataDefinition extends ToscaDataDefinition { } public ToscaGetFunctionType getToscaGetFunctionType() { - if (isToscaGetFunction()) { - if (toscaFunction != null) { - return ((ToscaGetFunctionDataDefinition) toscaFunction).getFunctionType(); - } - return toscaGetFunctionType; + if (isToscaGetFunction() && toscaFunction != null) { + return ((ToscaGetFunctionDataDefinition) toscaFunction).getFunctionType(); } return null; @@ -337,10 +334,10 @@ public class PropertyDataDefinition extends ToscaDataDefinition { @JsonIgnoreProperties public boolean isToscaGetFunction() { - return this.toscaGetFunctionType != null || (this.toscaFunction != null + return this.toscaFunction != null && (this.toscaFunction.getType() == ToscaFunctionType.GET_ATTRIBUTE - || this.toscaFunction.getType() == ToscaFunctionType.GET_INPUT - || this.toscaFunction.getType() == ToscaFunctionType.GET_PROPERTY)); + || this.toscaFunction.getType() == ToscaFunctionType.GET_INPUT + || this.toscaFunction.getType() == ToscaFunctionType.GET_PROPERTY); } @JsonIgnoreProperties diff --git a/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinitionTest.java b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinitionTest.java index 2d73faf41e..f83eb9d069 100644 --- a/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinitionTest.java +++ b/common-be/src/test/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinitionTest.java @@ -694,16 +694,6 @@ class PropertyDataDefinitionTest { toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_ATTRIBUTE); assertEquals(ToscaGetFunctionType.GET_ATTRIBUTE, propertyDataDefinition.getToscaGetFunctionType()); - - propertyDataDefinition = new PropertyDataDefinition(); - propertyDataDefinition.setToscaGetFunctionType(ToscaGetFunctionType.GET_INPUT); - assertEquals(ToscaGetFunctionType.GET_INPUT, propertyDataDefinition.getToscaGetFunctionType()); - - propertyDataDefinition.setToscaGetFunctionType(ToscaGetFunctionType.GET_PROPERTY); - assertEquals(ToscaGetFunctionType.GET_PROPERTY, propertyDataDefinition.getToscaGetFunctionType()); - - propertyDataDefinition.setToscaGetFunctionType(ToscaGetFunctionType.GET_ATTRIBUTE); - assertEquals(ToscaGetFunctionType.GET_ATTRIBUTE, propertyDataDefinition.getToscaGetFunctionType()); } @Test @@ -721,12 +711,8 @@ class PropertyDataDefinitionTest { @Test void isToscaGetFunctionTest() { - var propertyDataDefinition = new PropertyDataDefinition(); - propertyDataDefinition.setToscaGetFunctionType(ToscaGetFunctionType.GET_PROPERTY); - assertTrue(propertyDataDefinition.isToscaGetFunction()); - - propertyDataDefinition = new PropertyDataDefinition(); - final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition(); + final var propertyDataDefinition = new PropertyDataDefinition(); + final var toscaGetFunction = new ToscaGetFunctionDataDefinition(); toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_INPUT); propertyDataDefinition.setToscaFunction(toscaGetFunction); assertTrue(propertyDataDefinition.isToscaGetFunction()); |