diff options
Diffstat (limited to 'catalog-be')
13 files changed, 886 insertions, 671 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 |