2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2020 Nordix Foundation
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.be.plugins.etsi.nfv.nsd.generator;
22 import static org.hamcrest.MatcherAssert.assertThat;
23 import static org.hamcrest.Matchers.anEmptyMap;
24 import static org.hamcrest.Matchers.greaterThan;
25 import static org.hamcrest.Matchers.not;
26 import static org.hamcrest.core.Is.is;
27 import static org.hamcrest.core.IsNull.notNullValue;
28 import static org.hamcrest.core.IsNull.nullValue;
29 import static org.junit.Assert.assertEquals;
30 import static org.junit.Assert.assertFalse;
31 import static org.junit.Assert.assertNull;
32 import static org.junit.Assert.assertTrue;
33 import static org.mockito.ArgumentMatchers.any;
34 import static org.mockito.ArgumentMatchers.anyBoolean;
35 import static org.mockito.Mockito.mock;
36 import static org.mockito.Mockito.when;
38 import com.google.common.collect.ImmutableList;
39 import com.google.common.collect.ImmutableMap;
40 import fj.data.Either;
41 import java.io.ByteArrayInputStream;
42 import java.io.IOException;
43 import java.util.ArrayList;
44 import java.util.HashMap;
45 import java.util.List;
47 import java.util.Map.Entry;
48 import org.junit.jupiter.api.BeforeEach;
49 import org.junit.jupiter.api.Test;
50 import org.mockito.Mock;
51 import org.mockito.MockitoAnnotations;
52 import org.openecomp.sdc.be.config.Configuration;
53 import org.openecomp.sdc.be.config.ConfigurationManager;
54 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
55 import org.openecomp.sdc.be.model.Component;
56 import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.exception.NsdException;
57 import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.model.Nsd;
58 import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.model.VnfDescriptor;
59 import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.tosca.yaml.ToscaTemplateYamlGenerator;
60 import org.openecomp.sdc.be.tosca.ToscaExportHandler;
61 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
62 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
63 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
64 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
65 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraint;
66 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintValidValues;
67 import org.openecomp.sdc.be.tosca.model.ToscaRequirement;
68 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
69 import org.openecomp.sdc.be.tosca.model.ToscaTemplateCapability;
70 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
71 import org.openecomp.sdc.common.api.ConfigurationSource;
72 import org.springframework.beans.factory.ObjectProvider;
73 import org.yaml.snakeyaml.Yaml;
75 class NsDescriptorGeneratorImplTest {
77 private static final String VNFD_AMF_NODE_NAME = "vnfd_amf";
78 private static final String VIRTUAL_LINK_REQUIREMENT_NAME = "virtual_link";
79 private static final String VIRTUAL_BINDING_REQUIREMENT_NAME = "virtual_binding";
80 private static final String DOT = ".";
81 private static final String PREFIX = "VNF";
82 private final ObjectProvider<ToscaTemplateYamlGenerator> toscaTemplateYamlGeneratorProvider = new ObjectProvider<>() {
84 public ToscaTemplateYamlGenerator getObject(Object... args) {
85 return new ToscaTemplateYamlGenerator((ToscaTemplate) args[0]);
89 public ToscaTemplateYamlGenerator getIfAvailable() {
94 public ToscaTemplateYamlGenerator getIfUnique() {
99 public ToscaTemplateYamlGenerator getObject() {
104 private ToscaExportHandler toscaExportHandler;
105 private NsDescriptorGeneratorImpl nsDescriptorGenerator;
109 setUpConfigurationMock();
110 MockitoAnnotations.initMocks(this);
111 nsDescriptorGenerator = new NsDescriptorGeneratorImpl(toscaExportHandler, toscaTemplateYamlGeneratorProvider);
114 private void setUpConfigurationMock() {
115 final List<Map<String, Map<String, String>>> defaultImports = new ArrayList<>();
116 final Map<String, Map<String, String>> importMap = new HashMap<>();
117 final Map<String, String> nodeImportEntry = new HashMap<>();
118 nodeImportEntry.put("file", "nodes.yml");
119 importMap.put("nodes", nodeImportEntry);
120 defaultImports.add(importMap);
121 final ConfigurationSource configurationSource = mock(ConfigurationSource.class);
122 final Configuration configuration = new Configuration();
123 configuration.setDefaultImports(defaultImports);
124 configuration.setHeatEnvArtifactHeader("");
125 configuration.setHeatEnvArtifactFooter("");
126 when(configurationSource.getAndWatchConfiguration(any(), any())).thenReturn(configuration);
127 new ConfigurationManager(configurationSource);
131 @SuppressWarnings("unchecked")
132 void testGenerate() throws IOException, NsdException {
134 final Component component = mock(Component.class);
135 when(component.getComponentType()).thenReturn(ComponentTypeEnum.SERVICE);
136 final ToscaTemplate componentToscaTemplate = new ToscaTemplate("");
137 final ToscaTopolgyTemplate componentToscaTopologyTemplate = new ToscaTopolgyTemplate();
138 componentToscaTemplate.setTopology_template(componentToscaTopologyTemplate);
139 final HashMap<String, ToscaNodeTemplate> nodeTemplateMap = new HashMap<>();
140 final ToscaNodeTemplate vnfAmfNodeTemplate = new ToscaNodeTemplate();
141 vnfAmfNodeTemplate.setType("com.ericsson.resource.abstract.Ericsson.AMF");
142 final Map<String, Object> propertyMap = new HashMap<>();
143 //a property to be excluded
144 propertyMap.put("nf_naming_code", new ToscaProperty());
145 //a property that wont be excluded
146 propertyMap.put("will_not_be_excluded", new ToscaProperty());
147 vnfAmfNodeTemplate.setProperties(propertyMap);
148 nodeTemplateMap.put(VNFD_AMF_NODE_NAME, vnfAmfNodeTemplate);
149 final Map<String, ToscaTemplateCapability> vnfAmfCapabilities = new HashMap<>();
150 vnfAmfCapabilities.put("myCapability", new ToscaTemplateCapability());
151 vnfAmfNodeTemplate.setCapabilities(vnfAmfCapabilities);
152 componentToscaTopologyTemplate.setNode_templates(nodeTemplateMap);
153 final SubstitutionMapping substitutionMapping = mock(SubstitutionMapping.class);
154 Map<String, String[]> requirements = new HashMap<>();
155 String[] requirementAssignmentVl = {"VNF1", PREFIX + DOT + VIRTUAL_LINK_REQUIREMENT_NAME};
156 requirements.put("VNF1" + DOT + VIRTUAL_LINK_REQUIREMENT_NAME, requirementAssignmentVl);
157 when(substitutionMapping.getRequirements()).thenReturn(requirements);
158 Map<String, String[]> capabilities = new HashMap<>();
159 String[] capabilitiesAssignment = {"VNF1", "capability1"};
160 capabilities.put("capability", capabilitiesAssignment);
161 when(substitutionMapping.getCapabilities()).thenReturn(capabilities);
162 componentToscaTopologyTemplate.setSubstitution_mappings(substitutionMapping);
164 Map<String, ToscaProperty> inputs = new HashMap<>();
165 inputs.put("invariant_id", new ToscaProperty());
166 inputs.put("other_property", new ToscaProperty());
167 componentToscaTopologyTemplate.setInputs(inputs );
168 final ToscaTemplate componentInterfaceToscaTemplate = new ToscaTemplate("");
169 final String designerPropertyValue = "designerValue";
170 final String versionPropertyValue = "versionValue";
171 final String namePropertyValue = "nameValue";
172 final String invariantIdPropertyValue = "invariantIdValue";
173 final String otherPropertyValue = "otherValue";
174 final ToscaNodeType interfaceToscaNodeType = createDefaultInterfaceToscaNodeType(designerPropertyValue, versionPropertyValue,
175 namePropertyValue, invariantIdPropertyValue, otherPropertyValue);
176 List<Map<String, ToscaRequirement>> interfaceNodeTypeRequirements = new ArrayList<>();
177 Map<String, ToscaRequirement> interfaceNodeTypeRequirementMap = new HashMap<>();
178 interfaceNodeTypeRequirementMap.put("VNF1" + DOT + VIRTUAL_LINK_REQUIREMENT_NAME, mock(ToscaRequirement.class));
179 interfaceNodeTypeRequirementMap.put("VNF1" + DOT + VIRTUAL_BINDING_REQUIREMENT_NAME, mock(ToscaRequirement.class));
180 interfaceNodeTypeRequirements.add(interfaceNodeTypeRequirementMap);
181 interfaceToscaNodeType.setRequirements(interfaceNodeTypeRequirements);
182 final String nsNodeTypeName = "nsNodeTypeName";
183 componentInterfaceToscaTemplate.setNode_types(ImmutableMap.of(nsNodeTypeName, interfaceToscaNodeType));
184 when(toscaExportHandler.convertToToscaTemplate(component)).thenReturn(Either.left(componentToscaTemplate));
185 when(toscaExportHandler.convertInterfaceNodeType(any(), any(), any(), any(), anyBoolean()))
186 .thenReturn(Either.left(componentInterfaceToscaTemplate));
187 final List<VnfDescriptor> vnfDescriptorList = new ArrayList<>();
188 VnfDescriptor vnfDescriptor1 = new VnfDescriptor();
189 vnfDescriptor1.setName(VNFD_AMF_NODE_NAME);
190 vnfDescriptor1.setVnfdFileName("vnfd_amf.yaml");
191 vnfDescriptor1.setNodeType("com.ericsson.resource.abstract.Ericsson.AMF");
192 vnfDescriptorList.add(vnfDescriptor1);
194 final Nsd nsd = nsDescriptorGenerator.generate(component, vnfDescriptorList).orElse(null);
197 assertThat("Nsd designer should be as expected", nsd.getDesigner(), is(designerPropertyValue));
198 assertThat("Nsd version should be as expected", nsd.getVersion(), is(versionPropertyValue));
199 assertThat("Nsd name should be as expected", nsd.getName(), is(namePropertyValue));
200 assertThat("Nsd invariantId should be as expected", nsd.getInvariantId(), is(invariantIdPropertyValue));
201 final Map<String, Object> toscaTemplateYaml = readYamlAsMap(nsd.getContents());
202 final Map<String, Object> topologyTemplate = (Map<String, Object>) toscaTemplateYaml.get("topology_template");
203 assertThat("topology_template should not be empty", topologyTemplate, is(not(anEmptyMap())));
204 final Map<String, Object> substitutionMappings = (Map<String, Object>) topologyTemplate
205 .get("substitution_mappings");
206 assertThat("substitution_mappings should not be empty", substitutionMappings, is(not(anEmptyMap())));
207 assertThat("substitution_mappings->node_type should not be null", substitutionMappings.get("node_type"), is(notNullValue()));
208 assertThat("substitution_mappings->node_type should be as expected", substitutionMappings.get("node_type"), is(nsNodeTypeName));
209 final Map<String, List<String>> subMappingRequirements = (Map<String, List<String>>) substitutionMappings.get("requirements");
210 assertThat(subMappingRequirements.get("VNF1" + DOT + VIRTUAL_LINK_REQUIREMENT_NAME).get(0), is("VNF1"));
211 assertThat(subMappingRequirements.get("VNF1" + DOT + VIRTUAL_LINK_REQUIREMENT_NAME).get(1), is(VIRTUAL_LINK_REQUIREMENT_NAME));
212 assertEquals(1, subMappingRequirements.size());
213 final Map<String, List<String>> subMappingCapabilities = (Map<String, List<String>>) substitutionMappings.get("capabilities");
214 assertNull(subMappingCapabilities);
216 final Map<String, Object> topologyInputs = (Map<String, Object>) topologyTemplate.get("inputs");
217 assertTrue(topologyInputs.containsKey("other_property"));
218 assertEquals(1, topologyInputs.size());
220 final Map<String, Object> nodeTemplates = (Map<String, Object>) ((Map<String, Object>) topologyTemplate.get("node_templates"));
221 final Map<String, Object> nodeTemplateVnfd = (Map<String, Object>) ((Map<String, Object>) nodeTemplates.get(VNFD_AMF_NODE_NAME));
222 final Map<String, Object> nodeTemplateProperties = (Map<String, Object>) ((Map<String, Object>) nodeTemplateVnfd.get("properties"));
223 assertTrue(nodeTemplateProperties.containsKey("will_not_be_excluded"));
225 final Map<String, Object> nodeType = (Map<String, Object>) ((Map<String, Object>) toscaTemplateYaml.get("node_types")).get(nsNodeTypeName);
226 assertTrue(((List<Map<String, Map>>)nodeType.get("requirements")).get(0).containsKey("VNF1" + DOT + VIRTUAL_LINK_REQUIREMENT_NAME));
227 assertFalse(((List<Map<String, Map>>)nodeType.get("requirements")).get(0).containsKey("VNF1" + DOT + VIRTUAL_BINDING_REQUIREMENT_NAME));
229 assertEquals(5, ((Map<String, Map>)nodeType.get("properties")).size());
230 for (final Entry<String, Map> property: ((Map<String, Map>)nodeType.get("properties")).entrySet()) {
231 if (property.getKey().equals("other_property")) {
232 assertNull(property.getValue().get("constraints"));
234 assertEquals(1, ((List<Map>)property.getValue().get("constraints")).size());
240 private ToscaNodeType createDefaultInterfaceToscaNodeType(final String designerPropertyValue, final String versionPropertyValue,
241 final String namePropertyValue, final String invariantIdPropertyValue, String otherPropertyValue) {
242 final ToscaNodeType interfaceToscaNodeType = new ToscaNodeType();
243 final Map<String, ToscaProperty> propertyMap = new HashMap<>();
244 propertyMap.put("designer", createToscaProperty(designerPropertyValue));
245 propertyMap.put("version", createToscaProperty(versionPropertyValue));
246 propertyMap.put("name", createToscaProperty(namePropertyValue));
247 propertyMap.put("invariant_id", createToscaProperty(invariantIdPropertyValue));
248 propertyMap.put("other_property", createToscaProperty(otherPropertyValue));
249 interfaceToscaNodeType.setProperties(propertyMap);
250 return interfaceToscaNodeType;
253 private void assertNotEmpty(Nsd nsd) {
254 assertThat("Nsd should not be null", nsd, is(notNullValue()));
255 assertThat("Nsd content should not be empty", nsd.getContents(), is(notNullValue()));
256 assertThat("Nsd content should not be empty", nsd.getContents().length, is(greaterThan(0)));
259 private ToscaProperty createToscaProperty(final String value) {
260 final ToscaProperty toscaProperty = new ToscaProperty();
261 toscaProperty.setDefaultp(value);
262 return toscaProperty;
265 @SuppressWarnings("unchecked")
266 private Map<String, Object> readYamlAsMap(final byte[] yamlContents) throws IOException {
267 final Yaml yaml = new Yaml();
268 try (final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(yamlContents)) {
269 return (Map<String, Object>) yaml.load(byteArrayInputStream);