1 package org.openecomp.sdc.generator.core.services;
3 import static org.openecomp.sdc.generator.util.GeneratorConstants.ALLOWED_FLAVORS_PROPERTY;
4 import static org.openecomp.sdc.generator.util.GeneratorConstants.DISK_SIZE;
5 import static org.openecomp.sdc.generator.util.GeneratorConstants.DISK_SIZE_PROP_DESC_PREFIX;
6 import static org.openecomp.sdc.generator.util.GeneratorConstants.IMAGES_PROPERTY;
7 import static org.openecomp.sdc.generator.util.GeneratorConstants.MEM_SIZE;
8 import static org.openecomp.sdc.generator.util.GeneratorConstants.MEM_SIZE_PROP_DESC_PREFIX;
9 import static org.openecomp.sdc.generator.util.GeneratorConstants.NUM_CPUS;
10 import static org.openecomp.sdc.generator.util.GeneratorConstants.NUM_CPUS_PROP_DESC_PREFIX;
11 import static org.openecomp.sdc.generator.util.GeneratorConstants.PORT_NODE_TEMPLATE_ID_SUFFIX;
12 import static org.openecomp.sdc.generator.util.GeneratorConstants.RELEASE_VENDOR;
13 import static org.openecomp.sdc.generator.util.GeneratorConstants.TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX;
14 import static org.openecomp.sdc.generator.util.GeneratorConstants.VFC_NODE_TEMPLATE_ID_SUFFIX;
15 import static org.openecomp.sdc.generator.util.GeneratorConstants.VNF_CONFIG_NODE_TEMPLATE_ID_SUFFIX;
16 import static org.openecomp.sdc.generator.util.GeneratorConstants.VNF_NODE_TEMPLATE_ID_SUFFIX;
18 import org.apache.commons.collections4.CollectionUtils;
19 import org.apache.commons.collections4.MapUtils;
20 import org.openecomp.sdc.generator.core.utils.GeneratorUtils;
21 import org.openecomp.sdc.generator.datatypes.tosca.MultiFlavorVfcImage;
22 import org.openecomp.sdc.generator.datatypes.tosca.VspModelInfo;
23 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
24 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
25 import org.openecomp.sdc.tosca.datatypes.model.Import;
26 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
27 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
28 import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition;
29 import org.openecomp.sdc.tosca.datatypes.model.PropertyType;
30 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
31 import org.openecomp.sdc.tosca.datatypes.model.TopologyTemplate;
32 import org.openecomp.sdc.tosca.services.DataModelUtil;
33 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
34 import org.openecomp.sdc.tosca.services.ToscaConstants;
35 import org.openecomp.sdc.tosca.services.ToscaUtil;
36 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
37 import org.openecomp.sdc.translator.services.heattotosca.Constants;
38 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
39 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.Nic;
41 import java.util.ArrayList;
42 import java.util.HashMap;
43 import java.util.LinkedHashMap;
44 import java.util.List;
46 import java.util.Objects;
47 import java.util.Optional;
50 * The type Manual vsp tosca generator.
52 public class ManualVspToscaGenerationService {
54 //Map of the abstract node template id and substitution node type
55 private Map<String, String> abstractSubstitutionIdTypes = new HashMap<>();
56 //Map of service template name and service template for the generated service templates
57 private Map<String, ServiceTemplate> generatedServiceTemplates = new HashMap<>();
61 * Create manual vsp tosca service model tosca service model.
63 * @param vspModelInfo the vsp model info
64 * @return the tosca service model
66 public ToscaServiceModel createManualVspToscaServiceModel(VspModelInfo vspModelInfo) {
67 ToscaServiceModel toscaServiceModel = new ToscaServiceModel();
68 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
69 Map<String, ServiceTemplate> serviceTemplates = new HashMap<>(GlobalTypesGenerator
70 .getGlobalTypesServiceTemplate());
71 toscaServiceModel.setServiceTemplates(serviceTemplates);
72 toscaServiceModel.setEntryDefinitionServiceTemplate(Constants.MAIN_TEMPLATE_NAME
73 + TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX);
74 createToscaFromVspData(vspModelInfo, toscaServiceModel);
75 for (Map.Entry<String, ServiceTemplate> serviceTemplateEntry :
76 generatedServiceTemplates.entrySet()) {
77 ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplateEntry
80 return toscaServiceModel;
83 private void createToscaFromVspData(VspModelInfo vspModelInfo,
84 ToscaServiceModel toscaServiceModel) {
85 List<ServiceTemplate> serviceTemplates = new ArrayList<>();
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,
97 generatedServiceTemplates.put(componentName.get(), substitutionServiceTemplate);
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();
109 return Optional.ofNullable(componentName);
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 createComponentNodeTemplate(mainServiceTemplate, vspModelInfo, componentId);
122 createVnfNodeTemplate(mainServiceTemplate, vspModelInfo);
124 return mainServiceTemplate;
127 private void createVnfConfigurationNodeTemplate(ServiceTemplate mainServiceTemplate,
128 VspModelInfo vspModelInfo) {
129 Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
130 if (componentName.isPresent()) {
131 NodeTemplate vnfConfigurationNodeTemplate = new NodeTemplate();
132 vnfConfigurationNodeTemplate.setType(ToscaNodeType.VNF_CONFIG_NODE_TYPE);
133 if (Objects.nonNull(vspModelInfo.getAllowedFlavors())) {
134 Map<String, Object> properties = new LinkedHashMap<>();
135 properties.put(ALLOWED_FLAVORS_PROPERTY, vspModelInfo.getAllowedFlavors());
136 vnfConfigurationNodeTemplate.setProperties(properties);
138 String nodeTemplateId = componentName.get() + VNF_CONFIG_NODE_TEMPLATE_ID_SUFFIX;
139 DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
140 vnfConfigurationNodeTemplate);
144 private void createComponentNodeTemplate(ServiceTemplate mainServiceTemplate,
145 VspModelInfo vspModelInfo,
146 String componentId) {
147 Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
148 if (componentName.isPresent()) {
149 NodeTemplate vfcNodeTemplate = new NodeTemplate();
150 vfcNodeTemplate.setType(ToscaNodeType.MULTIFLAVOR_VFC_NODE_TYPE);
151 Map<String, Object> properties = new LinkedHashMap<>();
152 if (MapUtils.isNotEmpty(vspModelInfo.getMultiFlavorVfcImages())) {
153 List<MultiFlavorVfcImage> componentImages =
154 vspModelInfo.getMultiFlavorVfcImages().get(componentId);
155 Map<String, MultiFlavorVfcImage> vfcImages = new HashMap<>();
156 for (MultiFlavorVfcImage image : componentImages) {
157 vfcImages.put(image.getSoftware_version(), image);
159 properties.put(IMAGES_PROPERTY, vfcImages);
160 vfcNodeTemplate.setProperties(properties);
162 String nodeTemplateId = componentName.get() + VFC_NODE_TEMPLATE_ID_SUFFIX;
163 DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
168 private void createVnfNodeTemplate(ServiceTemplate mainServiceTemplate,
169 VspModelInfo vspModelInfo) {
170 Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
171 if (componentName.isPresent()) {
172 NodeTemplate vnfNodeTemplate = new NodeTemplate();
173 String vnfNodeTemplateType =
174 ToscaNodeType.MULTIDEPLOYMENTFLAVOR_NODE_TYPE + "." + componentName.get();
175 vnfNodeTemplate.setType(vnfNodeTemplateType);
176 List<String> directiveList = new ArrayList<>();
177 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
178 vnfNodeTemplate.setDirectives(directiveList);
179 vnfNodeTemplate.setProperties(new LinkedHashMap<>());
181 .addSubstitutionFilteringProperty(getSubstitutionServiceTemplateFileName(componentName
182 .get()), vnfNodeTemplate, 1);
183 //Enable below if we need "abstract_" as prefix like we have in Unified model
184 //String nodeTemplateId =
185 // Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX + componentName + "VNF_NODE_TEMPLATE_ID_SUFFIX";
186 String nodeTemplateId = componentName.get() + VNF_NODE_TEMPLATE_ID_SUFFIX;
187 DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
189 abstractSubstitutionIdTypes.put(componentName.get(), vnfNodeTemplateType);
193 private String getSubstitutionServiceTemplateFileName(String componentName) {
194 return componentName + TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX;
197 private String getNodeTemplateId(String componentName, String idPrefix, String idSuffix) {
198 StringBuilder builder = new StringBuilder();
199 //builder.append(idPrefix);
200 builder.append(componentName);
201 builder.append(idSuffix);
202 return builder.toString();
205 private ServiceTemplate createInitMainServiceTemplate(String releaseVendor) {
206 ServiceTemplate mainServiceTemplate = new ServiceTemplate();
207 Map<String, String> templateMetadata = new HashMap<>();
208 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
209 if (Objects.nonNull(releaseVendor)) {
210 templateMetadata.put(RELEASE_VENDOR, releaseVendor);
212 mainServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
213 mainServiceTemplate.setMetadata(templateMetadata);
214 mainServiceTemplate.setTopology_template(new TopologyTemplate());
215 mainServiceTemplate.setImports(getImports());
216 return mainServiceTemplate;
219 private List<Map<String, Import>> getImports() {
220 Map<String, Import> globalSubstitutionTypeImportMap = new HashMap<>();
221 Import globalSubstitutionTypeImport = new Import();
222 globalSubstitutionTypeImport.setFile(ToscaUtil.getServiceTemplateFileName(Constants
223 .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
224 globalSubstitutionTypeImportMap.put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
225 globalSubstitutionTypeImport);
226 Map<String, Import> globalImports = new HashMap<>();
227 List<Map<String, Import>> manualVspGlobalTypesImportList = GlobalTypesGenerator
228 .getManualVspGlobalTypesImportList();
229 manualVspGlobalTypesImportList.add(globalSubstitutionTypeImportMap);
230 return manualVspGlobalTypesImportList;
233 private ServiceTemplate createSubstitutionServiceTemplate(String serviceTemplateName,
234 String substitutionNodeTypeId,
235 VspModelInfo vspModelInfo,
236 ToscaServiceModel toscaServiceModel) {
237 ServiceTemplate substitutionServiceTemplate =
238 createInitSubstitutionServiceTemplate(serviceTemplateName);
239 createSubstitutionServiceTemplateComponents(substitutionServiceTemplate, vspModelInfo,
241 createSubstitutionServiceTemplateNics(substitutionServiceTemplate, vspModelInfo,
243 handleSubstitutionMapping(substitutionServiceTemplate, toscaServiceModel,
244 substitutionNodeTypeId, serviceTemplateName);
245 return substitutionServiceTemplate;
248 private void createSubstitutionServiceTemplateComponents(ServiceTemplate
249 substitutionServiceTemplate,
250 VspModelInfo vspModelInfo,
251 ToscaServiceModel toscaServiceModel) {
252 Map<String, String> components = vspModelInfo.getComponents();
253 if (MapUtils.isNotEmpty(components)) {
254 for (String componentId : components.keySet()) {
255 String componentName = components.get(componentId);
256 String localNodeTypeId =
257 createComponentDefinitionNodeTemplate(substitutionServiceTemplate, componentName);
258 createLocalNodeType(substitutionServiceTemplate, localNodeTypeId);
263 private void createSubstitutionServiceTemplateNics(ServiceTemplate substitutionServiceTemplate,
264 VspModelInfo vspModelInfo,
265 ToscaServiceModel toscaServiceModel) {
266 Map<String, List<Nic>> nics = vspModelInfo.getNics();
267 if (MapUtils.isNotEmpty(nics)) {
268 for (Map.Entry<String, List<Nic>> entry : nics.entrySet()) {
269 String componentId = entry.getKey();
270 String componentNodeTemplateId = getSubstitutionComponentNodeTemplateId(
271 vspModelInfo.getComponents().get(componentId));
272 List<Nic> nicList = entry.getValue();
273 if (CollectionUtils.isNotEmpty(nicList)) {
274 for (Nic nic : nicList) {
275 NodeTemplate nicNodeTemplate = new NodeTemplate();
276 nicNodeTemplate.setType(ToscaNodeType.NETWORK_PORT);
277 DataModelUtil.addBindingReqFromPortToCompute(componentNodeTemplateId, nicNodeTemplate);
278 DataModelUtil.addNodeTemplate(substitutionServiceTemplate,
279 getNicNodeTemplateId(nic.getName()), nicNodeTemplate);
286 private String getSubstitutionComponentNodeTemplateId(String componentName) {
287 //TODO: Confirm if anything else is needed here
288 return componentName;
291 private String getNicNodeTemplateId(String nicName) {
292 StringBuilder builder = new StringBuilder();
293 builder.append(nicName);
294 builder.append(PORT_NODE_TEMPLATE_ID_SUFFIX);
295 return builder.toString();
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;
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 );
314 private String getLocalNodeTypeId(String componentName) {
315 return ToscaNodeType.VFC_NODE_TYPE_PREFIX + componentName;
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;
330 private void handleSubstitutionMapping(ServiceTemplate substitutionServiceTemplate,
331 ToscaServiceModel toscaServiceModel,
332 String substitutionNodeTypeId,
333 String componentName) {
334 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
335 ServiceTemplate globalSubstitutionServiceTemplate = fetchGlobalSubstitutionServiceTemplate();
336 NodeType substitutionNodeType =
337 createGlobalSubstitutionNodeType(substitutionServiceTemplate, componentName);
338 DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId,
339 substitutionNodeType);
341 Map<String, Map<String, List<String>>> substitutionMapping =
342 GeneratorUtils.getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType,
343 substitutionServiceTemplate, toscaServiceModel);
344 if (Objects.nonNull(substitutionMapping)) {
345 //add substitution mapping after capability and requirement expose calculation
346 substitutionServiceTemplate.getTopology_template().setSubstitution_mappings(
347 DataModelUtil.createSubstitutionTemplateSubMapping(substitutionNodeTypeId,
348 substitutionNodeType, substitutionMapping));
352 //*************** CREATE GLOBAL SUBSTITUTION SERVICE TEMPLATE **********************
354 private ServiceTemplate createGlobalSubstitutionServiceTemplate(ServiceTemplate
355 substitutionServiceTemplate,
356 String componentName) {
357 ServiceTemplate globalSubstitutionServiceTemplate = fetchGlobalSubstitutionServiceTemplate();
358 NodeType substitutionNodeType =
359 createGlobalSubstitutionNodeType(substitutionServiceTemplate, componentName);
360 String substitutionNodeTypeId = getSubstitutionNodeTypeId(componentName);
361 DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId,
362 substitutionNodeType);
363 return globalSubstitutionServiceTemplate;
366 private ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
367 ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
368 Map<String, String> templateMetadata = new HashMap<>();
369 globalSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants
370 .TOSCA_DEFINITIONS_VERSION);
371 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME,
372 Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
373 globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
374 globalSubstitutionServiceTemplate.setImports(getImports());
375 return globalSubstitutionServiceTemplate;
378 private NodeType createGlobalSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
379 String componentName) {
380 NodeType substitutionNodeType = new ToscaAnalyzerServiceImpl()
381 .createInitSubstitutionNodeType(substitutionServiceTemplate,
382 ToscaNodeType.VFC_ABSTRACT_SUBSTITUTE);
383 substitutionNodeType.setProperties(
384 getManualVspSubstitutionNodeTypeProperties(substitutionNodeType, componentName));
385 return substitutionNodeType;
388 private Map<String, PropertyDefinition> getManualVspSubstitutionNodeTypeProperties(
389 NodeType substitutionNodeType, String componentName) {
390 //Create num_cpus property
391 PropertyDefinition numCpus = new PropertyDefinition();
392 numCpus.setType(PropertyType.INTEGER.getDisplayName());
393 numCpus.setDescription(NUM_CPUS_PROP_DESC_PREFIX + componentName);
394 numCpus.setRequired(true);
395 //Create disk_size property
396 PropertyDefinition diskSize = new PropertyDefinition();
397 diskSize.setType(PropertyType.SCALAR_UNIT_SIZE.getDisplayName());
398 diskSize.setDescription(DISK_SIZE_PROP_DESC_PREFIX + componentName);
399 diskSize.setRequired(true);
400 //Create mem_size property
401 PropertyDefinition memSize = new PropertyDefinition();
402 memSize.setType(PropertyType.SCALAR_UNIT_SIZE.getDisplayName());
403 memSize.setDescription(MEM_SIZE_PROP_DESC_PREFIX + componentName);
404 memSize.setRequired(true);
406 Map<String, PropertyDefinition> manualVspProperties = new LinkedHashMap<>();
407 manualVspProperties.put(NUM_CPUS, numCpus);
408 manualVspProperties.put(DISK_SIZE, diskSize);
409 manualVspProperties.put(MEM_SIZE, memSize);
411 return manualVspProperties;
414 private String getSubstitutionNodeTypeId(String componentName) {
415 return ToscaNodeType.MULTIDEPLOYMENTFLAVOR_NODE_TYPE + "." + componentName;
419 * Fetch global substitution service template service template.
421 * @return the global substitution service template
423 private ServiceTemplate fetchGlobalSubstitutionServiceTemplate() {
424 ServiceTemplate globalSubstitutionServiceTemplate =
425 generatedServiceTemplates.get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
426 if (Objects.isNull(globalSubstitutionServiceTemplate)) {
427 globalSubstitutionServiceTemplate = createInitGlobalSubstitutionServiceTemplate();
428 generatedServiceTemplates.put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
429 globalSubstitutionServiceTemplate);
431 return globalSubstitutionServiceTemplate;