From 7b0009c2bebe54214f920baf6b2aa4058921777b Mon Sep 17 00:00:00 2001 From: "andre.schmid" Date: Fri, 29 Jul 2022 20:39:23 +0100 Subject: [PATCH] Support for TOSCA functions for Service Import MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reads, interprets and persists property values that uses TOSCA functions during a Service import. Change-Id: I6943c447cc743213cb9807d6433cb25fa5effbc3 Issue-ID: SDC-4120 Signed-off-by: André Schmid --- .../csar/ToscaFunctionYamlParsingHandler.java | 180 +++++++++++++++++++++ .../csar/YamlTemplateParsingHandler.java | 170 ++++++++++--------- .../impl/ServiceImportBusinessLogic.java | 158 ++++++++++-------- .../be/components/impl/ToscaFunctionService.java | 158 ++++++++++++++++++ .../csar/ToscaFunctionYamlParsingHandlerTest.java | 150 +++++++++++++++++ .../csar/YamlTemplateParsingHandlerTest.java | 19 +-- .../components/impl/ResourceBusinessLogicTest.java | 2 +- .../components/impl/ToscaFunctionServiceTest.java | 148 +++++++++++++++++ .../org/openecomp/sdc/be/model/UploadPropInfo.java | 33 +--- .../model/operations/impl/PropertyOperation.java | 134 --------------- .../be/datatypes/elements/ToscaConcatFunction.java | 4 + .../elements/ToscaFunctionJsonDeserializer.java | 22 ++- 12 files changed, 845 insertions(+), 333 deletions(-) create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandler.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ToscaFunctionService.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandlerTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ToscaFunctionServiceTest.java diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandler.java new file mode 100644 index 0000000000..6bc74a69df --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandler.java @@ -0,0 +1,180 @@ +/* + * - + * ============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.csar; + +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Stream; +import org.openecomp.sdc.be.datatypes.elements.CustomYamlFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaConcatFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionParameter; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaStringParameter; +import org.openecomp.sdc.be.datatypes.enums.PropertySource; +import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; + +@org.springframework.stereotype.Component +public class ToscaFunctionYamlParsingHandler { + + /** + * Builds a {@link ToscaFunction} based on the property value. It will build the object with the maximum information available in the property + * value, as not all the necessary information can be extracted from it. It will only parse values from supported functions in + * {@link ToscaFunctionType}. + * + * @param toscaFunctionPropertyValueMap the value of a property calls a TOSCA function + * @return the partially filled {@link ToscaFunction} object + */ + public Optional buildToscaFunctionBasedOnPropertyValue(final Map toscaFunctionPropertyValueMap) { + if (!isPropertyValueToscaFunction(toscaFunctionPropertyValueMap)) { + return Optional.empty(); + } + final String functionType = toscaFunctionPropertyValueMap.keySet().iterator().next(); + final ToscaFunctionType toscaFunctionType = ToscaFunctionType.findType(functionType).orElse(null); + if (toscaFunctionType == null) { + return Optional.empty(); + } + switch (toscaFunctionType) { + case GET_INPUT: { + return handleGetInputFunction(toscaFunctionPropertyValueMap, functionType); + } + case GET_PROPERTY: + case GET_ATTRIBUTE: { + return handleGetPropertyFunction(toscaFunctionPropertyValueMap, functionType, toscaFunctionType); + } + case CONCAT: + return handleConcatFunction(toscaFunctionPropertyValueMap, functionType); + default: + return Optional.empty(); + } + } + + /** + * Checks if the property value is a supported TOSCA function. + * + * @param propValueObj the value of a property + * @return {@code true} if the value is a supported TOSCA function, {@code false} otherwise + */ + public boolean isPropertyValueToscaFunction(final Object propValueObj) { + if (propValueObj instanceof Map) { + final Map propValueMap = (Map) propValueObj; + if (propValueMap.keySet().size() > 1) { + return false; + } + return Stream.of(ToscaFunctionType.GET_INPUT, ToscaFunctionType.GET_PROPERTY, ToscaFunctionType.GET_ATTRIBUTE, ToscaFunctionType.CONCAT) + .anyMatch(type -> propValueMap.containsKey(type.getName())); + } + return false; + } + + private Optional handleConcatFunction(Map toscaFunctionPropertyValueMap, String functionType) { + final ToscaConcatFunction toscaConcatFunction = new ToscaConcatFunction(); + final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType); + if (!(functionValueObj instanceof List)) { + return Optional.empty(); + } + final List functionParameters = (List) functionValueObj; + if (functionParameters.size() < 2) { + return Optional.empty(); + } + functionParameters.forEach(parameter -> { + if (parameter instanceof String) { + final var stringParameter = new ToscaStringParameter(); + stringParameter.setValue((String) parameter); + toscaConcatFunction.addParameter(stringParameter); + return; + } + if (isPropertyValueToscaFunction(parameter)) { + buildToscaFunctionBasedOnPropertyValue((Map) parameter).ifPresent(toscaFunction -> { + if (toscaFunction instanceof ToscaFunctionParameter) { + toscaConcatFunction.addParameter((ToscaFunctionParameter) toscaFunction); + } + }); + return; + } + final var customYamlFunction = new CustomYamlFunction(); + customYamlFunction.setYamlValue(parameter); + toscaConcatFunction.addParameter(customYamlFunction); + }); + return Optional.of(toscaConcatFunction); + } + + private static Optional handleGetPropertyFunction(Map toscaFunctionPropertyValueMap, String functionType, + ToscaFunctionType toscaFunctionType) { + final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition(); + toscaGetFunction.setFunctionType( + toscaFunctionType == ToscaFunctionType.GET_PROPERTY ? ToscaGetFunctionType.GET_PROPERTY : ToscaGetFunctionType.GET_ATTRIBUTE + ); + final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType); + if (!(functionValueObj instanceof List)) { + return Optional.empty(); + } + final List functionParameters; + try { + functionParameters = (List) functionValueObj; + } catch (final ClassCastException ignored) { + return Optional.empty(); + } + if (functionParameters.size() < 2) { + return Optional.empty(); + } + final String propertySourceType = functionParameters.get(0); + final PropertySource propertySource = PropertySource.findType(propertySourceType).orElse(null); + if (propertySource == PropertySource.SELF) { + toscaGetFunction.setPropertySource(propertySource); + } else { + toscaGetFunction.setPropertySource(PropertySource.INSTANCE); + toscaGetFunction.setSourceName(propertySourceType); + } + toscaGetFunction.setPropertyPathFromSource(functionParameters.subList(1, functionParameters.size())); + final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1); + toscaGetFunction.setPropertyName(propertyName); + return Optional.of(toscaGetFunction); + } + + private static Optional handleGetInputFunction(Map toscaFunctionPropertyValueMap, String functionType) { + final ToscaGetFunctionDataDefinition toscaGetFunction = new ToscaGetFunctionDataDefinition(); + toscaGetFunction.setFunctionType(ToscaGetFunctionType.GET_INPUT); + toscaGetFunction.setPropertySource(PropertySource.SELF); + final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType); + if (!(functionValueObj instanceof List) && !(functionValueObj instanceof String)) { + return Optional.empty(); + } + if (functionValueObj instanceof String) { + toscaGetFunction.setPropertyPathFromSource(List.of((String) functionValueObj)); + } else { + final List functionParameters; + try { + functionParameters = (List) functionValueObj; + } catch (final ClassCastException ignored) { + return Optional.empty(); + } + toscaGetFunction.setPropertyPathFromSource(functionParameters); + } + final String propertyName = toscaGetFunction.getPropertyPathFromSource().get(toscaGetFunction.getPropertyPathFromSource().size() - 1); + toscaGetFunction.setPropertyName(propertyName); + return Optional.of(toscaGetFunction); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java index a68bbf3a2d..cbba46f35c 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java @@ -77,7 +77,6 @@ import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.regex.Pattern; import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; @@ -88,7 +87,6 @@ import org.openecomp.sdc.be.components.impl.ImportUtils; import org.openecomp.sdc.be.components.impl.NodeFilterUploadCreator; import org.openecomp.sdc.be.components.impl.PolicyTypeBusinessLogic; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; -import org.openecomp.sdc.be.components.utils.PropertiesUtils; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao; @@ -130,22 +128,24 @@ import org.yaml.snakeyaml.parser.ParserException; @org.springframework.stereotype.Component public class YamlTemplateParsingHandler { - private static final Pattern propertyValuePattern = Pattern.compile("[ ]*\\{[ ]*(str_replace=|token=|get_property=|concat=|get_attribute=)+"); private static final int SUB_MAPPING_CAPABILITY_OWNER_NAME_IDX = 0; private static final int SUB_MAPPING_CAPABILITY_NAME_IDX = 1; private static final Logger log = Logger.getLogger(YamlTemplateParsingHandler.class); - private Gson gson = new Gson(); - private JanusGraphDao janusGraphDao; - private GroupTypeBusinessLogic groupTypeBusinessLogic; - private AnnotationBusinessLogic annotationBusinessLogic; - private PolicyTypeBusinessLogic policyTypeBusinessLogic; + private final Gson gson = new Gson(); + private final JanusGraphDao janusGraphDao; + private final GroupTypeBusinessLogic groupTypeBusinessLogic; + private final AnnotationBusinessLogic annotationBusinessLogic; + private final PolicyTypeBusinessLogic policyTypeBusinessLogic; + private final ToscaFunctionYamlParsingHandler toscaFunctionYamlParsingHandler; public YamlTemplateParsingHandler(JanusGraphDao janusGraphDao, GroupTypeBusinessLogic groupTypeBusinessLogic, - AnnotationBusinessLogic annotationBusinessLogic, PolicyTypeBusinessLogic policyTypeBusinessLogic) { + AnnotationBusinessLogic annotationBusinessLogic, PolicyTypeBusinessLogic policyTypeBusinessLogic, + final ToscaFunctionYamlParsingHandler toscaFunctionYamlParsingHandler) { this.janusGraphDao = janusGraphDao; this.groupTypeBusinessLogic = groupTypeBusinessLogic; this.annotationBusinessLogic = annotationBusinessLogic; this.policyTypeBusinessLogic = policyTypeBusinessLogic; + this.toscaFunctionYamlParsingHandler = toscaFunctionYamlParsingHandler; } public ParsedToscaYamlInfo parseResourceInfoFromYAML(String fileName, String resourceYml, Map createdNodesToscaResourceNames, @@ -306,31 +306,36 @@ public class YamlTemplateParsingHandler { return policyTypeDefinition; } - private List validateFillPolicyProperties(PolicyTypeDefinition policyTypeDefinition, - Map policyTemplateJsonMap) { - if (MapUtils.isEmpty(policyTemplateJsonMap) || Objects.isNull(policyTypeDefinition)) { + private List validateFillPolicyProperties(final PolicyTypeDefinition policyTypeDefinition, + final Map policyTemplateJsonMap) { + if (policyTypeDefinition == null || CollectionUtils.isEmpty(policyTypeDefinition.getProperties()) + || MapUtils.isEmpty(policyTemplateJsonMap)) { return Collections.emptyList(); } - List propertyDataDefinitionList = new ArrayList<>(); - Map propertiesMap = (Map) policyTemplateJsonMap.get(PROPERTIES.getElementName()); - if (MapUtils.isEmpty(propertiesMap)) { + final Map propertiesJsonMap = (Map) policyTemplateJsonMap.get(PROPERTIES.getElementName()); + if (MapUtils.isEmpty(propertiesJsonMap)) { return Collections.emptyList(); } - if (CollectionUtils.isNotEmpty(policyTypeDefinition.getProperties())) { - propertyDataDefinitionList = policyTypeDefinition.getProperties().stream() - .map(propertyDefinition -> setPropertyValue(propertiesMap, propertyDefinition)).collect(Collectors.toList()); - } - return propertyDataDefinitionList; - } - - private PropertyDataDefinition setPropertyValue(Map propertiesMap, PropertyDataDefinition srcPropertyDataDefinition) { - PropertyDataDefinition newPropertyDef = new PropertyDataDefinition(srcPropertyDataDefinition); - String propertyName = newPropertyDef.getName(); - if (Objects.nonNull(propertiesMap.get(propertyName))) { - Object propValue = propertiesMap.get(propertyName); - newPropertyDef.setValue(PropertiesUtils.trimQuotes(gson.toJson(propValue))); - } - return newPropertyDef; + return propertiesJsonMap.entrySet().stream() + .map(propertyJson -> { + final PropertyDefinition originalProperty = + policyTypeDefinition.getProperties().stream() + .filter(propertyDefinition -> propertyDefinition.getName().equals(propertyJson.getKey())) + .findFirst() + .orElse(null); + if (originalProperty == null) { + return null; + } + final UploadPropInfo uploadPropInfo = buildProperty(propertyJson.getKey(), propertyJson.getValue()); + final PropertyDefinition propertyDefinition = new PropertyDefinition(originalProperty); + propertyDefinition.setValue(gson.toJson(uploadPropInfo.getValue())); + propertyDefinition.setToscaFunction(uploadPropInfo.getToscaFunction()); + propertyDefinition.setGetInputValues(uploadPropInfo.getGet_input()); + propertyDefinition.setDescription(uploadPropInfo.getDescription()); + return propertyDefinition; + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); } private Map> validateFillPolicyTargets(Map policyTemplateJson) { @@ -473,8 +478,8 @@ public class YamlTemplateParsingHandler { .collect(Collectors.toMap(GroupDefinition::getName, g -> g)); Map substitutionMappings = getSubstitutionMappings(toscaJson); if (capabilitiesSubstitutionMappingsExist(substitutionMappings)) { - groups.entrySet().forEach(entry -> updateCapabilitiesNames(entry.getValue(), - getNamesToUpdate(entry.getKey(), (Map>) substitutionMappings.get(CAPABILITIES.getElementName())))); + groups.forEach((key, value) -> updateCapabilitiesNames(value, + getNamesToUpdate(key, (Map>) substitutionMappings.get(CAPABILITIES.getElementName())))); } return groups; } @@ -555,28 +560,21 @@ public class YamlTemplateParsingHandler { } } - private void mergeGroupProperties(GroupDefinition groupInfo, Map parsedProperties) { - if (CollectionUtils.isNotEmpty(groupInfo.getProperties())) { - validateGroupProperties(parsedProperties, groupInfo); - groupInfo.getProperties().forEach(p -> mergeGroupProperty(p, parsedProperties)); - } - } - - private void mergeGroupProperty(PropertyDataDefinition property, Map parsedProperties) { - if (parsedProperties.containsKey(property.getName())) { - Object propValue = parsedProperties.get(property.getName()); - if (valueNotContainsPattern(propertyValuePattern, propValue)) { - setPropertyValueAndGetInputsValues(property, propValue); - } + private void mergeGroupProperties(final GroupDefinition groupDefinition, final Map parsedProperties) { + if (CollectionUtils.isEmpty(groupDefinition.getProperties())) { + return; } + validateGroupProperties(parsedProperties, groupDefinition); + groupDefinition.getProperties().stream() + .filter(property -> parsedProperties.containsKey(property.getName())) + .forEach(property -> mergeGroupProperty(property, parsedProperties.get(property.getName()))); } - private void setPropertyValueAndGetInputsValues(PropertyDataDefinition property, Object propValue) { - if (propValue != null) { - UploadPropInfo uploadPropInfo = buildProperty(property.getName(), propValue); - property.setValue(convertPropertyValue(ToscaPropertyType.isValidType(property.getType()), uploadPropInfo.getValue())); - property.setGetInputValues(uploadPropInfo.getGet_input()); - } + private void mergeGroupProperty(final PropertyDataDefinition property, final Object propertyYaml) { + final UploadPropInfo uploadPropInfo = buildProperty(property.getName(), propertyYaml); + property.setToscaFunction(uploadPropInfo.getToscaFunction()); + property.setValue(convertPropertyValue(ToscaPropertyType.isValidType(property.getType()), uploadPropInfo.getValue())); + property.setGetInputValues(uploadPropInfo.getGet_input()); } private String convertPropertyValue(ToscaPropertyType type, Object value) { @@ -675,7 +673,7 @@ public class YamlTemplateParsingHandler { } private void validateGroupProperties(Map parsedProperties, GroupDefinition groupInfo) { - List parsedPropertiesNames = parsedProperties.entrySet().stream().map(Map.Entry::getKey).collect(toList()); + List parsedPropertiesNames = new ArrayList<>(parsedProperties.keySet()); validateProperties(groupInfo.getProperties().stream().map(PropertyDataDefinition::getName).collect(toList()), parsedPropertiesNames, ActionStatus.GROUP_PROPERTY_NOT_FOUND, groupInfo.getName(), groupInfo.getType()); } @@ -788,7 +786,8 @@ public class YamlTemplateParsingHandler { private void updateProperties(UploadComponentInstanceInfo nodeTemplateInfo, Map nodeTemplateJsonMap) { if (nodeTemplateJsonMap.containsKey(PROPERTIES.getElementName())) { - Map> properties = buildPropModuleFromYaml(nodeTemplateJsonMap); + Map> properties = + buildPropModuleFromYaml((Map) nodeTemplateJsonMap.get(PROPERTIES.getElementName())); if (!properties.isEmpty()) { nodeTemplateInfo.setProperties(properties); } @@ -942,7 +941,8 @@ public class YamlTemplateParsingHandler { artifactTemplateInfo.setFile((String) nodeTemplateJsonMap.get(FILE.getElementName())); } if (nodeTemplateJsonMap.containsKey(PROPERTIES.getElementName())) { - Map> props = buildPropModuleFromYaml(nodeTemplateJsonMap); + Map> props = + buildPropModuleFromYaml((Map) nodeTemplateJsonMap.get(PROPERTIES.getElementName())); if (!props.isEmpty()) { List properties = props.values().stream().flatMap(Collection::stream).collect(toList()); artifactTemplateInfo.setProperties(properties); @@ -1011,7 +1011,8 @@ public class YamlTemplateParsingHandler { } } if (nodeTemplateJsonMap.containsKey(PROPERTIES.getElementName())) { - Map> props = buildPropModuleFromYaml(nodeTemplateJsonMap); + Map> props = + buildPropModuleFromYaml((Map) nodeTemplateJsonMap.get(PROPERTIES.getElementName())); if (!props.isEmpty()) { List properties = props.values().stream().flatMap(Collection::stream).collect(toList()); capTemplateInfo.setProperties(properties); @@ -1063,17 +1064,9 @@ public class YamlTemplateParsingHandler { return attributeDef; } - private Map> buildPropModuleFromYaml(Map nodeTemplateJsonMap) { - Map> moduleProp = new HashMap<>(); - Either, ResultStatusEnum> toscaProperties = findFirstToscaMapElement(nodeTemplateJsonMap, PROPERTIES); - if (toscaProperties.isLeft()) { - Map jsonProperties = toscaProperties.left().value(); - for (Map.Entry jsonPropObj : jsonProperties.entrySet()) { - if (valueNotContainsPattern(propertyValuePattern, jsonPropObj.getValue())) { - addProperty(moduleProp, jsonPropObj); - } - } - } + private Map> buildPropModuleFromYaml(final Map propertyMap) { + final Map> moduleProp = new HashMap<>(); + propertyMap.entrySet().forEach(propertyMapEntry -> addProperty(moduleProp, propertyMapEntry)); return moduleProp; } @@ -1089,32 +1082,35 @@ public class YamlTemplateParsingHandler { } @SuppressWarnings("unchecked") - private UploadPropInfo buildProperty(String propName, Object propValue) { - UploadPropInfo propertyDef = new UploadPropInfo(); - propertyDef.setValue(propValue); + private UploadPropInfo buildProperty(String propName, Object propValueObj) { + final var propertyDef = new UploadPropInfo(); + propertyDef.setValue(propValueObj); propertyDef.setName(propName); - if (propValue instanceof Map) { - if (((Map) propValue).containsKey(TYPE.getElementName())) { - propertyDef.setType(((Map) propValue).get(TYPE.getElementName()).toString()); + if (propValueObj instanceof Map) { + final Map propValueMap = (Map) propValueObj; + if (propValueMap.containsKey(TYPE.getElementName())) { + propertyDef.setType(propValueMap.get(TYPE.getElementName()).toString()); } - if (containsGetInput(propValue)) { - fillInputRecursively(propName, (Map) propValue, propertyDef); + if (containsGetInput(propValueObj)) { + fillInputRecursively(propName, propValueMap, propertyDef); } - if (((Map) propValue).containsKey(DESCRIPTION.getElementName())) { - propertyDef.setDescription(((Map) propValue).get(DESCRIPTION.getElementName()).toString()); + if (toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(propValueObj)) { + toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue(propValueMap).ifPresent(propertyDef::setToscaFunction); } - if (((Map) propValue).containsKey(DEFAULT_VALUE.getElementName())) { - propertyDef.setValue(((Map) propValue).get(DEFAULT_VALUE.getElementName())); + if (propValueMap.containsKey(DESCRIPTION.getElementName())) { + propertyDef.setDescription((propValueMap).get(DESCRIPTION.getElementName()).toString()); } - if (((Map) propValue).containsKey(IS_PASSWORD.getElementName())) { - propertyDef.setPassword(Boolean.getBoolean(((Map) propValue).get(IS_PASSWORD.getElementName()).toString())); + if (propValueMap.containsKey(DEFAULT_VALUE.getElementName())) { + propertyDef.setValue(propValueMap.get(DEFAULT_VALUE.getElementName())); + } + if (propValueMap.containsKey(IS_PASSWORD.getElementName())) { + propertyDef.setPassword(Boolean.getBoolean(propValueMap.get(IS_PASSWORD.getElementName()).toString())); } else { - propertyDef.setValue(propValue); + propertyDef.setValue(propValueObj); } - } else if (propValue instanceof List) { - List propValueList = (List) propValue; - fillInputsListRecursively(propertyDef, propValueList); - propertyDef.setValue(propValue); + } else if (propValueObj instanceof List) { + fillInputsListRecursively(propertyDef, (List) propValueObj); + propertyDef.setValue(propValueObj); } return propertyDef; } @@ -1217,10 +1213,6 @@ public class YamlTemplateParsingHandler { } } - private boolean valueNotContainsPattern(Pattern pattern, Object propValue) { - return propValue == null || !pattern.matcher(propValue.toString()).find(); - } - private Object failIfNotTopologyTemplate(String fileName) { janusGraphDao.rollback(); throw new ByActionStatusComponentException(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, fileName); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java index 0850535108..7e15a52b90 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java @@ -33,9 +33,12 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.Set; import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; import lombok.Getter; import lombok.Setter; import org.apache.commons.collections.CollectionUtils; @@ -45,7 +48,6 @@ import org.apache.commons.lang3.tuple.ImmutablePair; import org.openecomp.sdc.be.components.csar.CsarArtifactsAndGroupsBusinessLogic; import org.openecomp.sdc.be.components.csar.CsarBusinessLogic; import org.openecomp.sdc.be.components.csar.CsarInfo; -import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine; import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperationEnum; import org.openecomp.sdc.be.components.impl.artifact.ArtifactOperationInfo; import org.openecomp.sdc.be.components.impl.exceptions.BusinessLogicException; @@ -56,16 +58,6 @@ import org.openecomp.sdc.be.components.impl.utils.CreateServiceFromYamlParameter import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic; import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; import org.openecomp.sdc.be.components.merge.resource.ResourceDataMergeBusinessLogic; -import org.openecomp.sdc.be.components.path.ForwardingPathValidator; -import org.openecomp.sdc.be.components.validation.NodeFilterValidator; -import org.openecomp.sdc.be.components.validation.ServiceDistributionValidation; -import org.openecomp.sdc.be.components.validation.component.ComponentContactIdValidator; -import org.openecomp.sdc.be.components.validation.component.ComponentDescriptionValidator; -import org.openecomp.sdc.be.components.validation.component.ComponentIconValidator; -import org.openecomp.sdc.be.components.validation.component.ComponentNameValidator; -import org.openecomp.sdc.be.components.validation.component.ComponentProjectCodeValidator; -import org.openecomp.sdc.be.components.validation.component.ComponentTagsValidator; -import org.openecomp.sdc.be.components.validation.component.ComponentValidator; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.api.ActionStatus; @@ -76,6 +68,8 @@ import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PolicyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; @@ -88,6 +82,7 @@ import org.openecomp.sdc.be.model.CapabilityDefinition; import org.openecomp.sdc.be.model.CapabilityRequirementRelationship; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; import org.openecomp.sdc.be.model.ComponentInstanceInput; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.ComponentParametersView; @@ -118,19 +113,11 @@ import org.openecomp.sdc.be.model.UploadResourceInfo; import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement; -import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ArtifactsOperations; -import org.openecomp.sdc.be.model.jsonjanusgraph.operations.InterfaceOperation; -import org.openecomp.sdc.be.model.jsonjanusgraph.operations.NodeFilterOperation; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade; import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter; import org.openecomp.sdc.be.model.operations.StorageException; -import org.openecomp.sdc.be.model.operations.api.IElementOperation; import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation; -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.InterfaceLifecycleOperation; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.be.tosca.CsarUtils; import org.openecomp.sdc.be.ui.model.OperationUi; @@ -179,19 +166,12 @@ public class ServiceImportBusinessLogic { private final JanusGraphDao janusGraphDao; private final ArtifactsBusinessLogic artifactsBusinessLogic; private final IGraphLockOperation graphLockOperation; + private final ToscaFunctionService toscaFunctionService; - public ServiceImportBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation, - IGroupTypeOperation groupTypeOperation, GroupBusinessLogic groupBusinessLogic, - InterfaceOperation interfaceOperation, InterfaceLifecycleOperation interfaceLifecycleTypeOperation, - ArtifactsBusinessLogic artifactsBusinessLogic, IDistributionEngine distributionEngine, - ComponentInstanceBusinessLogic componentInstanceBusinessLogic, - ServiceDistributionValidation serviceDistributionValidation, ForwardingPathValidator forwardingPathValidator, - UiComponentDataConverter uiComponentDataConverter, NodeFilterOperation serviceFilterOperation, - NodeFilterValidator serviceFilterValidator, ArtifactsOperations artifactToscaOperation, - ComponentContactIdValidator componentContactIdValidator, ComponentNameValidator componentNameValidator, - ComponentTagsValidator componentTagsValidator, ComponentValidator componentValidator, - ComponentIconValidator componentIconValidator, ComponentProjectCodeValidator componentProjectCodeValidator, - ComponentDescriptionValidator componentDescriptionValidator, final ComponentsUtils componentsUtils, + public ServiceImportBusinessLogic(final GroupBusinessLogic groupBusinessLogic, + final ArtifactsBusinessLogic artifactsBusinessLogic, + final ComponentInstanceBusinessLogic componentInstanceBusinessLogic, + final UiComponentDataConverter uiComponentDataConverter, final ComponentsUtils componentsUtils, final ToscaOperationFacade toscaOperationFacade, final ServiceBusinessLogic serviceBusinessLogic, final CsarBusinessLogic csarBusinessLogic, final CsarArtifactsAndGroupsBusinessLogic csarArtifactsAndGroupsBusinessLogic, @@ -200,7 +180,7 @@ public class ServiceImportBusinessLogic { final ServiceImportParseLogic serviceImportParseLogic, final ComponentNodeFilterBusinessLogic componentNodeFilterBusinessLogic, final PolicyBusinessLogic policyBusinessLogic, final JanusGraphDao janusGraphDao, - final IGraphLockOperation graphLockOperation) { + final IGraphLockOperation graphLockOperation, final ToscaFunctionService toscaFunctionService) { this.componentInstanceBusinessLogic = componentInstanceBusinessLogic; this.uiComponentDataConverter = uiComponentDataConverter; this.componentsUtils = componentsUtils; @@ -218,6 +198,7 @@ public class ServiceImportBusinessLogic { this.janusGraphDao = janusGraphDao; this.artifactsBusinessLogic = artifactsBusinessLogic; this.graphLockOperation = graphLockOperation; + this.toscaFunctionService = toscaFunctionService; } public Service createService(Service service, AuditingActionEnum auditingAction, User user, Map csarUIPayload, @@ -239,8 +220,11 @@ public class ServiceImportBusinessLogic { csarBusinessLogic.validateCsarBeforeCreate(service, csarUUID); log.debug("CsarUUID is {} - going to create resource from CSAR", csarUUID); return createServiceFromCsar(service, user, csarUIPayload, csarUUID); - } catch (Exception e) { - log.debug("Exception occured when createService,error is:{}", e.getMessage(), e); + } catch (final ComponentException e) { + log.debug("Exception occurred when createService: {}", e.getMessage(), e); + throw e; + } catch (final Exception e) { + log.debug("Exception occurred when createService: {}", e.getMessage(), e); throw new ComponentException(ActionStatus.GENERAL_ERROR); } } @@ -258,8 +242,11 @@ public class ServiceImportBusinessLogic { } return createServiceFromYaml(service, csarInfo.getMainTemplateContent(), csarInfo.getMainTemplateName(), nodeTypesInfo, csarInfo, findNodeTypesArtifactsToHandleRes.left().value(), true, false, null, user.getUserId()); - } catch (Exception e) { - log.debug("Exception occured when createServiceFromCsar,error is:{}", e.getMessage(), e); + } catch (final ComponentException e) { + log.debug("Exception occurred when createServiceFromCsar,error is:{}", e.getMessage(), e); + throw e; + } catch (final Exception e) { + log.debug("Exception occurred when createServiceFromCsar,error is:{}", e.getMessage(), e); throw new ComponentException(ActionStatus.GENERAL_ERROR); } } @@ -925,13 +912,27 @@ public class ServiceImportBusinessLogic { return getServiceResponseFormatEither(service); } - private Either createPoliciesOnResource(Service service, - Map policies) { - if (MapUtils.isNotEmpty(policies)) { - policyBusinessLogic.createPolicies(service, policies); - } else { + private Either createPoliciesOnResource(final Service service, + final Map policies) { + if (MapUtils.isEmpty(policies)) { return Either.left(service); } + final Map> instanceAttributeMap = + service.getComponentInstancesAttributes() + .entrySet().stream() + .collect( + toMap(Entry::getKey, + entry -> entry.getValue().stream().map(AttributeDefinition.class::cast).collect(toList())) + ); + policies.values().stream() + .map(PolicyDataDefinition::getProperties) + .flatMap(Collection::stream) + .filter(PropertyDataDefinition::isToscaFunction) + .forEach(policyDefinition -> + toscaFunctionService + .updateFunctionWithDataFromSelfComponent(policyDefinition.getToscaFunction(), service, service.getComponentInstancesProperties(), instanceAttributeMap) + ); + policyBusinessLogic.createPolicies(service, policies); return getServiceResponseFormatEither(service); } @@ -1357,7 +1358,7 @@ public class ServiceImportBusinessLogic { Map uploadResInstancesMap) { log.debug("#createResourceInstancesRelations - Going to create relations "); List componentInstancesList = service.getComponentInstances(); - if (((MapUtils.isEmpty(uploadResInstancesMap) || CollectionUtils.isEmpty(componentInstancesList)))) { // PNF can have no resource instances + if (MapUtils.isEmpty(uploadResInstancesMap) || CollectionUtils.isEmpty(componentInstancesList)) { // PNF can have no resource instances log.debug("#createResourceInstancesRelations - No instances found in the resource {} is empty, yaml template file name {}, ", service.getUniqueId(), yamlName); BeEcompErrorManager.getInstance() @@ -1378,13 +1379,16 @@ public class ServiceImportBusinessLogic { log.debug("enter ServiceImportBusinessLogic createServiceInstancesRelations#createResourceInstancesRelations - Before get all datatypes. "); final ApplicationDataTypeCache applicationDataTypeCache = serviceBusinessLogic.applicationDataTypeCache; if (applicationDataTypeCache != null) { - Service finalResource = service; + final Map allDataTypesMap = + componentsUtils.getAllDataTypes(applicationDataTypeCache, service.getModel()); + final Service service1 = service; uploadResInstancesMap.values().forEach( - i -> processComponentInstance(yamlName, finalResource, componentInstancesList, - componentsUtils.getAllDataTypes(applicationDataTypeCache, finalResource.getModel()), instProperties, + i -> processComponentInstance(yamlName, service1, componentInstancesList, + allDataTypesMap, instProperties, instCapabilities, instRequirements, instDeploymentArtifacts, instArtifacts, instAttributes, originCompMap, instInputs, instNodeFilter, i)); } + updatePropertyToscaFunctionData(service, instProperties, instAttributes); serviceImportParseLogic.associateComponentInstancePropertiesToComponent(yamlName, service, instProperties); serviceImportParseLogic.associateComponentInstanceInputsToComponent(yamlName, service, instInputs); serviceImportParseLogic.associateCINodeFilterToComponent(yamlName, service, instNodeFilter); @@ -1412,6 +1416,29 @@ public class ServiceImportBusinessLogic { return eitherGetResource.left().value(); } + private void updatePropertyToscaFunctionData(final Component service, + final Map> instancePropertyMap, + final Map> instanceAttributeMap) { + final Component updatedService = + toscaOperationFacade.getToscaElement(service.getUniqueId()).left() + .on(storageOperationStatus -> { + final ActionStatus status = componentsUtils.convertFromStorageResponse(storageOperationStatus); + final ResponseFormat responseFormat = + componentsUtils.getResponseFormatByComponent(status, service, service.getComponentType()); + throw new ComponentException(responseFormat); + } + ); + instancePropertyMap.values().forEach(instancePropertyList -> + instancePropertyList.stream() + .filter(PropertyDataDefinition::isToscaFunction) + .forEach(instanceProperty -> { + toscaFunctionService.updateFunctionWithDataFromSelfComponent(instanceProperty.getToscaFunction(), + updatedService, instancePropertyMap, instanceAttributeMap); + instanceProperty.setValue(instanceProperty.getToscaFunction().getValue()); + }) + ); + } + protected void processComponentInstance(String yamlName, Component component, List componentInstancesList, Map allDataTypes, Map> instProperties, @@ -1426,7 +1453,7 @@ public class ServiceImportBusinessLogic { log.debug("enter ServiceImportBusinessLogic processComponentInstance"); Optional currentCompInstanceOpt = componentInstancesList.stream() .filter(i -> i.getName().equals(uploadComponentInstanceInfo.getName())).findFirst(); - if (!currentCompInstanceOpt.isPresent()) { + if (currentCompInstanceOpt.isEmpty()) { log.debug(COMPONENT_INSTANCE_WITH_NAME_IN_RESOURCE, uploadComponentInstanceInfo.getName(), component.getUniqueId()); BeEcompErrorManager.getInstance() .logInternalDataError(COMPONENT_INSTANCE_WITH_NAME + uploadComponentInstanceInfo.getName() + IN_RESOURCE, component.getUniqueId(), @@ -1542,23 +1569,20 @@ public class ServiceImportBusinessLogic { Map allDataTypes) { Map> propMap = uploadComponentInstanceInfo.getProperties(); Map currPropertiesMap = new HashMap<>(); - List listFromMap = originResource.getProperties(); - if ((propMap != null && !propMap.isEmpty()) && (listFromMap == null || listFromMap.isEmpty())) { + List originalPropertyList = originResource.getProperties(); + if (MapUtils.isNotEmpty(propMap) && CollectionUtils.isEmpty(originalPropertyList)) { log.debug("failed to find properties "); return componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND); } - if (listFromMap == null || listFromMap.isEmpty()) { + if (CollectionUtils.isEmpty(originalPropertyList)) { return componentsUtils.getResponseFormat(ActionStatus.OK); } - for (PropertyDefinition prop : listFromMap) { - String propName = prop.getName(); - if (!currPropertiesMap.containsKey(propName)) { - currPropertiesMap.put(propName, prop); - } - } + originalPropertyList.stream() + .filter(property -> !currPropertiesMap.containsKey(property.getName())) + .forEach(property -> currPropertiesMap.put(property.getName(), property)); List instPropList = new ArrayList<>(); - if (propMap != null && propMap.size() > 0) { - for (List propertyList : propMap.values()) { + if (MapUtils.isNotEmpty(propMap)) { + for (final List propertyList : propMap.values()) { UploadPropInfo propertyInfo = propertyList.get(0); String propName = propertyInfo.getName(); if (!currPropertiesMap.containsKey(propName)) { @@ -1566,26 +1590,26 @@ public class ServiceImportBusinessLogic { return componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, propName); } PropertyDefinition curPropertyDef = currPropertiesMap.get(propName); - ComponentInstanceProperty property = null; String value = null; - List getInputs = null; + final List getInputs = new ArrayList<>(); boolean isValidate = true; if (propertyInfo.getValue() != null) { - getInputs = propertyInfo.getGet_input(); - isValidate = getInputs == null || getInputs.isEmpty(); + getInputs.addAll(propertyInfo.getGet_input()); + isValidate = getInputs.isEmpty(); if (isValidate) { value = getPropertyJsonStringValue(propertyInfo.getValue(), curPropertyDef.getType()); } else { value = getPropertyJsonStringValue(propertyInfo.getValue(), TypeUtils.ToscaTagNamesEnum.GET_INPUT.getElementName()); } } - property = new ComponentInstanceProperty(curPropertyDef, value, null); + final var property = new ComponentInstanceProperty(curPropertyDef, value, null); String validatePropValue = serviceBusinessLogic.validatePropValueBeforeCreate(property, value, isValidate, allDataTypes); property.setValue(validatePropValue); - if (getInputs != null && !getInputs.isEmpty()) { - List getInputValues = new ArrayList<>(); - for (GetInputValueDataDefinition getInput : getInputs) { - List inputs = component.getInputs(); + property.setToscaFunction(propertyInfo.getToscaFunction()); + if (!getInputs.isEmpty()) { + final List getInputValues = new ArrayList<>(); + for (final GetInputValueDataDefinition getInput : getInputs) { + final List inputs = component.getInputs(); if (inputs == null || inputs.isEmpty()) { log.debug("Failed to add property {} to instance. Inputs list is empty ", property); serviceBusinessLogic.rollbackWithException(ActionStatus.INPUTS_NOT_FOUND, @@ -2407,7 +2431,7 @@ public class ServiceImportBusinessLogic { .getResponseFormat(componentsUtils.convertFromStorageResponse(eitherValidation.right().value())); throw new ComponentException(errorResponse); } - if (eitherValidation.left().value()) { + if (Boolean.TRUE.equals(eitherValidation.left().value())) { log.debug("resource with name: {}, already exists", resource.getName()); ResponseFormat errorResponse = componentsUtils .getResponseFormat(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, ComponentTypeEnum.RESOURCE.getValue(), resource.getName()); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ToscaFunctionService.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ToscaFunctionService.java new file mode 100644 index 0000000000..28843af54a --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ToscaFunctionService.java @@ -0,0 +1,158 @@ +/* + * - + * ============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; + +import java.util.List; +import java.util.Map; +import org.openecomp.sdc.be.datatypes.elements.ToscaConcatFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.PropertySource; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; + +@org.springframework.stereotype.Service +public class ToscaFunctionService { + + final List functionTypesToUpdateList = + List.of(ToscaFunctionType.GET_INPUT, ToscaFunctionType.GET_ATTRIBUTE, ToscaFunctionType.GET_PROPERTY, ToscaFunctionType.CONCAT); + + /** + * Sets the sourceUniqueId, sourceName and propertyUniqueId values in a ToscaFunction based on values from the given component. This method may be + * useful during creation of a ToscaFunction where these values are not otherwise provided. + * + * @param toscaFunctionToUpdate the TOSCA function to update + * @param selfComponent the SELF Component + * @param instancePropertyMap the SELF Component instances properties + * @param instanceAttributeMap the SELF Component instances attributes + */ + public void updateFunctionWithDataFromSelfComponent(final ToscaFunction toscaFunctionToUpdate, final Component selfComponent, + final Map> instancePropertyMap, + final Map> instanceAttributeMap) { + switch (toscaFunctionToUpdate.getType()) { + case GET_INPUT: { + updateGetInputFunction((ToscaGetFunctionDataDefinition) toscaFunctionToUpdate, selfComponent); + break; + } + case GET_PROPERTY: + case GET_ATTRIBUTE: { + updateGetPropertyFunction((ToscaGetFunctionDataDefinition) toscaFunctionToUpdate, selfComponent, instancePropertyMap, + instanceAttributeMap); + break; + } + case CONCAT: + updateConcatFunction((ToscaConcatFunction) toscaFunctionToUpdate, selfComponent, instancePropertyMap, instanceAttributeMap); + break; + } + } + + /** + * Updates the TOSCA concat function parameters, where the parameter is a TOSCA function. + * + * @param concatFunction the TOSCA concat function to update + * @param selfComponent the SELF component + * @param instancePropertyMap the component instances properties + * @param instanceAttributeMap the component instances attributes + */ + private void updateConcatFunction(final ToscaConcatFunction concatFunction, final Component selfComponent, + final Map> instancePropertyMap, + final Map> instanceAttributeMap) { + concatFunction.getParameters().stream() + .filter(ToscaFunction.class::isInstance) + .filter(functionParameter -> functionTypesToUpdateList.contains(functionParameter.getType())) + .forEach(functionParameter -> + updateFunctionWithDataFromSelfComponent((ToscaFunction) functionParameter, selfComponent, instancePropertyMap, instanceAttributeMap)); + } + + /** + * Updates the Source Unique Id, the Source Name and the Property Unique Id of the TOSCA get_input function. + * + * @param toscaGetFunction the TOSCA get_input function to update + * @param selfComponent the SELF component + */ + private void updateGetInputFunction(final ToscaGetFunctionDataDefinition toscaGetFunction, final Component selfComponent) { + toscaGetFunction.setSourceUniqueId(selfComponent.getUniqueId()); + toscaGetFunction.setSourceName(selfComponent.getName()); + selfComponent.getInputs().stream() + .filter(inputDefinition -> inputDefinition.getName().equals(toscaGetFunction.getPropertyName())) + .findAny().ifPresent(input -> + toscaGetFunction.setPropertyUniqueId(input.getUniqueId()) + ); + } + + /** + * Updates the Source Unique Id, the Source Name and the Property Unique Id of the TOSCA get function. + * + * @param toscaGetFunction the TOSCA get function to update + * @param selfComponent the SELF component + * @param instancePropertyMap the component instances properties + * @param instanceAttributeMap the component instances attributes + */ + private void updateGetPropertyFunction(final ToscaGetFunctionDataDefinition toscaGetFunction, final Component selfComponent, + final Map> instancePropertyMap, + final Map> instanceAttributeMap) { + if (toscaGetFunction.getPropertySource() == PropertySource.SELF) { + toscaGetFunction.setSourceUniqueId(selfComponent.getUniqueId()); + toscaGetFunction.setSourceName(selfComponent.getName()); + if (toscaGetFunction.getType() == ToscaFunctionType.GET_PROPERTY) { + selfComponent.getProperties().stream() + .filter(property -> property.getName().equals(toscaGetFunction.getPropertyPathFromSource().get(0))) + .findAny() + .ifPresent(property -> + toscaGetFunction.setPropertyUniqueId(property.getUniqueId()) + ); + } else { + selfComponent.getAttributes().stream() + .filter(attribute -> attribute.getName().equals(toscaGetFunction.getPropertyPathFromSource().get(0))) + .findAny() + .ifPresent(attribute -> + toscaGetFunction.setPropertyUniqueId(attribute.getUniqueId()) + ); + } + } else if (toscaGetFunction.getPropertySource() == PropertySource.INSTANCE) { + selfComponent.getComponentInstances().stream() + .filter(componentInstance -> toscaGetFunction.getSourceName().equals(componentInstance.getName())) + .findAny() + .ifPresent(componentInstance -> toscaGetFunction.setSourceUniqueId(componentInstance.getUniqueId())); + if (toscaGetFunction.getType() == ToscaFunctionType.GET_PROPERTY) { + final List instanceProperties = instancePropertyMap.get(toscaGetFunction.getSourceUniqueId()); + instanceProperties.stream() + .filter(property -> property.getName().equals(toscaGetFunction.getPropertyPathFromSource().get(0))) + .findAny() + .ifPresent(property -> + toscaGetFunction.setPropertyUniqueId(property.getUniqueId()) + ); + } else { + final List instanceAttributes = instanceAttributeMap.get(toscaGetFunction.getSourceUniqueId()); + instanceAttributes.stream() + .filter(attribute -> attribute.getName().equals(toscaGetFunction.getPropertyPathFromSource().get(0))) + .findAny() + .ifPresent(attribute -> + toscaGetFunction.setPropertyUniqueId(attribute.getUniqueId()) + ); + } + } + } + +} diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandlerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandlerTest.java new file mode 100644 index 0000000000..5b0096bb3f --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/ToscaFunctionYamlParsingHandlerTest.java @@ -0,0 +1,150 @@ +/* + * - + * ============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.csar; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.datatypes.elements.ToscaConcatFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunctionType; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaStringParameter; +import org.openecomp.sdc.be.datatypes.enums.PropertySource; +import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; + +class ToscaFunctionYamlParsingHandlerTest { + + final ToscaFunctionYamlParsingHandler toscaFunctionYamlParsingHandler = new ToscaFunctionYamlParsingHandler(); + + @Test + void buildToscaFunctionBasedOnPropertyValue_NotAToscaFunctionTest() { + assertEquals(Optional.empty(), toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue(null)); + } + + @Test + void buildToscaFunctionBasedOnPropertyValue_GetInputTest() { + final List getInputParameters = List.of("input", "subProperty"); + final Map getInput = Map.of(ToscaFunctionType.GET_INPUT.getName(), getInputParameters); + final Optional actualToscaFunctionOpt = toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue(getInput); + assertTrue(actualToscaFunctionOpt.isPresent()); + final ToscaFunction actualToscaFunction = actualToscaFunctionOpt.get(); + assertGetInput(actualToscaFunction, getInputParameters); + } + + @Test + void buildToscaFunctionBasedOnPropertyValue_GetPropertyTest() { + final List getPropertyValue = List.of(PropertySource.SELF.getName(), "aProperty", "aSubProperty"); + final Map getProperty = Map.of(ToscaFunctionType.GET_PROPERTY.getName(), getPropertyValue); + + final Optional actualToscaFunctionOpt = toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue(getProperty); + assertTrue(actualToscaFunctionOpt.isPresent()); + final ToscaFunction actualToscaFunction = actualToscaFunctionOpt.get(); + assertEquals(ToscaFunctionType.GET_PROPERTY, actualToscaFunction.getType()); + assertTrue(actualToscaFunction instanceof ToscaGetFunctionDataDefinition); + final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) actualToscaFunction; + assertEquals(ToscaGetFunctionType.GET_PROPERTY, toscaGetFunction.getFunctionType()); + assertEquals("aSubProperty", toscaGetFunction.getPropertyName()); + assertEquals(PropertySource.SELF, toscaGetFunction.getPropertySource()); + assertEquals(getPropertyValue.subList(1, getPropertyValue.size()), toscaGetFunction.getPropertyPathFromSource()); + assertNull(toscaGetFunction.getPropertyUniqueId()); + assertNull(toscaGetFunction.getSourceName()); + } + + @Test + void buildToscaFunctionBasedOnPropertyValue_GetAttributeTest() { + final List getPropertyValue = List.of(PropertySource.INSTANCE.getName(), "anAttribute", "aSubAttribute"); + final Map getProperty = Map.of(ToscaFunctionType.GET_ATTRIBUTE.getName(), getPropertyValue); + + final Optional actualToscaFunctionOpt = toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue(getProperty); + assertTrue(actualToscaFunctionOpt.isPresent()); + final ToscaFunction actualToscaFunction = actualToscaFunctionOpt.get(); + assertEquals(ToscaFunctionType.GET_ATTRIBUTE, actualToscaFunction.getType()); + assertTrue(actualToscaFunction instanceof ToscaGetFunctionDataDefinition); + final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) actualToscaFunction; + assertEquals(ToscaGetFunctionType.GET_ATTRIBUTE, toscaGetFunction.getFunctionType()); + assertEquals("aSubAttribute", toscaGetFunction.getPropertyName()); + assertEquals(PropertySource.INSTANCE, toscaGetFunction.getPropertySource()); + assertEquals(getPropertyValue.subList(1, getPropertyValue.size()), toscaGetFunction.getPropertyPathFromSource()); + assertEquals(getPropertyValue.get(0), toscaGetFunction.getSourceName()); + assertNull(toscaGetFunction.getPropertyUniqueId()); + } + + @Test + void buildToscaFunctionBasedOnPropertyValue_ConcatTest() { + final List concatValue = List.of("string1", "-", Map.of(ToscaFunctionType.GET_INPUT.getName(), "inputName")); + final Map concatValueMap = Map.of(ToscaFunctionType.CONCAT.getName(), concatValue); + + final Optional actualToscaFunctionOpt = toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue(concatValueMap); + assertTrue(actualToscaFunctionOpt.isPresent()); + final ToscaFunction actualToscaFunction = actualToscaFunctionOpt.get(); + assertEquals(ToscaFunctionType.CONCAT, actualToscaFunction.getType()); + assertTrue(actualToscaFunction instanceof ToscaConcatFunction); + final ToscaConcatFunction toscaConcatFunction = (ToscaConcatFunction) actualToscaFunction; + assertEquals(3, toscaConcatFunction.getParameters().size()); + assertTrue(toscaConcatFunction.getParameters().get(0) instanceof ToscaStringParameter); + final ToscaStringParameter parameter1 = (ToscaStringParameter) toscaConcatFunction.getParameters().get(0); + assertEquals("string1", parameter1.getValue()); + assertTrue(toscaConcatFunction.getParameters().get(1) instanceof ToscaStringParameter); + final ToscaStringParameter parameter2 = (ToscaStringParameter) toscaConcatFunction.getParameters().get(1); + assertEquals("-", parameter2.getValue()); + assertTrue(toscaConcatFunction.getParameters().get(2) instanceof ToscaGetFunctionDataDefinition); + final ToscaGetFunctionDataDefinition getFunction = (ToscaGetFunctionDataDefinition) toscaConcatFunction.getParameters().get(2); + assertGetInput(getFunction, List.of("inputName")); + } + + + @Test + void isPropertyValueToscaFunctionTest() { + assertFalse(toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(ToscaFunctionType.GET_INPUT.getName())); + assertFalse(toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(new HashMap<>())); + assertFalse(toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction( + Map.of(ToscaFunctionType.GET_ATTRIBUTE.getName(), "", ToscaFunctionType.GET_INPUT.getName(), "") + ) + ); + assertTrue(toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(Map.of(ToscaFunctionType.GET_ATTRIBUTE.getName(), ""))); + assertTrue(toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(Map.of(ToscaFunctionType.GET_INPUT.getName(), ""))); + assertTrue(toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(Map.of(ToscaFunctionType.GET_PROPERTY.getName(), ""))); + assertTrue(toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(Map.of(ToscaFunctionType.CONCAT.getName(), ""))); + assertFalse(toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(Map.of(ToscaFunctionType.YAML.getName(), ""))); + assertFalse(toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(Map.of(ToscaFunctionType.STRING.getName(), ""))); + } + + private static void assertGetInput(final ToscaFunction actualGetInputFunction, final List expectedGetInputParameters) { + assertEquals(ToscaFunctionType.GET_INPUT, actualGetInputFunction.getType()); + assertTrue(actualGetInputFunction instanceof ToscaGetFunctionDataDefinition); + final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) actualGetInputFunction; + assertEquals(ToscaGetFunctionType.GET_INPUT, toscaGetFunction.getFunctionType()); + assertEquals(expectedGetInputParameters.get(expectedGetInputParameters.size() - 1), toscaGetFunction.getPropertyName()); + assertEquals(PropertySource.SELF, toscaGetFunction.getPropertySource()); + assertEquals(expectedGetInputParameters, toscaGetFunction.getPropertyPathFromSource()); + assertNull(toscaGetFunction.getPropertyUniqueId()); + assertNull(toscaGetFunction.getSourceName()); + } +} \ No newline at end of file diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandlerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandlerTest.java index 6d779a192e..d9525b1590 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandlerTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandlerTest.java @@ -90,6 +90,8 @@ public class YamlTemplateParsingHandlerTest { private User user; @Mock private PolicyTypeBusinessLogic policyTypeBusinessLogic; + @Mock + private ToscaFunctionYamlParsingHandler toscaFunctionYamlParsingHandler; private YamlTemplateParsingHandler handler; @@ -135,10 +137,9 @@ public class YamlTemplateParsingHandlerTest { @BeforeEach public void setup() { - - AnnotationBusinessLogic annotationBusinessLogic = new AnnotationBusinessLogic(annotationTypeOperations, - annotationValidator); - handler = new YamlTemplateParsingHandler(janusGraphDao, groupTypeBusinessLogic, annotationBusinessLogic, policyTypeBusinessLogic); + final var annotationBusinessLogic = new AnnotationBusinessLogic(annotationTypeOperations, annotationValidator); + handler = new YamlTemplateParsingHandler(janusGraphDao, groupTypeBusinessLogic, annotationBusinessLogic, policyTypeBusinessLogic, + toscaFunctionYamlParsingHandler); ReflectionTestUtils.setField(handler, "policyTypeBusinessLogic", policyTypeBusinessLogic); } @@ -315,15 +316,15 @@ public class YamlTemplateParsingHandlerTest { assertEquals(5, resourceInstanceWithAttributes.getAttributes().size()); assertTrue(resourceInstanceWithAttributes.getAttributes().containsKey("fq_name")); - assertEquals(resourceInstanceWithAttributes.getAttributes().get("fq_name").getValue(), "fq_name_value"); + assertEquals("fq_name_value", resourceInstanceWithAttributes.getAttributes().get("fq_name").getValue()); assertTrue(resourceInstanceWithAttributes.getAttributes().containsKey("tosca_name")); - assertEquals(resourceInstanceWithAttributes.getAttributes().get("tosca_name").getValue(), "tosca_name_value"); + assertEquals("tosca_name_value", resourceInstanceWithAttributes.getAttributes().get("tosca_name").getValue()); assertTrue(resourceInstanceWithAttributes.getAttributes().containsKey("subnets_show")); - assertEquals(resourceInstanceWithAttributes.getAttributes().get("subnets_show").getValue(), expectedSubnetsShowList); + assertEquals(expectedSubnetsShowList, resourceInstanceWithAttributes.getAttributes().get("subnets_show").getValue()); assertTrue(resourceInstanceWithAttributes.getAttributes().containsKey("subnets_name")); - assertEquals(resourceInstanceWithAttributes.getAttributes().get("subnets_name").getValue(), expectedSubnetsNameMap); + assertEquals(expectedSubnetsNameMap, resourceInstanceWithAttributes.getAttributes().get("subnets_name").getValue()); assertTrue(resourceInstanceWithAttributes.getAttributes().containsKey("new_attribute")); - assertEquals(resourceInstanceWithAttributes.getAttributes().get("new_attribute").getValue(), "new_attribute_value"); + assertEquals("new_attribute_value", resourceInstanceWithAttributes.getAttributes().get("new_attribute").getValue()); } private void validateParsedYaml(ParsedToscaYamlInfo parsedYaml, String group, List expectedProp) { diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java index d85ad38120..ff47d75509 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java @@ -1483,7 +1483,7 @@ class ResourceBusinessLogicTest { String resourceYml = new String(csar.get("Definitions/my_vnf.yaml")); YamlTemplateParsingHandler yamlTemplateParser = new YamlTemplateParsingHandler(mockJanusGraphDao, null, - Mockito.mock(AnnotationBusinessLogic.class), null); + Mockito.mock(AnnotationBusinessLogic.class), null, null); final ParsedToscaYamlInfo parsedToscaYamlInfo = yamlTemplateParser.parseResourceInfoFromYAML("Definitions/my_vnf.yml", resourceYml, Collections.EMPTY_MAP, Collections.EMPTY_MAP, "myVnf", resourceResponse, ""); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ToscaFunctionServiceTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ToscaFunctionServiceTest.java new file mode 100644 index 0000000000..89507d43dd --- /dev/null +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ToscaFunctionServiceTest.java @@ -0,0 +1,148 @@ +/* + * - + * ============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; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.openecomp.sdc.be.datatypes.elements.ToscaConcatFunction; +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.AttributeDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Service; + +class ToscaFunctionServiceTest { + + private final ToscaFunctionService toscaFunctionService = new ToscaFunctionService(); + + + @Test + void updateFunctionWithDataFromSelfComponentTest() { + //given a component with one property, one attribute, one instance. The instance have one property and one attribute. + final Component component = new Service(); + component.setUniqueId("componentId"); + component.setName("componentName"); + final var componentInput1 = new InputDefinition(); + componentInput1.setUniqueId("input1Id"); + componentInput1.setName("input1Name"); + component.setInputs(List.of(componentInput1)); + + final var componentAttribute1 = new AttributeDefinition(); + componentAttribute1.setUniqueId("componentAttribute1Id"); + componentAttribute1.setName("componentAttribute1Name"); + component.setAttributes(List.of(componentAttribute1)); + + final var componentProperty1 = new PropertyDefinition(); + componentProperty1.setUniqueId("componentProperty1Id"); + componentProperty1.setName("componentProperty1Name"); + component.setProperties(List.of(componentProperty1)); + + final var componentInstance1 = new ComponentInstance(); + componentInstance1.setName("componentInstance1Name"); + componentInstance1.setUniqueId("componentInstance1Id"); + component.setComponentInstances(List.of(componentInstance1)); + + final Map> instancePropertyMap = new HashMap<>(); + final var componentInstanceProperty = new ComponentInstanceProperty(); + final String instancePropertyId1 = "instancePropertyId1"; + componentInstanceProperty.setUniqueId(instancePropertyId1); + final String instancePropertyName1 = "instancePropertyName1"; + componentInstanceProperty.setName(instancePropertyName1); + instancePropertyMap.put(componentInstance1.getUniqueId(), List.of(componentInstanceProperty)); + + final Map> instanceAttributeMap = new HashMap<>(); + final AttributeDefinition instanceAttribute1 = new ComponentInstanceAttribute(); + instanceAttribute1.setUniqueId("instanceAttribute1Id"); + instanceAttribute1.setName("instanceAttribute1Name"); + instanceAttributeMap.put(componentInstance1.getUniqueId(), List.of(instanceAttribute1)); + + final ToscaConcatFunction toscaConcatFunction = new ToscaConcatFunction(); + + final ToscaGetFunctionDataDefinition toscaGetInput = new ToscaGetFunctionDataDefinition(); + toscaGetInput.setFunctionType(ToscaGetFunctionType.GET_INPUT); + toscaGetInput.setPropertyName(componentInput1.getName()); + toscaGetInput.setPropertySource(PropertySource.SELF); + toscaConcatFunction.setParameters(List.of(toscaGetInput)); + + final ToscaGetFunctionDataDefinition toscaGetPropertyFromInstance = new ToscaGetFunctionDataDefinition(); + toscaGetPropertyFromInstance.setFunctionType(ToscaGetFunctionType.GET_PROPERTY); + toscaGetPropertyFromInstance.setPropertyName(instancePropertyName1); + toscaGetPropertyFromInstance.setSourceName(componentInstance1.getName()); + toscaGetPropertyFromInstance.setPropertySource(PropertySource.INSTANCE); + toscaGetPropertyFromInstance.setPropertyPathFromSource(List.of(instancePropertyName1)); + + final ToscaGetFunctionDataDefinition toscaGetPropertyFromSelf = new ToscaGetFunctionDataDefinition(); + toscaGetPropertyFromSelf.setFunctionType(ToscaGetFunctionType.GET_PROPERTY); + toscaGetPropertyFromSelf.setPropertyName(componentProperty1.getName()); + toscaGetPropertyFromSelf.setPropertySource(PropertySource.SELF); + toscaGetPropertyFromSelf.setPropertyPathFromSource(List.of(componentProperty1.getName())); + + final ToscaGetFunctionDataDefinition toscaGetAttributeFromInstance = new ToscaGetFunctionDataDefinition(); + toscaGetAttributeFromInstance.setFunctionType(ToscaGetFunctionType.GET_ATTRIBUTE); + toscaGetAttributeFromInstance.setPropertyName(instanceAttribute1.getUniqueId()); + toscaGetAttributeFromInstance.setSourceName(componentInstance1.getName()); + toscaGetAttributeFromInstance.setPropertySource(PropertySource.INSTANCE); + toscaGetAttributeFromInstance.setPropertyPathFromSource(List.of(instanceAttribute1.getName())); + + final ToscaGetFunctionDataDefinition toscaGetAttributeFromSelf = new ToscaGetFunctionDataDefinition(); + toscaGetAttributeFromSelf.setFunctionType(ToscaGetFunctionType.GET_ATTRIBUTE); + toscaGetAttributeFromSelf.setPropertyName(componentAttribute1.getName()); + toscaGetAttributeFromSelf.setPropertySource(PropertySource.SELF); + toscaGetAttributeFromSelf.setPropertyPathFromSource(List.of(componentAttribute1.getName())); + + toscaConcatFunction.setParameters( + List.of(toscaGetInput, toscaGetPropertyFromSelf, toscaGetPropertyFromInstance, toscaGetAttributeFromSelf, toscaGetAttributeFromInstance) + ); + + //when + toscaFunctionService.updateFunctionWithDataFromSelfComponent(toscaConcatFunction, component, instancePropertyMap, instanceAttributeMap); + + //then + assertEquals(componentInput1.getUniqueId(), toscaGetInput.getPropertyUniqueId()); + assertEquals(component.getUniqueId(), toscaGetInput.getSourceUniqueId()); + assertEquals(component.getName(), toscaGetInput.getSourceName()); + + assertEquals(instancePropertyId1, toscaGetPropertyFromInstance.getPropertyUniqueId()); + assertEquals(componentInstance1.getUniqueId(), toscaGetPropertyFromInstance.getSourceUniqueId()); + + assertEquals(instanceAttribute1.getUniqueId(), toscaGetAttributeFromInstance.getPropertyUniqueId()); + assertEquals(componentInstance1.getUniqueId(), toscaGetAttributeFromInstance.getSourceUniqueId()); + + assertEquals(componentAttribute1.getUniqueId(), toscaGetAttributeFromSelf.getPropertyUniqueId()); + assertEquals(component.getUniqueId(), toscaGetAttributeFromSelf.getSourceUniqueId()); + assertEquals(component.getName(), toscaGetAttributeFromSelf.getSourceName()); + + assertEquals(componentProperty1.getUniqueId(), toscaGetPropertyFromSelf.getPropertyUniqueId()); + assertEquals(component.getUniqueId(), toscaGetPropertyFromSelf.getSourceUniqueId()); + assertEquals(component.getName(), toscaGetPropertyFromSelf.getSourceName()); + } +} \ No newline at end of file diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.java index d5221eeef2..da71aeef97 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.java @@ -21,14 +21,20 @@ package org.openecomp.sdc.be.model; import java.util.ArrayList; import java.util.List; +import lombok.Getter; +import lombok.Setter; import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaFunction; +@Setter +@Getter public class UploadPropInfo extends UploadInfo { private Object value; private String description; private boolean password; private List get_input; + private ToscaFunction toscaFunction; public List getGet_input() { if (get_input == null) { @@ -37,31 +43,4 @@ public class UploadPropInfo extends UploadInfo { return get_input; } - public void setGet_input(List get_input) { - this.get_input = get_input; - } - - public Object getValue() { - return value; - } - - public void setValue(Object value) { - this.value = value; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public boolean isPassword() { - return password; - } - - public void setPassword(boolean password) { - this.password = password; - } } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java index b66f6c9433..7546e90a82 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java @@ -1701,140 +1701,6 @@ public class PropertyOperation extends AbstractOperation implements IPropertyOpe return validateAndUpdatePropertyValue(property.getType(), property.getValue(), true, innerType, dataTypes); } -// private void validateToscaGetFunction(T property, org.openecomp.sdc.be.model.Component parentComponent) { -// final ToscaGetFunctionDataDefinition toscaGetFunction = (ToscaGetFunctionDataDefinition) property.getToscaFunction(); -// validateGetToscaFunctionAttributes(toscaGetFunction); -// validateGetPropertySource(toscaGetFunction.getFunctionType(), toscaGetFunction.getPropertySource()); -// if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_INPUT) { -// validateGetFunction(property, parentComponent.getInputs(), parentComponent.getModel()); -// return; -// } -// if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_PROPERTY) { -// if (toscaGetFunction.getPropertySource() == PropertySource.SELF) { -// validateGetFunction(property, parentComponent.getProperties(), parentComponent.getModel()); -// } else if (toscaGetFunction.getPropertySource() == PropertySource.INSTANCE) { -// final ComponentInstance componentInstance = -// parentComponent.getComponentInstanceById(toscaGetFunction.getSourceUniqueId()) -// .orElseThrow(ToscaGetFunctionExceptionSupplier.instanceNotFound(toscaGetFunction.getSourceName())); -// validateGetFunction(property, componentInstance.getProperties(), parentComponent.getModel()); -// } -// -// return; -// } -// if (toscaGetFunction.getFunctionType() == ToscaGetFunctionType.GET_ATTRIBUTE) { -// if (toscaGetFunction.getPropertySource() == PropertySource.SELF) { -// validateGetFunction(property, parentComponent.getAttributes(), parentComponent.getModel()); -// } else if (toscaGetFunction.getPropertySource() == PropertySource.INSTANCE) { -// final ComponentInstance componentInstance = -// parentComponent.getComponentInstanceById(toscaGetFunction.getSourceUniqueId()) -// .orElseThrow(ToscaGetFunctionExceptionSupplier.instanceNotFound(toscaGetFunction.getSourceName())); -// validateGetFunction(property, componentInstance.getAttributes(), parentComponent.getModel()); -// } -// -// return; -// } -// -// throw ToscaGetFunctionExceptionSupplier.functionNotSupported(toscaGetFunction.getFunctionType()).get(); -// } - -// private void validateGetFunction(final T property, -// final List 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 dataTypeMap = loadDataTypes(model); -// final List propertyPathFromSource = toscaGetFunction.getPropertyPathFromSource(); -// DataTypeDefinition dataType = dataTypeMap.get(referredProperty.getType()); -// if (dataType == null) { -// throw ToscaGetFunctionExceptionSupplier -// .propertyDataTypeNotFound(propertyPathFromSource.get(0), referredProperty.getType(), toscaGetFunction.getFunctionType()).get(); -// } -// ToscaPropertyData foundProperty = referredProperty; -// for (int i = 1; i < propertyPathFromSource.size(); i++) { -// final String currentPropertyName = propertyPathFromSource.get(i); -// foundProperty = dataType.getProperties().stream() -// .filter(propertyDefinition -> currentPropertyName.equals(propertyDefinition.getName())).findFirst() -// .orElseThrow( -// ToscaGetFunctionExceptionSupplier -// .propertyNotFoundOnTarget(propertyPathFromSource.subList(0, i), toscaGetFunction.getPropertySource(), -// toscaGetFunction.getFunctionType()) -// ); -// dataType = dataTypeMap.get(foundProperty.getType()); -// if (dataType == null) { -// throw ToscaGetFunctionExceptionSupplier -// .propertyDataTypeNotFound(propertyPathFromSource.subList(0, i), foundProperty.getType(), -// toscaGetFunction.getFunctionType()).get(); -// } -// } -// return foundProperty; -// } - public Either, StorageOperationStatus> getAllPropertiesRec(String uniqueId, NodeTypeEnum nodeType, Class clazz) { return this.findPropertiesOfNode(nodeType, uniqueId).right().bind(this::handleNotFoundProperties).left() diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaConcatFunction.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaConcatFunction.java index 62307fb4be..975721be26 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaConcatFunction.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaConcatFunction.java @@ -53,4 +53,8 @@ public class ToscaConcatFunction implements ToscaFunction, ToscaFunctionParamete ); } + public void addParameter(final ToscaFunctionParameter functionParameter) { + this.parameters.add(functionParameter); + } + } diff --git a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java index fda832b98e..363af1cdeb 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ToscaFunctionJsonDeserializer.java @@ -105,9 +105,11 @@ public class ToscaFunctionJsonDeserializer extends StdDeserializer context.instantiationException(ToscaGetFunctionDataDefinition.class, @@ -115,9 +117,6 @@ public class ToscaFunctionJsonDeserializer extends StdDeserializer