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