1 package org.openecomp.sdc.generator.core.services;
3 import org.apache.commons.collections4.CollectionUtils;
4 import org.apache.commons.collections4.MapUtils;
5 import org.openecomp.sdc.generator.core.utils.GeneratorUtils;
6 import org.openecomp.sdc.generator.datatypes.tosca.MultiFlavorVfcImage;
7 import org.openecomp.sdc.generator.datatypes.tosca.VspModelInfo;
8 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
9 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
10 import org.openecomp.sdc.tosca.datatypes.model.Import;
11 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
12 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
13 import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition;
14 import org.openecomp.sdc.tosca.datatypes.model.PropertyType;
15 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
16 import org.openecomp.sdc.tosca.datatypes.model.TopologyTemplate;
17 import org.openecomp.sdc.tosca.services.DataModelUtil;
18 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
19 import org.openecomp.sdc.tosca.services.ToscaConstants;
20 import org.openecomp.sdc.tosca.services.ToscaUtil;
21 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
22 import org.openecomp.sdc.translator.services.heattotosca.Constants;
23 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
24 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.NetworkType;
25 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.Nic;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.LinkedHashMap;
30 import java.util.List;
32 import java.util.Objects;
33 import java.util.Optional;
35 import static org.openecomp.sdc.generator.util.GeneratorConstants.ALLOWED_FLAVORS_PROPERTY;
36 import static org.openecomp.sdc.generator.util.GeneratorConstants.DISK_SIZE;
37 import static org.openecomp.sdc.generator.util.GeneratorConstants.DISK_SIZE_PROP_DESC_PREFIX;
38 import static org.openecomp.sdc.generator.util.GeneratorConstants.IMAGES_PROPERTY;
39 import static org.openecomp.sdc.generator.util.GeneratorConstants.MEM_SIZE;
40 import static org.openecomp.sdc.generator.util.GeneratorConstants.MEM_SIZE_PROP_DESC_PREFIX;
41 import static org.openecomp.sdc.generator.util.GeneratorConstants.NUM_CPUS;
42 import static org.openecomp.sdc.generator.util.GeneratorConstants.NUM_CPUS_PROP_DESC_PREFIX;
43 import static org.openecomp.sdc.generator.util.GeneratorConstants.PORT_NODE_TEMPLATE_ID_SUFFIX;
44 import static org.openecomp.sdc.generator.util.GeneratorConstants.PORT_TYPE_EXTERNAL_NODE_TEMPLATE_SUFFIX;
45 import static org.openecomp.sdc.generator.util.GeneratorConstants.PORT_TYPE_INTERNAL_NODE_TEMPLATE_SUFFIX;
46 import static org.openecomp.sdc.generator.util.GeneratorConstants.RELEASE_VENDOR;
47 import static org.openecomp.sdc.generator.util.GeneratorConstants.TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX;
48 import static org.openecomp.sdc.generator.util.GeneratorConstants.VNF_CONFIG_NODE_TEMPLATE_ID_SUFFIX;
49 import static org.openecomp.sdc.generator.util.GeneratorConstants.VNF_NODE_TEMPLATE_ID_SUFFIX;
52 * The type Manual vsp tosca generator.
54 public class ManualVspToscaGenerationService {
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<>();
63 * Create manual vsp tosca service model tosca service model.
65 * @param vspModelInfo the vsp model info
66 * @return the tosca service model
68 public ToscaServiceModel createManualVspToscaServiceModel(VspModelInfo vspModelInfo) {
69 ToscaServiceModel toscaServiceModel = new ToscaServiceModel();
70 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
71 Map<String, ServiceTemplate> serviceTemplates = new HashMap<>(GlobalTypesGenerator
72 .getGlobalTypesServiceTemplate());
73 toscaServiceModel.setServiceTemplates(serviceTemplates);
74 toscaServiceModel.setEntryDefinitionServiceTemplate(Constants.MAIN_TEMPLATE_NAME
75 + TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX);
76 createToscaFromVspData(vspModelInfo, toscaServiceModel);
77 for (Map.Entry<String, ServiceTemplate> serviceTemplateEntry :
78 generatedServiceTemplates.entrySet()) {
79 ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplateEntry
82 return toscaServiceModel;
85 private void createToscaFromVspData(VspModelInfo vspModelInfo,
86 ToscaServiceModel toscaServiceModel) {
87 List<ServiceTemplate> serviceTemplates = new ArrayList<>();
88 //Only one component supported
89 Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
90 if (componentName.isPresent()) {
91 //Create main service template
92 ServiceTemplate mainServiceTemplate = createMainServiceTemplate(vspModelInfo);
93 generatedServiceTemplates.put(Constants.MAIN_TEMPLATE_NAME, mainServiceTemplate);
94 //Create substitution service template
95 for (Map.Entry<String, String> entry : abstractSubstitutionIdTypes.entrySet()) {
96 ServiceTemplate substitutionServiceTemplate =
97 createSubstitutionServiceTemplate(componentName.get(), entry.getValue(), vspModelInfo,
99 generatedServiceTemplates.put(componentName.get(), substitutionServiceTemplate);
105 private Optional<String> getComponentNameFromVspModel(VspModelInfo vspModelInfo) {
106 String componentName = null;
107 if (MapUtils.isNotEmpty(vspModelInfo.getComponents())) {
108 //supported for single component only
109 componentName = vspModelInfo.getComponents().entrySet().iterator().next().getValue();
111 return Optional.ofNullable(componentName);
114 private ServiceTemplate createMainServiceTemplate(VspModelInfo vspModelInfo) {
115 ServiceTemplate mainServiceTemplate = createInitMainServiceTemplate(vspModelInfo
116 .getReleaseVendor());
117 Map<String, String> components = vspModelInfo.getComponents();
118 if (MapUtils.isNotEmpty(components)) {
119 //Currently since only one component is supported we can fetch the component in this manner.
120 // May be need to revisited for supporting multiple components
121 String componentId = components.entrySet().iterator().next().getKey();
122 createVnfConfigurationNodeTemplate(mainServiceTemplate, vspModelInfo);
123 createVnfNodeTemplate(mainServiceTemplate, vspModelInfo, componentId);
125 return mainServiceTemplate;
128 private void createVnfConfigurationNodeTemplate(ServiceTemplate mainServiceTemplate,
129 VspModelInfo vspModelInfo) {
130 Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
131 if (componentName.isPresent()) {
132 NodeTemplate vnfConfigurationNodeTemplate = new NodeTemplate();
133 vnfConfigurationNodeTemplate.setType(ToscaNodeType.VNF_CONFIG_NODE_TYPE);
134 if (Objects.nonNull(vspModelInfo.getAllowedFlavors())) {
135 Map<String, Object> properties = new LinkedHashMap<>();
136 properties.put(ALLOWED_FLAVORS_PROPERTY, vspModelInfo.getAllowedFlavors());
137 vnfConfigurationNodeTemplate.setProperties(properties);
139 String nodeTemplateId = componentName.get() + VNF_CONFIG_NODE_TEMPLATE_ID_SUFFIX;
140 DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
141 vnfConfigurationNodeTemplate);
145 private void createVnfNodeTemplate(ServiceTemplate mainServiceTemplate,
146 VspModelInfo vspModelInfo, String componentId) {
147 Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
148 if (componentName.isPresent()) {
149 NodeTemplate vnfNodeTemplate = new NodeTemplate();
150 vnfNodeTemplate.setType(ToscaNodeType.MULTIDEPLOYMENTFLAVOR_NODE_TYPE);
151 List<String> directiveList = new ArrayList<>();
152 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
153 vnfNodeTemplate.setDirectives(directiveList);
154 vnfNodeTemplate.setProperties(getVnfNodeTemplateProperties(vspModelInfo, componentId));
156 .addSubstitutionFilteringProperty(getSubstitutionServiceTemplateFileName(componentName
157 .get()), vnfNodeTemplate, 1);
158 //Enable below if we need "abstract_" as prefix like we have in Unified model
159 //String nodeTemplateId =
160 // Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX + componentName + "VNF_NODE_TEMPLATE_ID_SUFFIX";
161 String nodeTemplateId = componentName.get() + VNF_NODE_TEMPLATE_ID_SUFFIX;
162 DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
164 abstractSubstitutionIdTypes.put(componentName.get(), ToscaNodeType
165 .MULTIDEPLOYMENTFLAVOR_NODE_TYPE);
169 private Map<String, Object> getVnfNodeTemplateProperties(VspModelInfo vspModelInfo,
170 String componentId) {
171 Map<String, Object> properties = new LinkedHashMap<>();
172 if (MapUtils.isNotEmpty(vspModelInfo.getMultiFlavorVfcImages())) {
173 List<MultiFlavorVfcImage> componentImages =
174 vspModelInfo.getMultiFlavorVfcImages().get(componentId);
175 if (Objects.nonNull(componentImages)) {
176 Map<String, MultiFlavorVfcImage> vfcImages = new HashMap<>();
177 componentImages.stream()
178 .forEach(multiFlavorVfcImage ->
179 vfcImages.put(multiFlavorVfcImage.getSoftware_version(), multiFlavorVfcImage));
180 properties.put(IMAGES_PROPERTY, vfcImages);
186 private String getSubstitutionServiceTemplateFileName(String componentName) {
187 return componentName + TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX;
190 private String getNodeTemplateId(String componentName, String idPrefix, String idSuffix) {
191 StringBuilder builder = new StringBuilder();
192 //builder.append(idPrefix);
193 builder.append(componentName);
194 builder.append(idSuffix);
195 return builder.toString();
198 private ServiceTemplate createInitMainServiceTemplate(String releaseVendor) {
199 ServiceTemplate mainServiceTemplate = new ServiceTemplate();
200 Map<String, String> templateMetadata = new HashMap<>();
201 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
202 if (Objects.nonNull(releaseVendor)) {
203 templateMetadata.put(RELEASE_VENDOR, releaseVendor);
205 mainServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
206 mainServiceTemplate.setMetadata(templateMetadata);
207 mainServiceTemplate.setTopology_template(new TopologyTemplate());
208 mainServiceTemplate.setImports(getImports());
209 return mainServiceTemplate;
212 private List<Map<String, Import>> getImports() {
213 Map<String, Import> globalSubstitutionTypeImportMap = new HashMap<>();
214 Import globalSubstitutionTypeImport = new Import();
215 globalSubstitutionTypeImport.setFile(ToscaUtil.getServiceTemplateFileName(Constants
216 .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
217 globalSubstitutionTypeImportMap.put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
218 globalSubstitutionTypeImport);
219 Map<String, Import> globalImports = new HashMap<>();
220 List<Map<String, Import>> manualVspGlobalTypesImportList = GlobalTypesGenerator
221 .getManualVspGlobalTypesImportList();
222 manualVspGlobalTypesImportList.add(globalSubstitutionTypeImportMap);
223 return manualVspGlobalTypesImportList;
226 private ServiceTemplate createSubstitutionServiceTemplate(String serviceTemplateName,
227 String substitutionNodeTypeId,
228 VspModelInfo vspModelInfo,
229 ToscaServiceModel toscaServiceModel) {
230 ServiceTemplate substitutionServiceTemplate =
231 createInitSubstitutionServiceTemplate(serviceTemplateName);
232 createSubstitutionServiceTemplateComponents(substitutionServiceTemplate, vspModelInfo,
234 createSubstitutionServiceTemplateNics(substitutionServiceTemplate, vspModelInfo,
236 handleSubstitutionMapping(substitutionServiceTemplate, toscaServiceModel,
237 substitutionNodeTypeId, serviceTemplateName);
238 return substitutionServiceTemplate;
241 private void createSubstitutionServiceTemplateComponents(ServiceTemplate
242 substitutionServiceTemplate,
243 VspModelInfo vspModelInfo,
244 ToscaServiceModel toscaServiceModel) {
245 Map<String, String> components = vspModelInfo.getComponents();
246 if (MapUtils.isNotEmpty(components)) {
247 for (String componentId : components.keySet()) {
248 String componentName = components.get(componentId);
249 String localNodeTypeId =
250 createComponentDefinitionNodeTemplate(substitutionServiceTemplate, componentName);
251 createLocalNodeType(substitutionServiceTemplate, localNodeTypeId);
256 private void createSubstitutionServiceTemplateNics(ServiceTemplate substitutionServiceTemplate,
257 VspModelInfo vspModelInfo,
258 ToscaServiceModel toscaServiceModel) {
259 Map<String, List<Nic>> nics = vspModelInfo.getNics();
260 if (MapUtils.isNotEmpty(nics)) {
261 for (Map.Entry<String, List<Nic>> entry : nics.entrySet()) {
262 String componentId = entry.getKey();
263 String componentNodeTemplateId = getSubstitutionComponentNodeTemplateId(
264 vspModelInfo.getComponents().get(componentId));
265 List<Nic> nicList = entry.getValue();
266 if (CollectionUtils.isNotEmpty(nicList)) {
267 for (Nic nic : nicList) {
268 NodeTemplate nicNodeTemplate = new NodeTemplate();
269 nicNodeTemplate.setType(ToscaNodeType.NETWORK_PORT);
270 DataModelUtil.addBindingReqFromPortToCompute(componentNodeTemplateId, nicNodeTemplate);
271 DataModelUtil.addNodeTemplate(substitutionServiceTemplate,
272 getNicNodeTemplateId(nic.getName(), nic.getNetworkType()), nicNodeTemplate);
279 private String getSubstitutionComponentNodeTemplateId(String componentName) {
280 //TODO: Confirm if anything else is needed here
281 return componentName;
284 private String getNicNodeTemplateId(String nicName, NetworkType nicNetworkType) {
285 StringBuilder builder = new StringBuilder();
286 builder.append(nicName);
287 if (nicNetworkType == NetworkType.External) {
288 builder.append(PORT_TYPE_EXTERNAL_NODE_TEMPLATE_SUFFIX);
289 } else if (nicNetworkType == NetworkType.Internal) {
290 builder.append(PORT_TYPE_INTERNAL_NODE_TEMPLATE_SUFFIX);
292 builder.append(PORT_NODE_TEMPLATE_ID_SUFFIX);
293 return builder.toString();
296 private String createComponentDefinitionNodeTemplate(ServiceTemplate substitutionServiceTemplate,
297 String componentName) {
298 NodeTemplate nodeTemplate = new NodeTemplate();
299 String localNodeTypeId = getLocalNodeTypeId(componentName);
300 nodeTemplate.setType(localNodeTypeId);
301 DataModelUtil.addNodeTemplate(substitutionServiceTemplate, componentName, nodeTemplate);
302 return localNodeTypeId;
305 private void createLocalNodeType(ServiceTemplate substitutionServiceTemplate,
306 String localNodeTypeId) {
307 NodeType localNodeType = new NodeType();
308 localNodeType.setDerived_from(ToscaNodeType.COMPUTE);
309 DataModelUtil.addNodeType(substitutionServiceTemplate, localNodeTypeId, localNodeType );
312 private String getLocalNodeTypeId(String componentName) {
313 return ToscaNodeType.VFC_NODE_TYPE_PREFIX + componentName;
316 private ServiceTemplate createInitSubstitutionServiceTemplate(String serviceTemplateName) {
317 ServiceTemplate substitutionServiceTemplate = new ServiceTemplate();
318 Map<String, String> templateMetadata = new HashMap<>();
319 substitutionServiceTemplate.setTosca_definitions_version(ToscaConstants
320 .TOSCA_DEFINITIONS_VERSION);
321 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, serviceTemplateName);
322 substitutionServiceTemplate.setMetadata(templateMetadata);
323 substitutionServiceTemplate.setTopology_template(new TopologyTemplate());
324 substitutionServiceTemplate.setImports(getImports());
325 return substitutionServiceTemplate;
328 private void handleSubstitutionMapping(ServiceTemplate substitutionServiceTemplate,
329 ToscaServiceModel toscaServiceModel,
330 String substitutionNodeTypeId,
331 String componentName) {
332 ServiceTemplate globalSubstitutionServiceTemplate = fetchGlobalSubstitutionServiceTemplate();
333 NodeType substitutionNodeType =
334 createGlobalSubstitutionNodeType(substitutionServiceTemplate, componentName);
335 DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId,
336 substitutionNodeType);
337 Map<String, Map<String, List<String>>> substitutionMapping =
338 GeneratorUtils.getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType,
339 substitutionServiceTemplate, toscaServiceModel);
340 if (Objects.nonNull(substitutionMapping)) {
341 //add substitution mapping after capability and requirement expose calculation
342 substitutionServiceTemplate.getTopology_template().setSubstitution_mappings(
343 DataModelUtil.createSubstitutionTemplateSubMapping(substitutionNodeTypeId,
344 substitutionNodeType, substitutionMapping));
348 //*************** CREATE GLOBAL SUBSTITUTION SERVICE TEMPLATE **********************
350 private ServiceTemplate createGlobalSubstitutionServiceTemplate(ServiceTemplate
351 substitutionServiceTemplate,
352 String componentName) {
353 ServiceTemplate globalSubstitutionServiceTemplate = fetchGlobalSubstitutionServiceTemplate();
354 NodeType substitutionNodeType =
355 createGlobalSubstitutionNodeType(substitutionServiceTemplate, componentName);
356 String substitutionNodeTypeId = getSubstitutionNodeTypeId(componentName);
357 DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId,
358 substitutionNodeType);
359 return globalSubstitutionServiceTemplate;
362 private ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
363 ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
364 Map<String, String> templateMetadata = new HashMap<>();
365 globalSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants
366 .TOSCA_DEFINITIONS_VERSION);
367 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME,
368 Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
369 globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
370 globalSubstitutionServiceTemplate.setImports(getImports());
371 return globalSubstitutionServiceTemplate;
374 private NodeType createGlobalSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
375 String componentName) {
376 NodeType substitutionNodeType = new ToscaAnalyzerServiceImpl()
377 .createInitSubstitutionNodeType(substitutionServiceTemplate,
378 ToscaNodeType.MULTIFLAVOR_VFC_NODE_TYPE);
379 substitutionNodeType.setProperties(
380 getManualVspSubstitutionNodeTypeProperties(substitutionNodeType, componentName));
381 return substitutionNodeType;
384 private Map<String, PropertyDefinition> getManualVspSubstitutionNodeTypeProperties(
385 NodeType substitutionNodeType, String componentName) {
386 //Create num_cpus property
387 PropertyDefinition numCpus = new PropertyDefinition();
388 numCpus.setType(PropertyType.INTEGER.getDisplayName());
389 numCpus.setDescription(NUM_CPUS_PROP_DESC_PREFIX + componentName);
390 numCpus.setRequired(true);
391 //Create disk_size property
392 PropertyDefinition diskSize = new PropertyDefinition();
393 diskSize.setType(PropertyType.SCALAR_UNIT_SIZE.getDisplayName());
394 diskSize.setDescription(DISK_SIZE_PROP_DESC_PREFIX + componentName);
395 diskSize.setRequired(true);
396 //Create mem_size property
397 PropertyDefinition memSize = new PropertyDefinition();
398 memSize.setType(PropertyType.SCALAR_UNIT_SIZE.getDisplayName());
399 memSize.setDescription(MEM_SIZE_PROP_DESC_PREFIX + componentName);
400 memSize.setRequired(true);
402 Map<String, PropertyDefinition> manualVspProperties = new LinkedHashMap<>();
403 manualVspProperties.put(NUM_CPUS, numCpus);
404 manualVspProperties.put(DISK_SIZE, diskSize);
405 manualVspProperties.put(MEM_SIZE, memSize);
407 return manualVspProperties;
410 private String getSubstitutionNodeTypeId(String componentName) {
411 return ToscaNodeType.MULTIDEPLOYMENTFLAVOR_NODE_TYPE + "." + componentName;
415 * Fetch global substitution service template service template.
417 * @return the global substitution service template
419 private ServiceTemplate fetchGlobalSubstitutionServiceTemplate() {
420 ServiceTemplate globalSubstitutionServiceTemplate =
421 generatedServiceTemplates.get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
422 if (Objects.isNull(globalSubstitutionServiceTemplate)) {
423 globalSubstitutionServiceTemplate = createInitGlobalSubstitutionServiceTemplate();
424 generatedServiceTemplates.put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
425 globalSubstitutionServiceTemplate);
427 return globalSubstitutionServiceTemplate;