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