Create plugin point for csar generation
[sdc.git] / catalog-be-plugins / etsi-nfv-nsd-csar-plugin / src / test / java / org / openecomp / sdc / be / plugins / etsi / nfv / nsd / generator / NsDescriptorGeneratorImplTest.java
1 /*
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
8  *
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.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19
20 package org.openecomp.sdc.be.plugins.etsi.nfv.nsd.generator;
21
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;
37
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;
46 import java.util.Map;
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;
74
75 class NsDescriptorGeneratorImplTest {
76
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<>() {
83         @Override
84         public ToscaTemplateYamlGenerator getObject(Object... args) {
85             return new ToscaTemplateYamlGenerator((ToscaTemplate) args[0]);
86         }
87
88         @Override
89         public ToscaTemplateYamlGenerator getIfAvailable() {
90             return null;
91         }
92
93         @Override
94         public ToscaTemplateYamlGenerator getIfUnique() {
95             return null;
96         }
97
98         @Override
99         public ToscaTemplateYamlGenerator getObject() {
100             return null;
101         }
102     };
103     @Mock
104     private ToscaExportHandler toscaExportHandler;
105     private NsDescriptorGeneratorImpl nsDescriptorGenerator;
106
107     @BeforeEach
108     void setUp() {
109         setUpConfigurationMock();
110         MockitoAnnotations.openMocks(this);
111         nsDescriptorGenerator = new NsDescriptorGeneratorImpl(toscaExportHandler, toscaTemplateYamlGeneratorProvider);
112     }
113
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);
128     }
129
130     @Test
131     @SuppressWarnings("unchecked")
132     void testGenerate() throws IOException, NsdException {
133         //given
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);
163         
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, false)).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);
193         //when
194         final Nsd nsd = nsDescriptorGenerator.generate(component, vnfDescriptorList).orElse(null);
195         //then
196         assertNotEmpty(nsd);
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);
215         
216         final Map<String, Object> topologyInputs = (Map<String, Object>) topologyTemplate.get("inputs");
217         assertTrue(topologyInputs.containsKey("other_property"));
218         assertEquals(1, topologyInputs.size());
219         
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"));
224
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));
228         
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"));
233             } else {
234                 assertEquals(1, ((List<Map>)property.getValue().get("constraints")).size());
235             }
236         }
237
238     }
239
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;
251     }
252
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)));
257     }
258
259     private ToscaProperty createToscaProperty(final String value) {
260         final ToscaProperty toscaProperty = new ToscaProperty();
261         toscaProperty.setDefaultp(value);
262         return toscaProperty;
263     }
264
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);
270         }
271     }
272 }