Rename packages from openecomp to onap.
[sdc.git] / openecomp-be / lib / openecomp-sdc-tosca-generator-lib / openecomp-sdc-tosca-generator-core / src / main / java / org / openecomp / sdc / generator / core / services / ManualVspToscaGenerationService.java
1 /*
2  * Copyright © 2016-2017 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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
17 package org.openecomp.sdc.generator.core.services;
18
19 import org.apache.commons.collections4.CollectionUtils;
20 import org.apache.commons.collections4.MapUtils;
21 import org.openecomp.sdc.generator.core.utils.GeneratorUtils;
22 import org.openecomp.sdc.generator.datatypes.tosca.MultiFlavorVfcImage;
23 import org.openecomp.sdc.generator.datatypes.tosca.VspModelInfo;
24 import org.openecomp.sdc.generator.util.GeneratorConstants;
25 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
26 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
27 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
28 import org.onap.sdc.tosca.datatypes.model.Import;
29 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
30 import org.onap.sdc.tosca.datatypes.model.NodeType;
31 import org.onap.sdc.tosca.datatypes.model.PropertyDefinition;
32 import org.onap.sdc.tosca.datatypes.model.PropertyType;
33 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
34 import org.onap.sdc.tosca.datatypes.model.TopologyTemplate;
35 import org.openecomp.sdc.tosca.services.DataModelUtil;
36 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
37 import org.openecomp.sdc.tosca.services.ToscaConstants;
38 import org.openecomp.sdc.tosca.services.ToscaUtil;
39 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
40 import org.openecomp.sdc.translator.services.heattotosca.Constants;
41 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
42 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.NetworkType;
43 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.Nic;
44
45 import java.util.ArrayList;
46 import java.util.HashMap;
47 import java.util.LinkedHashMap;
48 import java.util.List;
49 import java.util.Map;
50 import java.util.Objects;
51 import java.util.Optional;
52
53 /**
54  * The type Manual vsp tosca generator.
55  */
56 public class ManualVspToscaGenerationService {
57
58   //Map of the abstract node template id and substitution node type
59   private Map<String, String> abstractSubstitutionIdTypes = new HashMap<>();
60   //Map of service template name and service template for the generated service templates
61   private Map<String, ServiceTemplate> generatedServiceTemplates = new HashMap<>();
62
63
64   /**
65    * Create manual vsp tosca service model tosca service model.
66    *
67    * @param vspModelInfo the vsp model info
68    * @return the tosca service model
69    */
70   public ToscaServiceModel createManualVspToscaServiceModel(VspModelInfo vspModelInfo) {
71     ToscaServiceModel toscaServiceModel = new ToscaServiceModel();
72     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
73     Map<String, ServiceTemplate> serviceTemplates = new HashMap<>(GlobalTypesGenerator
74         .getGlobalTypesServiceTemplate(OnboardingTypesEnum.MANUAL));
75     toscaServiceModel.setServiceTemplates(serviceTemplates);
76     toscaServiceModel.setEntryDefinitionServiceTemplate(Constants.MAIN_TEMPLATE_NAME
77         + GeneratorConstants.TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX);
78     createToscaFromVspData(vspModelInfo, toscaServiceModel);
79     for (Map.Entry<String, ServiceTemplate> serviceTemplateEntry :
80         generatedServiceTemplates.entrySet()) {
81       ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplateEntry
82           .getValue());
83     }
84     return toscaServiceModel;
85   }
86
87   private void createToscaFromVspData(VspModelInfo vspModelInfo,
88                                         ToscaServiceModel toscaServiceModel) {
89     List<ServiceTemplate> serviceTemplates = new ArrayList<>();
90     //Only one component supported
91     Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
92     if (componentName.isPresent()) {
93       //Create main service template
94       ServiceTemplate mainServiceTemplate = createMainServiceTemplate(vspModelInfo);
95       generatedServiceTemplates.put(Constants.MAIN_TEMPLATE_NAME, mainServiceTemplate);
96       //Create substitution service template
97       for (Map.Entry<String, String> entry : abstractSubstitutionIdTypes.entrySet()) {
98         ServiceTemplate substitutionServiceTemplate =
99             createSubstitutionServiceTemplate(componentName.get(), entry.getValue(), vspModelInfo,
100                 toscaServiceModel);
101         generatedServiceTemplates.put(componentName.get(), substitutionServiceTemplate);
102       }
103     }
104
105   }
106
107   private Optional<String> getComponentNameFromVspModel(VspModelInfo vspModelInfo) {
108     String componentName = null;
109     if (MapUtils.isNotEmpty(vspModelInfo.getComponents())) {
110       //supported for single component only
111       componentName = vspModelInfo.getComponents().entrySet().iterator().next().getValue();
112     }
113     return Optional.ofNullable(componentName);
114   }
115
116   private ServiceTemplate createMainServiceTemplate(VspModelInfo vspModelInfo) {
117     ServiceTemplate mainServiceTemplate = createInitMainServiceTemplate(vspModelInfo
118         .getReleaseVendor());
119     Map<String, String> components = vspModelInfo.getComponents();
120     if (MapUtils.isNotEmpty(components)) {
121       //Currently since only one component is supported we can fetch the component in this manner.
122       // May be need to revisited for supporting multiple components
123       String componentId = components.entrySet().iterator().next().getKey();
124       createVnfConfigurationNodeTemplate(mainServiceTemplate, vspModelInfo);
125       createVnfNodeTemplate(mainServiceTemplate, vspModelInfo, componentId);
126     }
127     return mainServiceTemplate;
128   }
129
130   private void createVnfConfigurationNodeTemplate(ServiceTemplate mainServiceTemplate,
131                                                   VspModelInfo vspModelInfo) {
132     Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
133     if (componentName.isPresent()) {
134       NodeTemplate vnfConfigurationNodeTemplate = new NodeTemplate();
135       vnfConfigurationNodeTemplate.setType(ToscaNodeType.VNF_CONFIG_NODE_TYPE);
136       if (Objects.nonNull(vspModelInfo.getAllowedFlavors())) {
137         Map<String, Object> properties = new LinkedHashMap<>();
138         properties.put(GeneratorConstants.ALLOWED_FLAVORS_PROPERTY, vspModelInfo.getAllowedFlavors());
139         vnfConfigurationNodeTemplate.setProperties(properties);
140       }
141       String nodeTemplateId = componentName.get() + GeneratorConstants.VNF_CONFIG_NODE_TEMPLATE_ID_SUFFIX;
142       DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
143           vnfConfigurationNodeTemplate);
144     }
145   }
146
147   private void createVnfNodeTemplate(ServiceTemplate mainServiceTemplate,
148                                      VspModelInfo vspModelInfo, String componentId) {
149     Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
150     if (componentName.isPresent()) {
151       NodeTemplate vnfNodeTemplate = new NodeTemplate();
152       vnfNodeTemplate.setType(ToscaNodeType.MULTIDEPLOYMENTFLAVOR_NODE_TYPE);
153       List<String> directiveList = new ArrayList<>();
154       directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
155       vnfNodeTemplate.setDirectives(directiveList);
156       vnfNodeTemplate.setProperties(getVnfNodeTemplateProperties(vspModelInfo, componentId));
157       DataModelUtil
158           .addSubstitutionFilteringProperty(getSubstitutionServiceTemplateFileName(componentName
159                   .get()), vnfNodeTemplate, 1);
160       //Enable below if we need "abstract_" as prefix like we have in Unified model
161       //String nodeTemplateId =
162       // Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX + componentName + "VNF_NODE_TEMPLATE_ID_SUFFIX";
163       String nodeTemplateId = componentName.get() + GeneratorConstants.VNF_NODE_TEMPLATE_ID_SUFFIX;
164       DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
165           vnfNodeTemplate);
166       abstractSubstitutionIdTypes.put(componentName.get(), ToscaNodeType
167           .MULTIDEPLOYMENTFLAVOR_NODE_TYPE);
168     }
169   }
170
171   private Map<String, Object> getVnfNodeTemplateProperties(VspModelInfo vspModelInfo,
172                                                            String componentId) {
173     Map<String, Object> properties = new LinkedHashMap<>();
174     if (MapUtils.isNotEmpty(vspModelInfo.getMultiFlavorVfcImages())) {
175       List<MultiFlavorVfcImage> componentImages =
176           vspModelInfo.getMultiFlavorVfcImages().get(componentId);
177       if (Objects.nonNull(componentImages)) {
178         Map<String, MultiFlavorVfcImage> vfcImages = new HashMap<>();
179         componentImages.stream()
180             .forEach(multiFlavorVfcImage ->
181                 vfcImages.put(multiFlavorVfcImage.getSoftware_version(), multiFlavorVfcImage));
182         properties.put(GeneratorConstants.IMAGES_PROPERTY, vfcImages);
183       }
184     }
185     return properties;
186   }
187
188   private String getSubstitutionServiceTemplateFileName(String componentName) {
189     return componentName + GeneratorConstants.TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX;
190   }
191
192   private String getNodeTemplateId(String componentName, String idPrefix, String idSuffix) {
193     StringBuilder builder = new StringBuilder();
194     //builder.append(idPrefix);
195     builder.append(componentName);
196     builder.append(idSuffix);
197     return builder.toString();
198   }
199
200   private ServiceTemplate createInitMainServiceTemplate(String releaseVendor) {
201     ServiceTemplate mainServiceTemplate = new ServiceTemplate();
202     Map<String, String> templateMetadata = new HashMap<>();
203     templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
204     if (Objects.nonNull(releaseVendor)) {
205       templateMetadata.put(GeneratorConstants.RELEASE_VENDOR, releaseVendor);
206     }
207     mainServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
208     mainServiceTemplate.setMetadata(templateMetadata);
209     mainServiceTemplate.setTopology_template(new TopologyTemplate());
210     mainServiceTemplate.setImports(getImports());
211     return mainServiceTemplate;
212   }
213
214   private List<Map<String, Import>> getImports() {
215     Map<String, Import> globalSubstitutionTypeImportMap = new HashMap<>();
216     Import globalSubstitutionTypeImport = new Import();
217     globalSubstitutionTypeImport.setFile(ToscaUtil.getServiceTemplateFileName(Constants
218         .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
219     globalSubstitutionTypeImportMap.put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
220         globalSubstitutionTypeImport);
221     Map<String, Import> globalImports = new HashMap<>();
222     List<Map<String, Import>> manualVspGlobalTypesImportList = GlobalTypesGenerator
223         .getManualVspGlobalTypesImportList();
224     manualVspGlobalTypesImportList.add(globalSubstitutionTypeImportMap);
225     return manualVspGlobalTypesImportList;
226   }
227
228   private ServiceTemplate createSubstitutionServiceTemplate(String serviceTemplateName,
229                                                             String substitutionNodeTypeId,
230                                                             VspModelInfo vspModelInfo,
231                                                             ToscaServiceModel toscaServiceModel) {
232     ServiceTemplate substitutionServiceTemplate =
233         createInitSubstitutionServiceTemplate(serviceTemplateName);
234     createSubstitutionServiceTemplateComponents(substitutionServiceTemplate, vspModelInfo,
235         toscaServiceModel);
236     createSubstitutionServiceTemplateNics(substitutionServiceTemplate, vspModelInfo,
237         toscaServiceModel);
238     handleSubstitutionMapping(substitutionServiceTemplate, toscaServiceModel,
239         substitutionNodeTypeId, serviceTemplateName);
240     return substitutionServiceTemplate;
241   }
242
243   private void createSubstitutionServiceTemplateComponents(ServiceTemplate
244                                                                substitutionServiceTemplate,
245                                                            VspModelInfo vspModelInfo,
246                                                            ToscaServiceModel toscaServiceModel) {
247     Map<String, String> components = vspModelInfo.getComponents();
248     if (MapUtils.isNotEmpty(components)) {
249       for (String componentId : components.keySet()) {
250         String componentName = components.get(componentId);
251         String localNodeTypeId =
252             createComponentDefinitionNodeTemplate(substitutionServiceTemplate, componentName);
253         createLocalNodeType(substitutionServiceTemplate, localNodeTypeId);
254       }
255     }
256   }
257
258   private void createSubstitutionServiceTemplateNics(ServiceTemplate substitutionServiceTemplate,
259                                                      VspModelInfo vspModelInfo,
260                                                      ToscaServiceModel toscaServiceModel) {
261     Map<String, List<Nic>> nics = vspModelInfo.getNics();
262     if (MapUtils.isNotEmpty(nics)) {
263       for (Map.Entry<String, List<Nic>> entry : nics.entrySet()) {
264         String componentId = entry.getKey();
265         String componentNodeTemplateId = getSubstitutionComponentNodeTemplateId(
266             vspModelInfo.getComponents().get(componentId));
267         List<Nic> nicList = entry.getValue();
268         if (CollectionUtils.isNotEmpty(nicList)) {
269           for (Nic nic : nicList) {
270             NodeTemplate nicNodeTemplate = new NodeTemplate();
271             nicNodeTemplate.setType(ToscaNodeType.NETWORK_PORT);
272             DataModelUtil.addBindingReqFromPortToCompute(componentNodeTemplateId, nicNodeTemplate);
273             DataModelUtil.addNodeTemplate(substitutionServiceTemplate,
274                 getNicNodeTemplateId(nic.getName(), nic.getNetworkType()), nicNodeTemplate);
275           }
276         }
277       }
278     }
279   }
280
281   private String getSubstitutionComponentNodeTemplateId(String componentName) {
282     //TODO: Confirm if anything else is needed here
283     return componentName;
284   }
285
286   private String getNicNodeTemplateId(String nicName, NetworkType nicNetworkType) {
287     StringBuilder builder = new StringBuilder();
288     builder.append(nicName);
289     if (nicNetworkType == NetworkType.External) {
290       builder.append(GeneratorConstants.PORT_TYPE_EXTERNAL_NODE_TEMPLATE_SUFFIX);
291     } else if (nicNetworkType == NetworkType.Internal) {
292       builder.append(GeneratorConstants.PORT_TYPE_INTERNAL_NODE_TEMPLATE_SUFFIX);
293     }
294     builder.append(GeneratorConstants.PORT_NODE_TEMPLATE_ID_SUFFIX);
295     return builder.toString();
296   }
297
298   private String createComponentDefinitionNodeTemplate(ServiceTemplate substitutionServiceTemplate,
299                                                        String componentName) {
300     NodeTemplate nodeTemplate = new NodeTemplate();
301     String localNodeTypeId = getLocalNodeTypeId(componentName);
302     nodeTemplate.setType(localNodeTypeId);
303     DataModelUtil.addNodeTemplate(substitutionServiceTemplate, componentName, nodeTemplate);
304     return localNodeTypeId;
305   }
306
307   private void createLocalNodeType(ServiceTemplate substitutionServiceTemplate,
308                                    String localNodeTypeId) {
309     NodeType localNodeType = new NodeType();
310     localNodeType.setDerived_from(ToscaNodeType.COMPUTE);
311     DataModelUtil.addNodeType(substitutionServiceTemplate, localNodeTypeId, localNodeType );
312   }
313
314   private String getLocalNodeTypeId(String componentName) {
315     return ToscaNodeType.VFC_NODE_TYPE_PREFIX + componentName;
316   }
317
318   private ServiceTemplate createInitSubstitutionServiceTemplate(String serviceTemplateName) {
319     ServiceTemplate substitutionServiceTemplate = new ServiceTemplate();
320     Map<String, String> templateMetadata = new HashMap<>();
321     substitutionServiceTemplate.setTosca_definitions_version(ToscaConstants
322         .TOSCA_DEFINITIONS_VERSION);
323     templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, serviceTemplateName);
324     substitutionServiceTemplate.setMetadata(templateMetadata);
325     substitutionServiceTemplate.setTopology_template(new TopologyTemplate());
326     substitutionServiceTemplate.setImports(getImports());
327     return substitutionServiceTemplate;
328   }
329
330   private void handleSubstitutionMapping(ServiceTemplate substitutionServiceTemplate,
331                                          ToscaServiceModel toscaServiceModel,
332                                          String substitutionNodeTypeId,
333                                          String componentName) {
334     ServiceTemplate globalSubstitutionServiceTemplate = fetchGlobalSubstitutionServiceTemplate();
335     NodeType substitutionNodeType =
336         createGlobalSubstitutionNodeType(substitutionServiceTemplate, componentName);
337     DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId,
338         substitutionNodeType);
339     Map<String, Map<String, List<String>>> substitutionMapping =
340         GeneratorUtils.getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType,
341             substitutionServiceTemplate, toscaServiceModel);
342     if (Objects.nonNull(substitutionMapping)) {
343       //add substitution mapping after capability and requirement expose calculation
344       substitutionServiceTemplate.getTopology_template().setSubstitution_mappings(
345           DataModelUtil.createSubstitutionTemplateSubMapping(substitutionNodeTypeId,
346               substitutionNodeType, substitutionMapping));
347     }
348   }
349
350   //*************** CREATE GLOBAL SUBSTITUTION SERVICE TEMPLATE **********************
351
352   private ServiceTemplate createGlobalSubstitutionServiceTemplate(ServiceTemplate
353                                                                       substitutionServiceTemplate,
354                                                                   String componentName) {
355     ServiceTemplate globalSubstitutionServiceTemplate = fetchGlobalSubstitutionServiceTemplate();
356     NodeType substitutionNodeType =
357         createGlobalSubstitutionNodeType(substitutionServiceTemplate, componentName);
358     String substitutionNodeTypeId = getSubstitutionNodeTypeId(componentName);
359     DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId,
360         substitutionNodeType);
361     return globalSubstitutionServiceTemplate;
362   }
363
364   private ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
365     ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
366     Map<String, String> templateMetadata = new HashMap<>();
367     globalSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants
368         .TOSCA_DEFINITIONS_VERSION);
369     templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME,
370         Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
371     globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
372     globalSubstitutionServiceTemplate.setImports(getImports());
373     return globalSubstitutionServiceTemplate;
374   }
375
376   private NodeType createGlobalSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
377                                                 String componentName) {
378     NodeType substitutionNodeType = new ToscaAnalyzerServiceImpl()
379         .createInitSubstitutionNodeType(substitutionServiceTemplate,
380             ToscaNodeType.MULTIFLAVOR_VFC_NODE_TYPE);
381     substitutionNodeType.setProperties(
382         getManualVspSubstitutionNodeTypeProperties(substitutionNodeType, componentName));
383     return substitutionNodeType;
384   }
385
386   private Map<String, PropertyDefinition> getManualVspSubstitutionNodeTypeProperties(
387       NodeType substitutionNodeType, String componentName) {
388     //Create num_cpus property
389     PropertyDefinition numCpus = new PropertyDefinition();
390     numCpus.setType(PropertyType.INTEGER.getDisplayName());
391     numCpus.setDescription(GeneratorConstants.NUM_CPUS_PROP_DESC_PREFIX + componentName);
392     numCpus.setRequired(true);
393     //Create disk_size property
394     PropertyDefinition diskSize = new PropertyDefinition();
395     diskSize.setType(PropertyType.SCALAR_UNIT_SIZE.getDisplayName());
396     diskSize.setDescription(GeneratorConstants.DISK_SIZE_PROP_DESC_PREFIX + componentName);
397     diskSize.setRequired(true);
398     //Create mem_size property
399     PropertyDefinition memSize = new PropertyDefinition();
400     memSize.setType(PropertyType.SCALAR_UNIT_SIZE.getDisplayName());
401     memSize.setDescription(GeneratorConstants.MEM_SIZE_PROP_DESC_PREFIX + componentName);
402     memSize.setRequired(true);
403
404     Map<String, PropertyDefinition> manualVspProperties = new LinkedHashMap<>();
405     manualVspProperties.put(GeneratorConstants.NUM_CPUS, numCpus);
406     manualVspProperties.put(GeneratorConstants.DISK_SIZE, diskSize);
407     manualVspProperties.put(GeneratorConstants.MEM_SIZE, memSize);
408
409     return manualVspProperties;
410   }
411
412   private String getSubstitutionNodeTypeId(String componentName) {
413     return ToscaNodeType.MULTIDEPLOYMENTFLAVOR_NODE_TYPE + "." + componentName;
414   }
415
416   /**
417    * Fetch global substitution service template service template.
418    *
419    * @return the global substitution service template
420    */
421   private ServiceTemplate fetchGlobalSubstitutionServiceTemplate() {
422     ServiceTemplate globalSubstitutionServiceTemplate =
423         generatedServiceTemplates.get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
424     if (Objects.isNull(globalSubstitutionServiceTemplate)) {
425       globalSubstitutionServiceTemplate = createInitGlobalSubstitutionServiceTemplate();
426       generatedServiceTemplates.put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
427               globalSubstitutionServiceTemplate);
428     }
429     return globalSubstitutionServiceTemplate;
430   }
431 }