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.onap.sdc.tosca.datatypes.model.*;
22 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
23 import org.openecomp.sdc.generator.core.utils.GeneratorUtils;
24 import org.openecomp.sdc.generator.datatypes.tosca.MultiFlavorVfcImage;
25 import org.openecomp.sdc.generator.datatypes.tosca.VspModelInfo;
26 import org.openecomp.sdc.generator.util.GeneratorConstants;
27 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
28 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
29 import org.openecomp.sdc.tosca.services.DataModelUtil;
30 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
31 import org.openecomp.sdc.tosca.services.ToscaConstants;
32 import org.openecomp.sdc.tosca.services.ToscaUtil;
33 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
34 import org.openecomp.sdc.translator.services.heattotosca.Constants;
35 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
36 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.NetworkType;
37 import org.openecomp.sdc.vendorsoftwareproduct.types.composition.Nic;
42 * The type Manual vsp tosca generator.
44 public class ManualVspToscaGenerationService {
46 //Map of the abstract node template id and substitution node type
47 private Map<String, String> abstractSubstitutionIdTypes = new HashMap<>();
48 //Map of service template name and service template for the generated service templates
49 private Map<String, ServiceTemplate> generatedServiceTemplates = new HashMap<>();
53 * Create manual vsp tosca service model tosca service model.
55 * @param vspModelInfo the vsp model info
56 * @return the tosca service model
58 public ToscaServiceModel createManualVspToscaServiceModel(VspModelInfo vspModelInfo) {
59 ToscaServiceModel toscaServiceModel = new ToscaServiceModel();
60 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
61 Map<String, ServiceTemplate> serviceTemplates = new HashMap<>(GlobalTypesGenerator
62 .getGlobalTypesServiceTemplate(OnboardingTypesEnum.MANUAL));
63 toscaServiceModel.setServiceTemplates(serviceTemplates);
64 toscaServiceModel.setEntryDefinitionServiceTemplate(Constants.MAIN_TEMPLATE_NAME
65 + GeneratorConstants.TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX);
66 createToscaFromVspData(vspModelInfo, toscaServiceModel);
67 for (Map.Entry<String, ServiceTemplate> serviceTemplateEntry :
68 generatedServiceTemplates.entrySet()) {
69 ToscaUtil.addServiceTemplateToMapWithKeyFileName(serviceTemplates, serviceTemplateEntry
72 return toscaServiceModel;
75 private void createToscaFromVspData(VspModelInfo vspModelInfo,
76 ToscaServiceModel toscaServiceModel) {
77 List<ServiceTemplate> serviceTemplates = new ArrayList<>();
78 //Only one component supported
79 Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
80 if (componentName.isPresent()) {
81 //Create main service template
82 ServiceTemplate mainServiceTemplate = createMainServiceTemplate(vspModelInfo);
83 generatedServiceTemplates.put(Constants.MAIN_TEMPLATE_NAME, mainServiceTemplate);
84 //Create substitution service template
85 for (Map.Entry<String, String> entry : abstractSubstitutionIdTypes.entrySet()) {
86 ServiceTemplate substitutionServiceTemplate =
87 createSubstitutionServiceTemplate(componentName.get(), entry.getValue(), vspModelInfo,
89 generatedServiceTemplates.put(componentName.get(), substitutionServiceTemplate);
95 private Optional<String> getComponentNameFromVspModel(VspModelInfo vspModelInfo) {
96 String componentName = null;
97 if (MapUtils.isNotEmpty(vspModelInfo.getComponents())) {
98 //supported for single component only
99 componentName = vspModelInfo.getComponents().entrySet().iterator().next().getValue();
101 return Optional.ofNullable(componentName);
104 private ServiceTemplate createMainServiceTemplate(VspModelInfo vspModelInfo) {
105 ServiceTemplate mainServiceTemplate = createInitMainServiceTemplate(vspModelInfo
106 .getReleaseVendor());
107 Map<String, String> components = vspModelInfo.getComponents();
108 if (MapUtils.isNotEmpty(components)) {
109 //Currently since only one component is supported we can fetch the component in this manner.
110 // May be need to revisited for supporting multiple components
111 String componentId = components.entrySet().iterator().next().getKey();
112 createVnfConfigurationNodeTemplate(mainServiceTemplate, vspModelInfo);
113 createVnfNodeTemplate(mainServiceTemplate, vspModelInfo, componentId);
115 return mainServiceTemplate;
118 private void createVnfConfigurationNodeTemplate(ServiceTemplate mainServiceTemplate,
119 VspModelInfo vspModelInfo) {
120 Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
121 if (componentName.isPresent()) {
122 NodeTemplate vnfConfigurationNodeTemplate = new NodeTemplate();
123 vnfConfigurationNodeTemplate.setType(ToscaNodeType.VNF_CONFIG_NODE_TYPE);
124 if (Objects.nonNull(vspModelInfo.getAllowedFlavors())) {
125 Map<String, Object> properties = new LinkedHashMap<>();
126 properties.put(GeneratorConstants.ALLOWED_FLAVORS_PROPERTY, vspModelInfo.getAllowedFlavors());
127 vnfConfigurationNodeTemplate.setProperties(properties);
129 String nodeTemplateId = componentName.get() + GeneratorConstants.VNF_CONFIG_NODE_TEMPLATE_ID_SUFFIX;
130 DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
131 vnfConfigurationNodeTemplate);
135 private void createVnfNodeTemplate(ServiceTemplate mainServiceTemplate,
136 VspModelInfo vspModelInfo, String componentId) {
137 Optional<String> componentName = getComponentNameFromVspModel(vspModelInfo);
138 if (componentName.isPresent()) {
139 NodeTemplate vnfNodeTemplate = new NodeTemplate();
140 vnfNodeTemplate.setType(ToscaNodeType.MULTIDEPLOYMENTFLAVOR_NODE_TYPE);
141 List<String> directiveList = new ArrayList<>();
142 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
143 vnfNodeTemplate.setDirectives(directiveList);
144 vnfNodeTemplate.setProperties(getVnfNodeTemplateProperties(vspModelInfo, componentId));
146 .addSubstitutionFilteringProperty(getSubstitutionServiceTemplateFileName(componentName
147 .get()), vnfNodeTemplate, 1);
148 //Enable below if we need "abstract_" as prefix like we have in Unified model
149 //String nodeTemplateId =
150 // Constants.ABSTRACT_NODE_TEMPLATE_ID_PREFIX + componentName + "VNF_NODE_TEMPLATE_ID_SUFFIX";
151 String nodeTemplateId = componentName.get() + GeneratorConstants.VNF_NODE_TEMPLATE_ID_SUFFIX;
152 DataModelUtil.addNodeTemplate(mainServiceTemplate, nodeTemplateId,
154 abstractSubstitutionIdTypes.put(componentName.get(), ToscaNodeType
155 .MULTIDEPLOYMENTFLAVOR_NODE_TYPE);
159 private Map<String, Object> getVnfNodeTemplateProperties(VspModelInfo vspModelInfo,
160 String componentId) {
161 Map<String, Object> properties = new LinkedHashMap<>();
162 if (MapUtils.isNotEmpty(vspModelInfo.getMultiFlavorVfcImages())) {
163 List<MultiFlavorVfcImage> componentImages =
164 vspModelInfo.getMultiFlavorVfcImages().get(componentId);
165 if (Objects.nonNull(componentImages)) {
166 Map<String, MultiFlavorVfcImage> vfcImages = new HashMap<>();
167 componentImages.stream()
168 .forEach(multiFlavorVfcImage ->
169 vfcImages.put(multiFlavorVfcImage.getSoftware_version(), multiFlavorVfcImage));
170 properties.put(GeneratorConstants.IMAGES_PROPERTY, vfcImages);
176 private String getSubstitutionServiceTemplateFileName(String componentName) {
177 return componentName + GeneratorConstants.TOSCA_SERVICE_TEMPLATE_FILE_NAME_SUFFIX;
180 private ServiceTemplate createInitMainServiceTemplate(String releaseVendor) {
181 ServiceTemplate mainServiceTemplate = new ServiceTemplate();
182 Map<String, String> templateMetadata = new HashMap<>();
183 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, Constants.MAIN_TEMPLATE_NAME);
184 if (Objects.nonNull(releaseVendor)) {
185 templateMetadata.put(GeneratorConstants.RELEASE_VENDOR, releaseVendor);
187 mainServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
188 mainServiceTemplate.setMetadata(templateMetadata);
189 mainServiceTemplate.setTopology_template(new TopologyTemplate());
190 mainServiceTemplate.setImports(getImports());
191 return mainServiceTemplate;
194 private List<Map<String, Import>> getImports() {
195 Map<String, Import> globalSubstitutionTypeImportMap = new HashMap<>();
196 Import globalSubstitutionTypeImport = new Import();
197 globalSubstitutionTypeImport.setFile(ToscaUtil.getServiceTemplateFileName(Constants
198 .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
199 globalSubstitutionTypeImportMap.put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
200 globalSubstitutionTypeImport);
201 Map<String, Import> globalImports = new HashMap<>();
202 List<Map<String, Import>> manualVspGlobalTypesImportList = GlobalTypesGenerator
203 .getManualVspGlobalTypesImportList();
204 manualVspGlobalTypesImportList.add(globalSubstitutionTypeImportMap);
205 return manualVspGlobalTypesImportList;
208 private ServiceTemplate createSubstitutionServiceTemplate(String serviceTemplateName,
209 String substitutionNodeTypeId,
210 VspModelInfo vspModelInfo,
211 ToscaServiceModel toscaServiceModel) {
212 ServiceTemplate substitutionServiceTemplate =
213 createInitSubstitutionServiceTemplate(serviceTemplateName);
214 createSubstitutionServiceTemplateComponents(substitutionServiceTemplate, vspModelInfo,
216 createSubstitutionServiceTemplateNics(substitutionServiceTemplate, vspModelInfo,
218 handleSubstitutionMapping(substitutionServiceTemplate, toscaServiceModel,
219 substitutionNodeTypeId, serviceTemplateName);
220 return substitutionServiceTemplate;
223 private void createSubstitutionServiceTemplateComponents(ServiceTemplate
224 substitutionServiceTemplate,
225 VspModelInfo vspModelInfo,
226 ToscaServiceModel toscaServiceModel) {
227 Map<String, String> components = vspModelInfo.getComponents();
228 if (MapUtils.isNotEmpty(components)) {
229 for (String componentId : components.keySet()) {
230 String componentName = components.get(componentId);
231 String localNodeTypeId =
232 createComponentDefinitionNodeTemplate(substitutionServiceTemplate, componentName);
233 createLocalNodeType(substitutionServiceTemplate, localNodeTypeId);
238 private void createSubstitutionServiceTemplateNics(ServiceTemplate substitutionServiceTemplate,
239 VspModelInfo vspModelInfo,
240 ToscaServiceModel toscaServiceModel) {
241 Map<String, List<Nic>> nics = vspModelInfo.getNics();
242 if (MapUtils.isNotEmpty(nics)) {
243 for (Map.Entry<String, List<Nic>> entry : nics.entrySet()) {
244 String componentId = entry.getKey();
245 String componentNodeTemplateId = getSubstitutionComponentNodeTemplateId(
246 vspModelInfo.getComponents().get(componentId));
247 List<Nic> nicList = entry.getValue();
248 if (CollectionUtils.isNotEmpty(nicList)) {
249 for (Nic nic : nicList) {
250 NodeTemplate nicNodeTemplate = new NodeTemplate();
251 nicNodeTemplate.setType(ToscaNodeType.NETWORK_PORT);
252 DataModelUtil.addBindingReqFromPortToCompute(componentNodeTemplateId, nicNodeTemplate);
253 DataModelUtil.addNodeTemplate(substitutionServiceTemplate,
254 getNicNodeTemplateId(nic.getName(), nic.getNetworkType()), nicNodeTemplate);
261 private String getSubstitutionComponentNodeTemplateId(String componentName) {
262 //TODO: Confirm if anything else is needed here
263 return componentName;
266 private String getNicNodeTemplateId(String nicName, NetworkType nicNetworkType) {
267 StringBuilder builder = new StringBuilder();
268 builder.append(nicName);
269 if (nicNetworkType == NetworkType.External) {
270 builder.append(GeneratorConstants.PORT_TYPE_EXTERNAL_NODE_TEMPLATE_SUFFIX);
271 } else if (nicNetworkType == NetworkType.Internal) {
272 builder.append(GeneratorConstants.PORT_TYPE_INTERNAL_NODE_TEMPLATE_SUFFIX);
274 builder.append(GeneratorConstants.PORT_NODE_TEMPLATE_ID_SUFFIX);
275 return builder.toString();
278 private String createComponentDefinitionNodeTemplate(ServiceTemplate substitutionServiceTemplate,
279 String componentName) {
280 NodeTemplate nodeTemplate = new NodeTemplate();
281 String localNodeTypeId = getLocalNodeTypeId(componentName);
282 nodeTemplate.setType(localNodeTypeId);
283 DataModelUtil.addNodeTemplate(substitutionServiceTemplate, componentName, nodeTemplate);
284 return localNodeTypeId;
287 private void createLocalNodeType(ServiceTemplate substitutionServiceTemplate,
288 String localNodeTypeId) {
289 NodeType localNodeType = new NodeType();
290 localNodeType.setDerived_from(ToscaNodeType.COMPUTE);
291 DataModelUtil.addNodeType(substitutionServiceTemplate, localNodeTypeId, localNodeType );
294 private String getLocalNodeTypeId(String componentName) {
295 return ToscaNodeType.VFC_NODE_TYPE_PREFIX + componentName;
298 private ServiceTemplate createInitSubstitutionServiceTemplate(String serviceTemplateName) {
299 ServiceTemplate substitutionServiceTemplate = new ServiceTemplate();
300 Map<String, String> templateMetadata = new HashMap<>();
301 substitutionServiceTemplate.setTosca_definitions_version(ToscaConstants
302 .TOSCA_DEFINITIONS_VERSION);
303 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, serviceTemplateName);
304 substitutionServiceTemplate.setMetadata(templateMetadata);
305 substitutionServiceTemplate.setTopology_template(new TopologyTemplate());
306 substitutionServiceTemplate.setImports(getImports());
307 return substitutionServiceTemplate;
310 private void handleSubstitutionMapping(ServiceTemplate substitutionServiceTemplate,
311 ToscaServiceModel toscaServiceModel,
312 String substitutionNodeTypeId,
313 String componentName) {
314 ServiceTemplate globalSubstitutionServiceTemplate = fetchGlobalSubstitutionServiceTemplate();
315 NodeType substitutionNodeType =
316 createGlobalSubstitutionNodeType(substitutionServiceTemplate, componentName);
317 DataModelUtil.addNodeType(globalSubstitutionServiceTemplate, substitutionNodeTypeId,
318 substitutionNodeType);
319 Map<String, Map<String, List<String>>> substitutionMapping =
320 GeneratorUtils.getSubstitutionNodeTypeExposedConnectionPoints(substitutionNodeType,
321 substitutionServiceTemplate, toscaServiceModel);
322 if (Objects.nonNull(substitutionMapping)) {
323 //add substitution mapping after capability and requirement expose calculation
324 substitutionServiceTemplate.getTopology_template().setSubstitution_mappings(
325 DataModelUtil.createSubstitutionTemplateSubMapping(substitutionNodeTypeId,
326 substitutionNodeType, substitutionMapping));
330 //*************** CREATE GLOBAL SUBSTITUTION SERVICE TEMPLATE **********************
332 private ServiceTemplate createInitGlobalSubstitutionServiceTemplate() {
333 ServiceTemplate globalSubstitutionServiceTemplate = new ServiceTemplate();
334 Map<String, String> templateMetadata = new HashMap<>();
335 globalSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants
336 .TOSCA_DEFINITIONS_VERSION);
337 templateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME,
338 Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
339 globalSubstitutionServiceTemplate.setMetadata(templateMetadata);
340 globalSubstitutionServiceTemplate.setImports(getImports());
341 return globalSubstitutionServiceTemplate;
344 private NodeType createGlobalSubstitutionNodeType(ServiceTemplate substitutionServiceTemplate,
345 String componentName) {
346 NodeType substitutionNodeType = new ToscaAnalyzerServiceImpl()
347 .createInitSubstitutionNodeType(substitutionServiceTemplate,
348 ToscaNodeType.MULTIFLAVOR_VFC_NODE_TYPE);
349 substitutionNodeType.setProperties(
350 getManualVspSubstitutionNodeTypeProperties(substitutionNodeType, componentName));
351 return substitutionNodeType;
354 private Map<String, PropertyDefinition> getManualVspSubstitutionNodeTypeProperties(
355 NodeType substitutionNodeType, String componentName) {
356 //Create num_cpus property
357 PropertyDefinition numCpus = new PropertyDefinition();
358 numCpus.setType(PropertyType.INTEGER.getDisplayName());
359 numCpus.setDescription(GeneratorConstants.NUM_CPUS_PROP_DESC_PREFIX + componentName);
360 numCpus.setRequired(true);
361 //Create disk_size property
362 PropertyDefinition diskSize = new PropertyDefinition();
363 diskSize.setType(PropertyType.SCALAR_UNIT_SIZE.getDisplayName());
364 diskSize.setDescription(GeneratorConstants.DISK_SIZE_PROP_DESC_PREFIX + componentName);
365 diskSize.setRequired(true);
366 //Create mem_size property
367 PropertyDefinition memSize = new PropertyDefinition();
368 memSize.setType(PropertyType.SCALAR_UNIT_SIZE.getDisplayName());
369 memSize.setDescription(GeneratorConstants.MEM_SIZE_PROP_DESC_PREFIX + componentName);
370 memSize.setRequired(true);
372 Map<String, PropertyDefinition> manualVspProperties = new LinkedHashMap<>();
373 manualVspProperties.put(GeneratorConstants.NUM_CPUS, numCpus);
374 manualVspProperties.put(GeneratorConstants.DISK_SIZE, diskSize);
375 manualVspProperties.put(GeneratorConstants.MEM_SIZE, memSize);
377 return manualVspProperties;
380 private String getSubstitutionNodeTypeId(String componentName) {
381 return ToscaNodeType.MULTIDEPLOYMENTFLAVOR_NODE_TYPE + "." + componentName;
385 * Fetch global substitution service template service template.
387 * @return the global substitution service template
389 private ServiceTemplate fetchGlobalSubstitutionServiceTemplate() {
390 ServiceTemplate globalSubstitutionServiceTemplate =
391 generatedServiceTemplates.get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
392 if (Objects.isNull(globalSubstitutionServiceTemplate)) {
393 globalSubstitutionServiceTemplate = createInitGlobalSubstitutionServiceTemplate();
394 generatedServiceTemplates.put(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME,
395 globalSubstitutionServiceTemplate);
397 return globalSubstitutionServiceTemplate;