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 java.util.ArrayList;
20 import java.util.HashMap;
21 import java.util.LinkedHashMap;
22 import java.util.List;
24 import java.util.Objects;
25 import java.util.Optional;
26 import org.apache.commons.collections4.CollectionUtils;
27 import org.apache.commons.collections4.MapUtils;
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.core.utilities.orchestration.OnboardingTypesEnum;
36 import org.openecomp.sdc.generator.core.utils.GeneratorUtils;
37 import org.openecomp.sdc.generator.datatypes.tosca.MultiFlavorVfcImage;
38 import org.openecomp.sdc.generator.datatypes.tosca.VspModelInfo;
39 import org.openecomp.sdc.generator.util.GeneratorConstants;
40 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
41 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
42 import org.openecomp.sdc.tosca.services.DataModelUtil;
43 import org.openecomp.sdc.tosca.services.ToscaConstants;
44 import org.openecomp.sdc.tosca.services.ToscaUtil;
45 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
46 import org.openecomp.sdc.translator.services.heattotosca.Constants;
47 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
48 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.NetworkType;
49 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.Nic;
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 Map<String, ServiceTemplate> serviceTemplates = new HashMap<>(GlobalTypesGenerator
71 .getGlobalTypesServiceTemplate(OnboardingTypesEnum.MANUAL));
72 toscaServiceModel.setServiceTemplates(serviceTemplates);
73 toscaServiceModel.setEntryDefinitionServiceTemplate(Constants.MAIN_TEMPLATE_NAME
74 + GeneratorConstants.TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX);
75 createToscaFromVspData(vspModelInfo, toscaServiceModel);
76 for (Map.Entry<String, ServiceTemplate> serviceTemplateEntry :
77 generatedServiceTemplates.entrySet()) {
78 ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplateEntry
81 return toscaServiceModel;
84 private void createToscaFromVspData(VspModelInfo vspModelInfo,
85 ToscaServiceModel toscaServiceModel) {
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 createVnfNodeTemplate(mainServiceTemplate, vspModelInfo, componentId);
123 return mainServiceTemplate;
126 private void createVnfConfigurationNodeTemplate(ServiceTemplate mainServiceTemplate,
127 VspModelInfo vspModelInfo) {
128 Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
129 if (componentName.isPresent()) {
130 NodeTemplate vnfConfigurationNodeTemplate = new NodeTemplate();
131 vnfConfigurationNodeTemplate.setType(ToscaNodeType.VNF_CONFIG_NODE_TYPE);
132 if (Objects.nonNull(vspModelInfo.getAllowedFlavors())) {
133 Map<String, Object> properties = new LinkedHashMap<>();
134 properties.put(GeneratorConstants.ALLOWED_FLAVORS_PROPERTY, vspModelInfo.getAllowedFlavors());
135 vnfConfigurationNodeTemplate.setProperties(properties);
137 String nodeTemplateId = componentName.get() + GeneratorConstants.VNF_CONFIG_NODE_TEMPLATE_ID_SUFFIX;
138 DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
139 vnfConfigurationNodeTemplate);
143 private void createVnfNodeTemplate(ServiceTemplate mainServiceTemplate,
144 VspModelInfo vspModelInfo, String componentId) {
145 Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
146 if (componentName.isPresent()) {
147 NodeTemplate vnfNodeTemplate = new NodeTemplate();
148 vnfNodeTemplate.setType(ToscaNodeType.MULTIDEPLOYMENTFLAVOR_NODE_TYPE);
149 List<String> directiveList = new ArrayList<>();
150 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
151 vnfNodeTemplate.setDirectives(directiveList);
152 vnfNodeTemplate.setProperties(getVnfNodeTemplateProperties(vspModelInfo, componentId));
154 .addSubstitutionFilteringProperty(getSubstitutionServiceTemplateFileName(componentName
155 .get()), vnfNodeTemplate, 1);
156 //Enable below if we need "abstract_" as prefix like we have in Unified model
157 //String nodeTemplateId =
158 // Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX + componentName + "VNF_NODE_TEMPLATE_ID_SUFFIX";
159 String nodeTemplateId = componentName.get() + GeneratorConstants.VNF_NODE_TEMPLATE_ID_SUFFIX;
160 DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
162 abstractSubstitutionIdTypes.put(componentName.get(), ToscaNodeType
163 .MULTIDEPLOYMENTFLAVOR_NODE_TYPE);
167 private Map<String, Object> getVnfNodeTemplateProperties(VspModelInfo vspModelInfo,
168 String componentId) {
169 Map<String, Object> properties = new LinkedHashMap<>();
170 if (MapUtils.isNotEmpty(vspModelInfo.getMultiFlavorVfcImages())) {
171 List<MultiFlavorVfcImage> componentImages =
172 vspModelInfo.getMultiFlavorVfcImages().get(componentId);
173 if (Objects.nonNull(componentImages)) {
174 Map<String, MultiFlavorVfcImage> vfcImages = new HashMap<>();
175 componentImages.stream()
176 .forEach(multiFlavorVfcImage ->
177 vfcImages.put(multiFlavorVfcImage.getSoftware_version(), multiFlavorVfcImage));
178 properties.put(GeneratorConstants.IMAGES_PROPERTY, vfcImages);
184 private String getSubstitutionServiceTemplateFileName(String componentName) {
185 return componentName + GeneratorConstants.TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX;
188 private ServiceTemplate createInitMainServiceTemplate(String releaseVendor) {
189 ServiceTemplate mainServiceTemplate = new ServiceTemplate();
190 Map<String, String> templateMetadata = new HashMap<>();
191 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
192 if (Objects.nonNull(releaseVendor)) {
193 templateMetadata.put(GeneratorConstants.RELEASE_VENDOR, releaseVendor);
195 mainServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
196 mainServiceTemplate.setMetadata(templateMetadata);
197 mainServiceTemplate.setTopology_template(new TopologyTemplate());
198 mainServiceTemplate.setImports(getImports());
199 return mainServiceTemplate;
202 private List<Map<String, Import>> getImports() {
203 Map<String, Import> globalSubstitutionTypeImportMap = new HashMap<>();
204 Import globalSubstitutionTypeImport = new Import();
205 globalSubstitutionTypeImport.setFile(ToscaUtil.getServiceTemplateFileName(Constants
206 .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
207 globalSubstitutionTypeImportMap.put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
208 globalSubstitutionTypeImport);
209 List<Map<String, Import>> manualVspGlobalTypesImportList = GlobalTypesGenerator
210 .getManualVspGlobalTypesImportList();
211 manualVspGlobalTypesImportList.add(globalSubstitutionTypeImportMap);
212 return manualVspGlobalTypesImportList;
215 private ServiceTemplate createSubstitutionServiceTemplate(String serviceTemplateName,
216 String substitutionNodeTypeId,
217 VspModelInfo vspModelInfo,
218 ToscaServiceModel toscaServiceModel) {
219 ServiceTemplate substitutionServiceTemplate =
220 createInitSubstitutionServiceTemplate(serviceTemplateName);
221 createSubstitutionServiceTemplateComponents(substitutionServiceTemplate, vspModelInfo);
222 createSubstitutionServiceTemplateNics(substitutionServiceTemplate, vspModelInfo);
223 handleSubstitutionMapping(substitutionServiceTemplate, toscaServiceModel,
224 substitutionNodeTypeId, serviceTemplateName);
225 return substitutionServiceTemplate;
228 private void createSubstitutionServiceTemplateComponents(ServiceTemplate
229 substitutionServiceTemplate,
230 VspModelInfo vspModelInfo) {
231 Map<String, String> components = vspModelInfo.getComponents();
232 if (MapUtils.isNotEmpty(components)) {
233 for (String componentName : components.values()) {
234 String localNodeTypeId =
235 createComponentDefinitionNodeTemplate(substitutionServiceTemplate, componentName);
236 createLocalNodeType(substitutionServiceTemplate, localNodeTypeId);
241 private void createSubstitutionServiceTemplateNics(ServiceTemplate substitutionServiceTemplate,
242 VspModelInfo vspModelInfo) {
243 Map<String, List<Nic>> nics = vspModelInfo.getNics();
244 if (MapUtils.isNotEmpty(nics)) {
245 for (Map.Entry<String, List<Nic>> entry : nics.entrySet()) {
246 String componentId = entry.getKey();
247 String componentNodeTemplateId = getSubstitutionComponentNodeTemplateId(
248 vspModelInfo.getComponents().get(componentId));
249 List<Nic> nicList = entry.getValue();
250 if (CollectionUtils.isNotEmpty(nicList)) {
251 for (Nic nic : nicList) {
252 NodeTemplate nicNodeTemplate = new NodeTemplate();
253 nicNodeTemplate.setType(ToscaNodeType.NETWORK_PORT);
254 DataModelUtil.addBindingReqFromPortToCompute(componentNodeTemplateId, nicNodeTemplate);
255 DataModelUtil.addNodeTemplate(substitutionServiceTemplate,
256 getNicNodeTemplateId(nic.getName(), nic.getNetworkType()), nicNodeTemplate);
263 private String getSubstitutionComponentNodeTemplateId(String componentName) {
264 //TODO: Confirm if anything else is needed here
265 return componentName;
268 private String getNicNodeTemplateId(String nicName, NetworkType nicNetworkType) {
269 StringBuilder builder = new StringBuilder();
270 builder.append(nicName);
271 if (nicNetworkType == NetworkType.External) {
272 builder.append(GeneratorConstants.PORT_TYPE_EXTERNAL_NODE_TEMPLATE_SUFFIX);
273 } else if (nicNetworkType == NetworkType.Internal) {
274 builder.append(GeneratorConstants.PORT_TYPE_INTERNAL_NODE_TEMPLATE_SUFFIX);
276 builder.append(GeneratorConstants.PORT_NODE_TEMPLATE_ID_SUFFIX);
277 return builder.toString();
280 private String createComponentDefinitionNodeTemplate(ServiceTemplate substitutionServiceTemplate,
281 String componentName) {
282 NodeTemplate nodeTemplate = new NodeTemplate();
283 String localNodeTypeId = getLocalNodeTypeId(componentName);
284 nodeTemplate.setType(localNodeTypeId);
285 DataModelUtil.addNodeTemplate(substitutionServiceTemplate, componentName, nodeTemplate);
286 return localNodeTypeId;
289 private void createLocalNodeType(ServiceTemplate substitutionServiceTemplate,
290 String localNodeTypeId) {
291 NodeType localNodeType = new NodeType();
292 localNodeType.setDerived_from(ToscaNodeType.COMPUTE);
293 DataModelUtil.addNodeType(substitutionServiceTemplate, localNodeTypeId, localNodeType );
296 private String getLocalNodeTypeId(String componentName) {
297 return ToscaNodeType.VFC_NODE_TYPE_PREFIX + componentName;
300 private ServiceTemplate createInitSubstitutionServiceTemplate(String serviceTemplateName) {
301 ServiceTemplate substitutionServiceTemplate = new ServiceTemplate();
302 Map<String, String> templateMetadata = new HashMap<>();
303 substitutionServiceTemplate.setTosca_definitions_version(ToscaConstants
304 .TOSCA_DEFINITIONS_VERSION);
305 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, serviceTemplateName);
306 substitutionServiceTemplate.setMetadata(templateMetadata);
307 substitutionServiceTemplate.setTopology_template(new TopologyTemplate());
308 substitutionServiceTemplate.setImports(getImports());
309 return substitutionServiceTemplate;
312 private void handleSubstitutionMapping(ServiceTemplate substitutionServiceTemplate,
313 ToscaServiceModel toscaServiceModel,
314 String substitutionNodeTypeId,
315 String componentName) {
316 ServiceTemplate globalSubstitutionServiceTemplate = fetchGlobalSubstitutionServiceTemplate();
317 NodeType substitutionNodeType =
318 createGlobalSubstitutionNodeType(substitutionServiceTemplate, componentName);
319 DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId,
320 substitutionNodeType);
321 Map<String, Map<String, List<String>>> substitutionMapping =
322 GeneratorUtils.getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType,
323 substitutionServiceTemplate, toscaServiceModel);
324 if (Objects.nonNull(substitutionMapping)) {
325 //add substitution mapping after capability and requirement expose calculation
326 substitutionServiceTemplate.getTopology_template().setSubstitution_mappings(
327 DataModelUtil.createSubstitutionTemplateSubMapping(substitutionNodeTypeId,
328 substitutionNodeType, substitutionMapping));
332 //*************** CREATE GLOBAL SUBSTITUTION SERVICE TEMPLATE **********************
334 private ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
335 ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
336 Map<String, String> templateMetadata = new HashMap<>();
337 globalSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants
338 .TOSCA_DEFINITIONS_VERSION);
339 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME,
340 Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
341 globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
342 globalSubstitutionServiceTemplate.setImports(getImports());
343 return globalSubstitutionServiceTemplate;
346 private NodeType createGlobalSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
347 String componentName) {
348 NodeType substitutionNodeType = new ToscaAnalyzerServiceImpl()
349 .createInitSubstitutionNodeType(substitutionServiceTemplate,
350 ToscaNodeType.MULTIFLAVOR_VFC_NODE_TYPE);
351 substitutionNodeType.setProperties(
352 getManualVspSubstitutionNodeTypeProperties(componentName));
353 return substitutionNodeType;
356 private Map<String, PropertyDefinition> getManualVspSubstitutionNodeTypeProperties(String componentName) {
357 //Create num_cpus property
358 PropertyDefinition numCpus = new PropertyDefinition();
359 numCpus.setType(PropertyType.INTEGER.getDisplayName());
360 numCpus.setDescription(GeneratorConstants.NUM_CPUS_PROP_DESC_PREFIX + componentName);
361 numCpus.setRequired(true);
362 //Create disk_size property
363 PropertyDefinition diskSize = new PropertyDefinition();
364 diskSize.setType(PropertyType.SCALAR_UNIT_SIZE.getDisplayName());
365 diskSize.setDescription(GeneratorConstants.DISK_SIZE_PROP_DESC_PREFIX + componentName);
366 diskSize.setRequired(true);
367 //Create mem_size property
368 PropertyDefinition memSize = new PropertyDefinition();
369 memSize.setType(PropertyType.SCALAR_UNIT_SIZE.getDisplayName());
370 memSize.setDescription(GeneratorConstants.MEM_SIZE_PROP_DESC_PREFIX + componentName);
371 memSize.setRequired(true);
373 Map<String, PropertyDefinition> manualVspProperties = new LinkedHashMap<>();
374 manualVspProperties.put(GeneratorConstants.NUM_CPUS, numCpus);
375 manualVspProperties.put(GeneratorConstants.DISK_SIZE, diskSize);
376 manualVspProperties.put(GeneratorConstants.MEM_SIZE, memSize);
378 return manualVspProperties;
382 * Fetch global substitution service template service template.
384 * @return the global substitution service template
386 private ServiceTemplate fetchGlobalSubstitutionServiceTemplate() {
387 ServiceTemplate globalSubstitutionServiceTemplate =
388 generatedServiceTemplates.get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
389 if (Objects.isNull(globalSubstitutionServiceTemplate)) {
390 globalSubstitutionServiceTemplate = createInitGlobalSubstitutionServiceTemplate();
391 generatedServiceTemplates.put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
392 globalSubstitutionServiceTemplate);
394 return globalSubstitutionServiceTemplate;