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.mockito.ArgumentMatchers.any;
30 import static org.mockito.ArgumentMatchers.anyBoolean;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.when;
34 import com.google.common.collect.ImmutableList;
35 import com.google.common.collect.ImmutableMap;
36 import fj.data.Either;
37 import java.io.ByteArrayInputStream;
38 import java.io.IOException;
39 import java.util.ArrayList;
40 import java.util.HashMap;
41 import java.util.List;
43 import org.junit.jupiter.api.BeforeEach;
44 import org.junit.jupiter.api.Test;
45 import org.mockito.Mock;
46 import org.mockito.MockitoAnnotations;
47 import org.openecomp.sdc.be.config.Configuration;
48 import org.openecomp.sdc.be.config.ConfigurationManager;
49 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
50 import org.openecomp.sdc.be.model.Component;
51 import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.exception.NsdException;
52 import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.model.Nsd;
53 import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.model.VnfDescriptor;
54 import org.openecomp.sdc.be.plugins.etsi.nfv.nsd.tosca.yaml.ToscaTemplateYamlGenerator;
55 import org.openecomp.sdc.be.tosca.ToscaExportHandler;
56 import org.openecomp.sdc.be.tosca.model.SubstitutionMapping;
57 import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate;
58 import org.openecomp.sdc.be.tosca.model.ToscaNodeType;
59 import org.openecomp.sdc.be.tosca.model.ToscaProperty;
60 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraint;
61 import org.openecomp.sdc.be.tosca.model.ToscaPropertyConstraintValidValues;
62 import org.openecomp.sdc.be.tosca.model.ToscaTemplate;
63 import org.openecomp.sdc.be.tosca.model.ToscaTemplateCapability;
64 import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate;
65 import org.openecomp.sdc.common.api.ConfigurationSource;
66 import org.springframework.beans.factory.ObjectProvider;
67 import org.yaml.snakeyaml.Yaml;
69 class NsDescriptorGeneratorImplTest {
71 private static final String VNFD_AMF_NODE_NAME = "vnfd_amf";
72 private static final String VIRTUAL_LINK_REQUIREMENT_NAME = "virtual_link";
75 private ToscaExportHandler toscaExportHandler;
77 private final ObjectProvider<ToscaTemplateYamlGenerator> toscaTemplateYamlGeneratorProvider = new ObjectProvider<>() {
79 public ToscaTemplateYamlGenerator getObject(Object... args) {
80 return new ToscaTemplateYamlGenerator((ToscaTemplate) args[0]);
84 public ToscaTemplateYamlGenerator getIfAvailable() {
89 public ToscaTemplateYamlGenerator getIfUnique() {
94 public ToscaTemplateYamlGenerator getObject() {
99 private NsDescriptorGeneratorImpl nsDescriptorGenerator;
103 setUpConfigurationMock();
104 MockitoAnnotations.initMocks(this);
105 nsDescriptorGenerator = new NsDescriptorGeneratorImpl(toscaExportHandler, toscaTemplateYamlGeneratorProvider);
108 private void setUpConfigurationMock() {
109 final List<Map<String, Map<String, String>>> defaultImports = new ArrayList<>();
110 final Map<String, Map<String, String>> importMap = new HashMap<>();
111 final Map<String, String> nodeImportEntry = new HashMap<>();
112 nodeImportEntry.put("file", "nodes.yml");
113 importMap.put("nodes", nodeImportEntry);
114 defaultImports.add(importMap);
116 final ConfigurationSource configurationSource = mock(ConfigurationSource.class);
117 final Configuration configuration = new Configuration();
118 configuration.setDefaultImports(defaultImports);
119 configuration.setHeatEnvArtifactHeader("");
120 configuration.setHeatEnvArtifactFooter("");
121 when(configurationSource.getAndWatchConfiguration(any(), any())).thenReturn(configuration);
122 new ConfigurationManager(configurationSource);
126 void testGenerate() throws IOException, NsdException {
128 final Component component = mock(Component.class);
129 when(component.getComponentType()).thenReturn(ComponentTypeEnum.SERVICE);
130 final ToscaTemplate componentToscaTemplate = new ToscaTemplate("");
131 final ToscaTopolgyTemplate componentToscaTopologyTemplate = new ToscaTopolgyTemplate();
132 componentToscaTemplate.setTopology_template(componentToscaTopologyTemplate);
134 final HashMap<String, ToscaNodeTemplate> nodeTemplateMap = new HashMap<>();
135 final ToscaNodeTemplate vnfAmfNodeTemplate = new ToscaNodeTemplate();
136 vnfAmfNodeTemplate.setType("com.ericsson.resource.abstract.Ericsson.AMF");
137 //a property to be excluded
138 vnfAmfNodeTemplate.setProperties(ImmutableMap.of("nf_naming_code", new ToscaProperty()));
139 //a property that wont be excluded
140 vnfAmfNodeTemplate.setProperties(ImmutableMap.of("will_not_be_excluded", new ToscaProperty()));
141 nodeTemplateMap.put(VNFD_AMF_NODE_NAME, vnfAmfNodeTemplate);
143 final Map<String, ToscaTemplateCapability> vnfAmfCapabilities = new HashMap<>();
144 vnfAmfCapabilities.put("myCapability", new ToscaTemplateCapability());
145 vnfAmfNodeTemplate.setCapabilities(vnfAmfCapabilities);
146 componentToscaTopologyTemplate.setNode_templates(nodeTemplateMap);
148 final SubstitutionMapping substitutionMapping = mock(SubstitutionMapping.class);
149 Map<String, String[]> requirements = new HashMap<>();
150 String[] requirementAssignment = {"VNF1", VIRTUAL_LINK_REQUIREMENT_NAME};
151 requirements.put(VIRTUAL_LINK_REQUIREMENT_NAME, requirementAssignment);
152 when(substitutionMapping.getRequirements()).thenReturn(requirements);
153 Map<String, String[]> capabilities = new HashMap<>();
154 String[] capabilitiesAssignment = {"VNF1", "capability1"};
155 capabilities.put("capability", capabilitiesAssignment);
156 when(substitutionMapping.getCapabilities()).thenReturn(capabilities);
157 componentToscaTopologyTemplate.setSubstitution_mappings(substitutionMapping);
159 final ToscaTemplate componentInterfaceToscaTemplate = new ToscaTemplate("");
160 final String designerPropertyValue = "designerValue";
161 final String versionPropertyValue = "versionValue";
162 final String namePropertyValue = "nameValue";
163 final String invariantIdPropertyValue = "invariantIdValue";
164 final ToscaNodeType interfaceToscaNodeType = createDefaultInterfaceToscaNodeType(designerPropertyValue,
165 versionPropertyValue, namePropertyValue, invariantIdPropertyValue);
166 final String nsNodeTypeName = "nsNodeTypeName";
167 componentInterfaceToscaTemplate.setNode_types(ImmutableMap.of(nsNodeTypeName, interfaceToscaNodeType));
170 when(toscaExportHandler.convertToToscaTemplate(component)).thenReturn(Either.left(componentToscaTemplate));
171 when(toscaExportHandler.convertInterfaceNodeType(any(), any(), any(), any(), anyBoolean()))
172 .thenReturn(Either.left(componentInterfaceToscaTemplate));
174 final List<VnfDescriptor> vnfDescriptorList = new ArrayList<>();
175 VnfDescriptor vnfDescriptor1 = new VnfDescriptor();
176 vnfDescriptor1.setName(VNFD_AMF_NODE_NAME);
177 vnfDescriptor1.setVnfdFileName("vnfd_amf.yaml");
178 vnfDescriptor1.setNodeType("com.ericsson.resource.abstract.Ericsson.AMF");
180 vnfDescriptorList.add(vnfDescriptor1);
183 final Nsd nsd = nsDescriptorGenerator.generate(component, vnfDescriptorList).orElse(null);
186 assertThat("Nsd designer should be as expected", nsd.getDesigner(), is(designerPropertyValue));
187 assertThat("Nsd version should be as expected", nsd.getVersion(), is(versionPropertyValue));
188 assertThat("Nsd name should be as expected", nsd.getName(), is(namePropertyValue));
189 assertThat("Nsd invariantId should be as expected", nsd.getInvariantId(), is(invariantIdPropertyValue));
191 final Map<String, Object> toscaTemplateYaml = readYamlAsMap(nsd.getContents());
192 @SuppressWarnings("unchecked")
193 final Map<String, Object> topologyTemplate = (Map<String, Object>) toscaTemplateYaml.get("topology_template");
194 assertThat("topology_template should not be empty", topologyTemplate, is(not(anEmptyMap())));
195 @SuppressWarnings("unchecked")
196 final Map<String, Object> substitutionMappings =
197 (Map<String, Object>) topologyTemplate.get("substitution_mappings");
198 assertThat("substitution_mappings should not be empty", substitutionMappings, is(not(anEmptyMap())));
199 assertThat("substitution_mappings->node_type should not be null",
200 substitutionMappings.get("node_type"), is(notNullValue()));
201 assertThat("substitution_mappings->node_type should be as expected",
202 substitutionMappings.get("node_type"), is(nsNodeTypeName));
204 final Map<String, List<String>> subMappingRequirements = (Map<String, List<String>>) substitutionMappings.get("requirements");
205 assertThat(subMappingRequirements.get(VIRTUAL_LINK_REQUIREMENT_NAME).get(0), is("VNF1"));
206 assertThat(subMappingRequirements.get(VIRTUAL_LINK_REQUIREMENT_NAME).get(1), is(VIRTUAL_LINK_REQUIREMENT_NAME));
207 final Map<String, List<String>> subMappingCapabilities = (Map<String, List<String>>) substitutionMappings.get("capabilities");
208 assertThat(subMappingCapabilities.get("capability").get(0), is("VNF1"));
209 assertThat(subMappingCapabilities.get("capability").get(1), is("capability1"));
211 @SuppressWarnings("unchecked")
212 final Map<String, Object> nodeTemplates =
213 (Map<String, Object>) topologyTemplate.get("node_templates");
214 @SuppressWarnings("unchecked")
215 final Map<String, Object> nodeTemplate =
216 (Map<String, Object>) nodeTemplates.get(VNFD_AMF_NODE_NAME);
217 assertThat("capabilities should be null",
218 nodeTemplate.get("capabilities"), is(nullValue()));
221 private ToscaNodeType createDefaultInterfaceToscaNodeType(final String designerPropertyValue,
222 final String versionPropertyValue,
223 final String namePropertyValue,
224 final String invariantIdPropertyValue) {
225 final ToscaNodeType interfaceToscaNodeType = new ToscaNodeType();
226 interfaceToscaNodeType.setProperties(
227 ImmutableMap.of("designer", createToscaProperty(designerPropertyValue),
228 "version", createToscaProperty(versionPropertyValue),
229 "name", createToscaProperty(namePropertyValue),
230 "invariant_id", createToscaProperty(invariantIdPropertyValue))
232 return interfaceToscaNodeType;
235 private void assertNotEmpty(Nsd nsd) {
236 assertThat("Nsd should not be null", nsd, is(notNullValue()));
237 assertThat("Nsd content should not be empty", nsd.getContents(), is(notNullValue()));
238 assertThat("Nsd content should not be empty", nsd.getContents().length, is(greaterThan(0)));
241 private ToscaProperty createToscaProperty(final String value) {
242 final ToscaProperty toscaProperty = new ToscaProperty();
243 final ToscaPropertyConstraint toscaPropertyConstraint =
244 new ToscaPropertyConstraintValidValues(ImmutableList.of(value));
245 toscaProperty.setConstraints(ImmutableList.of(toscaPropertyConstraint));
246 return toscaProperty;
249 @SuppressWarnings("unchecked")
250 private Map<String, Object> readYamlAsMap(final byte[] yamlContents) throws IOException {
251 final Yaml yaml = new Yaml();
252 try (final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(yamlContents)) {
253 return (Map<String, Object>) yaml.load(byteArrayInputStream);