diff options
author | andre.schmid <andre.schmid@est.tech> | 2022-07-29 20:39:23 +0100 |
---|---|---|
committer | Michael Morris <michael.morris@est.tech> | 2022-08-06 22:43:00 +0000 |
commit | 7b0009c2bebe54214f920baf6b2aa4058921777b (patch) | |
tree | 1e5a24cea14540b1e6b8777719487aa47497fa42 /catalog-be | |
parent | c2f19bdcf5b5d5647770a5d3435d942fb3dd0efa (diff) |
Support for TOSCA functions for Service Import
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 <andre.schmid@est.tech>
Diffstat (limited to 'catalog-be')
8 files changed, 819 insertions, 166 deletions
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<ToscaFunction> buildToscaFunctionBasedOnPropertyValue(final Map<String, Object> 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<String, Object> propValueMap = (Map<String, Object>) 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<ToscaFunction> handleConcatFunction(Map<String, Object> toscaFunctionPropertyValueMap, String functionType) { + final ToscaConcatFunction toscaConcatFunction = new ToscaConcatFunction(); + final Object functionValueObj = toscaFunctionPropertyValueMap.get(functionType); + if (!(functionValueObj instanceof List)) { + return Optional.empty(); + } + final List<Object> functionParameters = (List<Object>) 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<String, Object>) 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<ToscaFunction> handleGetPropertyFunction(Map<String, Object> 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<String> functionParameters; + try { + functionParameters = (List<String>) 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<ToscaFunction> handleGetInputFunction(Map<String, Object> 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<String> functionParameters; + try { + functionParameters = (List<String>) 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<String, String> createdNodesToscaResourceNames, @@ -306,31 +306,36 @@ public class YamlTemplateParsingHandler { return policyTypeDefinition; } - private List<PropertyDataDefinition> validateFillPolicyProperties(PolicyTypeDefinition policyTypeDefinition, - Map<String, Object> policyTemplateJsonMap) { - if (MapUtils.isEmpty(policyTemplateJsonMap) || Objects.isNull(policyTypeDefinition)) { + private List<PropertyDataDefinition> validateFillPolicyProperties(final PolicyTypeDefinition policyTypeDefinition, + final Map<String, Object> policyTemplateJsonMap) { + if (policyTypeDefinition == null || CollectionUtils.isEmpty(policyTypeDefinition.getProperties()) + || MapUtils.isEmpty(policyTemplateJsonMap)) { return Collections.emptyList(); } - List<PropertyDataDefinition> propertyDataDefinitionList = new ArrayList<>(); - Map<String, Object> propertiesMap = (Map<String, Object>) policyTemplateJsonMap.get(PROPERTIES.getElementName()); - if (MapUtils.isEmpty(propertiesMap)) { + final Map<String, Object> propertiesJsonMap = (Map<String, Object>) 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<String, Object> 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<PolicyTargetType, List<String>> validateFillPolicyTargets(Map<String, Object> policyTemplateJson) { @@ -473,8 +478,8 @@ public class YamlTemplateParsingHandler { .collect(Collectors.toMap(GroupDefinition::getName, g -> g)); Map<String, Object> substitutionMappings = getSubstitutionMappings(toscaJson); if (capabilitiesSubstitutionMappingsExist(substitutionMappings)) { - groups.entrySet().forEach(entry -> updateCapabilitiesNames(entry.getValue(), - getNamesToUpdate(entry.getKey(), (Map<String, List<String>>) substitutionMappings.get(CAPABILITIES.getElementName())))); + groups.forEach((key, value) -> updateCapabilitiesNames(value, + getNamesToUpdate(key, (Map<String, List<String>>) substitutionMappings.get(CAPABILITIES.getElementName())))); } return groups; } @@ -555,28 +560,21 @@ public class YamlTemplateParsingHandler { } } - private void mergeGroupProperties(GroupDefinition groupInfo, Map<String, Object> parsedProperties) { - if (CollectionUtils.isNotEmpty(groupInfo.getProperties())) { - validateGroupProperties(parsedProperties, groupInfo); - groupInfo.getProperties().forEach(p -> mergeGroupProperty(p, parsedProperties)); - } - } - - private void mergeGroupProperty(PropertyDataDefinition property, Map<String, Object> 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<String, Object> 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<String, Object> parsedProperties, GroupDefinition groupInfo) { - List<String> parsedPropertiesNames = parsedProperties.entrySet().stream().map(Map.Entry::getKey).collect(toList()); + List<String> 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<String, Object> nodeTemplateJsonMap) { if (nodeTemplateJsonMap.containsKey(PROPERTIES.getElementName())) { - Map<String, List<UploadPropInfo>> properties = buildPropModuleFromYaml(nodeTemplateJsonMap); + Map<String, List<UploadPropInfo>> properties = + buildPropModuleFromYaml((Map<String, Object>) 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<String, List<UploadPropInfo>> props = buildPropModuleFromYaml(nodeTemplateJsonMap); + Map<String, List<UploadPropInfo>> props = + buildPropModuleFromYaml((Map<String, Object>) nodeTemplateJsonMap.get(PROPERTIES.getElementName())); if (!props.isEmpty()) { List<UploadPropInfo> 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<String, List<UploadPropInfo>> props = buildPropModuleFromYaml(nodeTemplateJsonMap); + Map<String, List<UploadPropInfo>> props = + buildPropModuleFromYaml((Map<String, Object>) nodeTemplateJsonMap.get(PROPERTIES.getElementName())); if (!props.isEmpty()) { List<UploadPropInfo> properties = props.values().stream().flatMap(Collection::stream).collect(toList()); capTemplateInfo.setProperties(properties); @@ -1063,17 +1064,9 @@ public class YamlTemplateParsingHandler { return attributeDef; } - private Map<String, List<UploadPropInfo>> buildPropModuleFromYaml(Map<String, Object> nodeTemplateJsonMap) { - Map<String, List<UploadPropInfo>> moduleProp = new HashMap<>(); - Either<Map<String, Object>, ResultStatusEnum> toscaProperties = findFirstToscaMapElement(nodeTemplateJsonMap, PROPERTIES); - if (toscaProperties.isLeft()) { - Map<String, Object> jsonProperties = toscaProperties.left().value(); - for (Map.Entry<String, Object> jsonPropObj : jsonProperties.entrySet()) { - if (valueNotContainsPattern(propertyValuePattern, jsonPropObj.getValue())) { - addProperty(moduleProp, jsonPropObj); - } - } - } + private Map<String, List<UploadPropInfo>> buildPropModuleFromYaml(final Map<String, Object> propertyMap) { + final Map<String, List<UploadPropInfo>> 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<String, Object>) propValue).containsKey(TYPE.getElementName())) { - propertyDef.setType(((Map<String, Object>) propValue).get(TYPE.getElementName()).toString()); + if (propValueObj instanceof Map) { + final Map<String, Object> propValueMap = (Map<String, Object>) propValueObj; + if (propValueMap.containsKey(TYPE.getElementName())) { + propertyDef.setType(propValueMap.get(TYPE.getElementName()).toString()); } - if (containsGetInput(propValue)) { - fillInputRecursively(propName, (Map<String, Object>) propValue, propertyDef); + if (containsGetInput(propValueObj)) { + fillInputRecursively(propName, propValueMap, propertyDef); } - if (((Map<String, Object>) propValue).containsKey(DESCRIPTION.getElementName())) { - propertyDef.setDescription(((Map<String, Object>) propValue).get(DESCRIPTION.getElementName()).toString()); + if (toscaFunctionYamlParsingHandler.isPropertyValueToscaFunction(propValueObj)) { + toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue(propValueMap).ifPresent(propertyDef::setToscaFunction); } - if (((Map<String, Object>) propValue).containsKey(DEFAULT_VALUE.getElementName())) { - propertyDef.setValue(((Map<String, Object>) propValue).get(DEFAULT_VALUE.getElementName())); + if (propValueMap.containsKey(DESCRIPTION.getElementName())) { + propertyDef.setDescription((propValueMap).get(DESCRIPTION.getElementName()).toString()); } - if (((Map<String, Object>) propValue).containsKey(IS_PASSWORD.getElementName())) { - propertyDef.setPassword(Boolean.getBoolean(((Map<String, Object>) 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<Object> propValueList = (List<Object>) propValue; - fillInputsListRecursively(propertyDef, propValueList); - propertyDef.setValue(propValue); + } else if (propValueObj instanceof List) { + fillInputsListRecursively(propertyDef, (List<Object>) 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<String, byte[]> 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<Service, ResponseFormat> createPoliciesOnResource(Service service, - Map<String, PolicyDefinition> policies) { - if (MapUtils.isNotEmpty(policies)) { - policyBusinessLogic.createPolicies(service, policies); - } else { + private Either<Service, ResponseFormat> createPoliciesOnResource(final Service service, + final Map<String, PolicyDefinition> policies) { + if (MapUtils.isEmpty(policies)) { return Either.left(service); } + final Map<String, List<AttributeDefinition>> 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<String, UploadComponentInstanceInfo> uploadResInstancesMap) { log.debug("#createResourceInstancesRelations - Going to create relations "); List<ComponentInstance> 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<String, DataTypeDefinition> 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<String, List<ComponentInstanceProperty>> instancePropertyMap, + final Map<String, List<AttributeDefinition>> 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<ComponentInstance> componentInstancesList, Map<String, DataTypeDefinition> allDataTypes, Map<String, List<ComponentInstanceProperty>> instProperties, @@ -1426,7 +1453,7 @@ public class ServiceImportBusinessLogic { log.debug("enter ServiceImportBusinessLogic processComponentInstance"); Optional<ComponentInstance> 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<String, DataTypeDefinition> allDataTypes) { Map<String, List<UploadPropInfo>> propMap = uploadComponentInstanceInfo.getProperties(); Map<String, PropertyDefinition> currPropertiesMap = new HashMap<>(); - List<PropertyDefinition> listFromMap = originResource.getProperties(); - if ((propMap != null && !propMap.isEmpty()) && (listFromMap == null || listFromMap.isEmpty())) { + List<PropertyDefinition> 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<ComponentInstanceProperty> instPropList = new ArrayList<>(); - if (propMap != null && propMap.size() > 0) { - for (List<UploadPropInfo> propertyList : propMap.values()) { + if (MapUtils.isNotEmpty(propMap)) { + for (final List<UploadPropInfo> 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<GetInputValueDataDefinition> getInputs = null; + final List<GetInputValueDataDefinition> 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<GetInputValueDataDefinition> getInputValues = new ArrayList<>(); - for (GetInputValueDataDefinition getInput : getInputs) { - List<InputDefinition> inputs = component.getInputs(); + property.setToscaFunction(propertyInfo.getToscaFunction()); + if (!getInputs.isEmpty()) { + final List<GetInputValueDataDefinition> getInputValues = new ArrayList<>(); + for (final GetInputValueDataDefinition getInput : getInputs) { + final List<InputDefinition> 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<ToscaFunctionType> 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<String, List<ComponentInstanceProperty>> instancePropertyMap, + final Map<String, List<AttributeDefinition>> 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<String, List<ComponentInstanceProperty>> instancePropertyMap, + final Map<String, List<AttributeDefinition>> 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<String, List<ComponentInstanceProperty>> instancePropertyMap, + final Map<String, List<AttributeDefinition>> 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<ComponentInstanceProperty> 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<AttributeDefinition> 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<String> getInputParameters = List.of("input", "subProperty"); + final Map<String, Object> getInput = Map.of(ToscaFunctionType.GET_INPUT.getName(), getInputParameters); + final Optional<ToscaFunction> actualToscaFunctionOpt = toscaFunctionYamlParsingHandler.buildToscaFunctionBasedOnPropertyValue(getInput); + assertTrue(actualToscaFunctionOpt.isPresent()); + final ToscaFunction actualToscaFunction = actualToscaFunctionOpt.get(); + assertGetInput(actualToscaFunction, getInputParameters); + } + + @Test + void buildToscaFunctionBasedOnPropertyValue_GetPropertyTest() { + final List<String> getPropertyValue = List.of(PropertySource.SELF.getName(), "aProperty", "aSubProperty"); + final Map<String, Object> getProperty = Map.of(ToscaFunctionType.GET_PROPERTY.getName(), getPropertyValue); + + final Optional<ToscaFunction> 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<String> getPropertyValue = List.of(PropertySource.INSTANCE.getName(), "anAttribute", "aSubAttribute"); + final Map<String, Object> getProperty = Map.of(ToscaFunctionType.GET_ATTRIBUTE.getName(), getPropertyValue); + + final Optional<ToscaFunction> 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<Object> concatValue = List.of("string1", "-", Map.of(ToscaFunctionType.GET_INPUT.getName(), "inputName")); + final Map<String, Object> concatValueMap = Map.of(ToscaFunctionType.CONCAT.getName(), concatValue); + + final Optional<ToscaFunction> 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<String> 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<String> 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<String, List<ComponentInstanceProperty>> 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<String, List<AttributeDefinition>> 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 |