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.sdc.generator.core.utils.GeneratorUtils;
22 import org.openecomp.sdc.generator.datatypes.tosca.MultiFlavorVfcImage;
23 import org.openecomp.sdc.generator.datatypes.tosca.VspModelInfo;
24 import org.openecomp.sdc.generator.util.GeneratorConstants;
25 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
26 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
27 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
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.sdc.tosca.services.DataModelUtil;
36 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
37 import org.openecomp.sdc.tosca.services.ToscaConstants;
38 import org.openecomp.sdc.tosca.services.ToscaUtil;
39 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
40 import org.openecomp.sdc.translator.services.heattotosca.Constants;
41 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
42 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.NetworkType;
43 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.Nic;
45 import java.util.ArrayList;
46 import java.util.HashMap;
47 import java.util.LinkedHashMap;
48 import java.util.List;
50 import java.util.Objects;
51 import java.util.Optional;
54 * The type Manual vsp tosca generator.
56 public class ManualVspToscaGenerationService {
58 //Map of the abstract node template id and substitution node type
59 private Map<String, String> abstractSubstitutionIdTypes = new HashMap<>();
60 //Map of service template name and service template for the generated service templates
61 private Map<String, ServiceTemplate> generatedServiceTemplates = new HashMap<>();
65 * Create manual vsp tosca service model tosca service model.
67 * @param vspModelInfo the vsp model info
68 * @return the tosca service model
70 public ToscaServiceModel createManualVspToscaServiceModel(VspModelInfo vspModelInfo) {
71 ToscaServiceModel toscaServiceModel = new ToscaServiceModel();
72 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
73 Map<String, ServiceTemplate> serviceTemplates = new HashMap<>(GlobalTypesGenerator
74 .getGlobalTypesServiceTemplate(OnboardingTypesEnum.MANUAL));
75 toscaServiceModel.setServiceTemplates(serviceTemplates);
76 toscaServiceModel.setEntryDefinitionServiceTemplate(Constants.MAIN_TEMPLATE_NAME
77 + GeneratorConstants.TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX);
78 createToscaFromVspData(vspModelInfo, toscaServiceModel);
79 for (Map.Entry<String, ServiceTemplate> serviceTemplateEntry :
80 generatedServiceTemplates.entrySet()) {
81 ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplateEntry
84 return toscaServiceModel;
87 private void createToscaFromVspData(VspModelInfo vspModelInfo,
88 ToscaServiceModel toscaServiceModel) {
89 List<ServiceTemplate> serviceTemplates = new ArrayList<>();
90 //Only one component supported
91 Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
92 if (componentName.isPresent()) {
93 //Create main service template
94 ServiceTemplate mainServiceTemplate = createMainServiceTemplate(vspModelInfo);
95 generatedServiceTemplates.put(Constants.MAIN_TEMPLATE_NAME, mainServiceTemplate);
96 //Create substitution service template
97 for (Map.Entry<String, String> entry : abstractSubstitutionIdTypes.entrySet()) {
98 ServiceTemplate substitutionServiceTemplate =
99 createSubstitutionServiceTemplate(componentName.get(), entry.getValue(), vspModelInfo,
101 generatedServiceTemplates.put(componentName.get(), substitutionServiceTemplate);
107 private Optional<String> getComponentNameFromVspModel(VspModelInfo vspModelInfo) {
108 String componentName = null;
109 if (MapUtils.isNotEmpty(vspModelInfo.getComponents())) {
110 //supported for single component only
111 componentName = vspModelInfo.getComponents().entrySet().iterator().next().getValue();
113 return Optional.ofNullable(componentName);
116 private ServiceTemplate createMainServiceTemplate(VspModelInfo vspModelInfo) {
117 ServiceTemplate mainServiceTemplate = createInitMainServiceTemplate(vspModelInfo
118 .getReleaseVendor());
119 Map<String, String> components = vspModelInfo.getComponents();
120 if (MapUtils.isNotEmpty(components)) {
121 //Currently since only one component is supported we can fetch the component in this manner.
122 // May be need to revisited for supporting multiple components
123 String componentId = components.entrySet().iterator().next().getKey();
124 createVnfConfigurationNodeTemplate(mainServiceTemplate, vspModelInfo);
125 createVnfNodeTemplate(mainServiceTemplate, vspModelInfo, componentId);
127 return mainServiceTemplate;
130 private void createVnfConfigurationNodeTemplate(ServiceTemplate mainServiceTemplate,
131 VspModelInfo vspModelInfo) {
132 Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
133 if (componentName.isPresent()) {
134 NodeTemplate vnfConfigurationNodeTemplate = new NodeTemplate();
135 vnfConfigurationNodeTemplate.setType(ToscaNodeType.VNF_CONFIG_NODE_TYPE);
136 if (Objects.nonNull(vspModelInfo.getAllowedFlavors())) {
137 Map<String, Object> properties = new LinkedHashMap<>();
138 properties.put(GeneratorConstants.ALLOWED_FLAVORS_PROPERTY, vspModelInfo.getAllowedFlavors());
139 vnfConfigurationNodeTemplate.setProperties(properties);
141 String nodeTemplateId = componentName.get() + GeneratorConstants.VNF_CONFIG_NODE_TEMPLATE_ID_SUFFIX;
142 DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
143 vnfConfigurationNodeTemplate);
147 private void createVnfNodeTemplate(ServiceTemplate mainServiceTemplate,
148 VspModelInfo vspModelInfo, String componentId) {
149 Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
150 if (componentName.isPresent()) {
151 NodeTemplate vnfNodeTemplate = new NodeTemplate();
152 vnfNodeTemplate.setType(ToscaNodeType.MULTIDEPLOYMENTFLAVOR_NODE_TYPE);
153 List<String> directiveList = new ArrayList<>();
154 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
155 vnfNodeTemplate.setDirectives(directiveList);
156 vnfNodeTemplate.setProperties(getVnfNodeTemplateProperties(vspModelInfo, componentId));
158 .addSubstitutionFilteringProperty(getSubstitutionServiceTemplateFileName(componentName
159 .get()), vnfNodeTemplate, 1);
160 //Enable below if we need "abstract_" as prefix like we have in Unified model
161 //String nodeTemplateId =
162 // Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX + componentName + "VNF_NODE_TEMPLATE_ID_SUFFIX";
163 String nodeTemplateId = componentName.get() + GeneratorConstants.VNF_NODE_TEMPLATE_ID_SUFFIX;
164 DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
166 abstractSubstitutionIdTypes.put(componentName.get(), ToscaNodeType
167 .MULTIDEPLOYMENTFLAVOR_NODE_TYPE);
171 private Map<String, Object> getVnfNodeTemplateProperties(VspModelInfo vspModelInfo,
172 String componentId) {
173 Map<String, Object> properties = new LinkedHashMap<>();
174 if (MapUtils.isNotEmpty(vspModelInfo.getMultiFlavorVfcImages())) {
175 List<MultiFlavorVfcImage> componentImages =
176 vspModelInfo.getMultiFlavorVfcImages().get(componentId);
177 if (Objects.nonNull(componentImages)) {
178 Map<String, MultiFlavorVfcImage> vfcImages = new HashMap<>();
179 componentImages.stream()
180 .forEach(multiFlavorVfcImage ->
181 vfcImages.put(multiFlavorVfcImage.getSoftware_version(), multiFlavorVfcImage));
182 properties.put(GeneratorConstants.IMAGES_PROPERTY, vfcImages);
188 private String getSubstitutionServiceTemplateFileName(String componentName) {
189 return componentName + GeneratorConstants.TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX;
192 private String getNodeTemplateId(String componentName, String idPrefix, String idSuffix) {
193 StringBuilder builder = new StringBuilder();
194 //builder.append(idPrefix);
195 builder.append(componentName);
196 builder.append(idSuffix);
197 return builder.toString();
200 private ServiceTemplate createInitMainServiceTemplate(String releaseVendor) {
201 ServiceTemplate mainServiceTemplate = new ServiceTemplate();
202 Map<String, String> templateMetadata = new HashMap<>();
203 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
204 if (Objects.nonNull(releaseVendor)) {
205 templateMetadata.put(GeneratorConstants.RELEASE_VENDOR, releaseVendor);
207 mainServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
208 mainServiceTemplate.setMetadata(templateMetadata);
209 mainServiceTemplate.setTopology_template(new TopologyTemplate());
210 mainServiceTemplate.setImports(getImports());
211 return mainServiceTemplate;
214 private List<Map<String, Import>> getImports() {
215 Map<String, Import> globalSubstitutionTypeImportMap = new HashMap<>();
216 Import globalSubstitutionTypeImport = new Import();
217 globalSubstitutionTypeImport.setFile(ToscaUtil.getServiceTemplateFileName(Constants
218 .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
219 globalSubstitutionTypeImportMap.put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
220 globalSubstitutionTypeImport);
221 Map<String, Import> globalImports = new HashMap<>();
222 List<Map<String, Import>> manualVspGlobalTypesImportList = GlobalTypesGenerator
223 .getManualVspGlobalTypesImportList();
224 manualVspGlobalTypesImportList.add(globalSubstitutionTypeImportMap);
225 return manualVspGlobalTypesImportList;
228 private ServiceTemplate createSubstitutionServiceTemplate(String serviceTemplateName,
229 String substitutionNodeTypeId,
230 VspModelInfo vspModelInfo,
231 ToscaServiceModel toscaServiceModel) {
232 ServiceTemplate substitutionServiceTemplate =
233 createInitSubstitutionServiceTemplate(serviceTemplateName);
234 createSubstitutionServiceTemplateComponents(substitutionServiceTemplate, vspModelInfo,
236 createSubstitutionServiceTemplateNics(substitutionServiceTemplate, vspModelInfo,
238 handleSubstitutionMapping(substitutionServiceTemplate, toscaServiceModel,
239 substitutionNodeTypeId, serviceTemplateName);
240 return substitutionServiceTemplate;
243 private void createSubstitutionServiceTemplateComponents(ServiceTemplate
244 substitutionServiceTemplate,
245 VspModelInfo vspModelInfo,
246 ToscaServiceModel toscaServiceModel) {
247 Map<String, String> components = vspModelInfo.getComponents();
248 if (MapUtils.isNotEmpty(components)) {
249 for (String componentId : components.keySet()) {
250 String componentName = components.get(componentId);
251 String localNodeTypeId =
252 createComponentDefinitionNodeTemplate(substitutionServiceTemplate, componentName);
253 createLocalNodeType(substitutionServiceTemplate, localNodeTypeId);
258 private void createSubstitutionServiceTemplateNics(ServiceTemplate substitutionServiceTemplate,
259 VspModelInfo vspModelInfo,
260 ToscaServiceModel toscaServiceModel) {
261 Map<String, List<Nic>> nics = vspModelInfo.getNics();
262 if (MapUtils.isNotEmpty(nics)) {
263 for (Map.Entry<String, List<Nic>> entry : nics.entrySet()) {
264 String componentId = entry.getKey();
265 String componentNodeTemplateId = getSubstitutionComponentNodeTemplateId(
266 vspModelInfo.getComponents().get(componentId));
267 List<Nic> nicList = entry.getValue();
268 if (CollectionUtils.isNotEmpty(nicList)) {
269 for (Nic nic : nicList) {
270 NodeTemplate nicNodeTemplate = new NodeTemplate();
271 nicNodeTemplate.setType(ToscaNodeType.NETWORK_PORT);
272 DataModelUtil.addBindingReqFromPortToCompute(componentNodeTemplateId, nicNodeTemplate);
273 DataModelUtil.addNodeTemplate(substitutionServiceTemplate,
274 getNicNodeTemplateId(nic.getName(), nic.getNetworkType()), nicNodeTemplate);
281 private String getSubstitutionComponentNodeTemplateId(String componentName) {
282 //TODO: Confirm if anything else is needed here
283 return componentName;
286 private String getNicNodeTemplateId(String nicName, NetworkType nicNetworkType) {
287 StringBuilder builder = new StringBuilder();
288 builder.append(nicName);
289 if (nicNetworkType == NetworkType.External) {
290 builder.append(GeneratorConstants.PORT_TYPE_EXTERNAL_NODE_TEMPLATE_SUFFIX);
291 } else if (nicNetworkType == NetworkType.Internal) {
292 builder.append(GeneratorConstants.PORT_TYPE_INTERNAL_NODE_TEMPLATE_SUFFIX);
294 builder.append(GeneratorConstants.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 ServiceTemplate globalSubstitutionServiceTemplate = fetchGlobalSubstitutionServiceTemplate();
335 NodeType substitutionNodeType =
336 createGlobalSubstitutionNodeType(substitutionServiceTemplate, componentName);
337 DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId,
338 substitutionNodeType);
339 Map<String, Map<String, List<String>>> substitutionMapping =
340 GeneratorUtils.getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType,
341 substitutionServiceTemplate, toscaServiceModel);
342 if (Objects.nonNull(substitutionMapping)) {
343 //add substitution mapping after capability and requirement expose calculation
344 substitutionServiceTemplate.getTopology_template().setSubstitution_mappings(
345 DataModelUtil.createSubstitutionTemplateSubMapping(substitutionNodeTypeId,
346 substitutionNodeType, substitutionMapping));
350 //*************** CREATE GLOBAL SUBSTITUTION SERVICE TEMPLATE **********************
352 private ServiceTemplate createGlobalSubstitutionServiceTemplate(ServiceTemplate
353 substitutionServiceTemplate,
354 String componentName) {
355 ServiceTemplate globalSubstitutionServiceTemplate = fetchGlobalSubstitutionServiceTemplate();
356 NodeType substitutionNodeType =
357 createGlobalSubstitutionNodeType(substitutionServiceTemplate, componentName);
358 String substitutionNodeTypeId = getSubstitutionNodeTypeId(componentName);
359 DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId,
360 substitutionNodeType);
361 return globalSubstitutionServiceTemplate;
364 private ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
365 ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
366 Map<String, String> templateMetadata = new HashMap<>();
367 globalSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants
368 .TOSCA_DEFINITIONS_VERSION);
369 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME,
370 Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
371 globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
372 globalSubstitutionServiceTemplate.setImports(getImports());
373 return globalSubstitutionServiceTemplate;
376 private NodeType createGlobalSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
377 String componentName) {
378 NodeType substitutionNodeType = new ToscaAnalyzerServiceImpl()
379 .createInitSubstitutionNodeType(substitutionServiceTemplate,
380 ToscaNodeType.MULTIFLAVOR_VFC_NODE_TYPE);
381 substitutionNodeType.setProperties(
382 getManualVspSubstitutionNodeTypeProperties(substitutionNodeType, componentName));
383 return substitutionNodeType;
386 private Map<String, PropertyDefinition> getManualVspSubstitutionNodeTypeProperties(
387 NodeType substitutionNodeType, String componentName) {
388 //Create num_cpus property
389 PropertyDefinition numCpus = new PropertyDefinition();
390 numCpus.setType(PropertyType.INTEGER.getDisplayName());
391 numCpus.setDescription(GeneratorConstants.NUM_CPUS_PROP_DESC_PREFIX + componentName);
392 numCpus.setRequired(true);
393 //Create disk_size property
394 PropertyDefinition diskSize = new PropertyDefinition();
395 diskSize.setType(PropertyType.SCALAR_UNIT_SIZE.getDisplayName());
396 diskSize.setDescription(GeneratorConstants.DISK_SIZE_PROP_DESC_PREFIX + componentName);
397 diskSize.setRequired(true);
398 //Create mem_size property
399 PropertyDefinition memSize = new PropertyDefinition();
400 memSize.setType(PropertyType.SCALAR_UNIT_SIZE.getDisplayName());
401 memSize.setDescription(GeneratorConstants.MEM_SIZE_PROP_DESC_PREFIX + componentName);
402 memSize.setRequired(true);
404 Map<String, PropertyDefinition> manualVspProperties = new LinkedHashMap<>();
405 manualVspProperties.put(GeneratorConstants.NUM_CPUS, numCpus);
406 manualVspProperties.put(GeneratorConstants.DISK_SIZE, diskSize);
407 manualVspProperties.put(GeneratorConstants.MEM_SIZE, memSize);
409 return manualVspProperties;
412 private String getSubstitutionNodeTypeId(String componentName) {
413 return ToscaNodeType.MULTIDEPLOYMENTFLAVOR_NODE_TYPE + "." + componentName;
417 * Fetch global substitution service template service template.
419 * @return the global substitution service template
421 private ServiceTemplate fetchGlobalSubstitutionServiceTemplate() {
422 ServiceTemplate globalSubstitutionServiceTemplate =
423 generatedServiceTemplates.get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
424 if (Objects.isNull(globalSubstitutionServiceTemplate)) {
425 globalSubstitutionServiceTemplate = createInitGlobalSubstitutionServiceTemplate();
426 generatedServiceTemplates.put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
427 globalSubstitutionServiceTemplate);
429 return globalSubstitutionServiceTemplate;