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