2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation;
23 import org.openecomp.sdc.common.errors.CoreException;
24 import org.openecomp.sdc.heat.datatypes.HeatBoolean;
25 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
26 import org.openecomp.sdc.heat.datatypes.model.Resource;
27 import org.openecomp.sdc.heat.services.HeatConstants;
28 import org.openecomp.sdc.logging.api.Logger;
29 import org.openecomp.sdc.logging.api.LoggerFactory;
30 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
31 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
32 import org.openecomp.sdc.tosca.datatypes.ToscaGroupType;
33 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
34 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
35 import org.openecomp.sdc.tosca.datatypes.model.AttributeDefinition;
36 import org.openecomp.sdc.tosca.datatypes.model.GroupDefinition;
37 import org.openecomp.sdc.tosca.datatypes.model.Import;
38 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
39 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
40 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
41 import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition;
42 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
43 import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition;
44 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
45 import org.openecomp.sdc.tosca.datatypes.model.SubstitutionMapping;
46 import org.openecomp.sdc.tosca.datatypes.model.TopologyTemplate;
47 import org.openecomp.sdc.tosca.services.DataModelUtil;
48 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
49 import org.openecomp.sdc.tosca.services.ToscaConstants;
50 import org.openecomp.sdc.tosca.services.ToscaUtil;
51 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
52 import org.openecomp.sdc.tosca.services.impl.ToscaFileOutputServiceCsarImpl;
53 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
54 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
55 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslatedHeatResource;
56 import org.openecomp.sdc.translator.services.heattotosca.Constants;
57 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
58 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
59 import org.openecomp.sdc.translator.services.heattotosca.errors.MissingMandatoryPropertyErrorBuilder;
60 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
61 import org.openecomp.sdc.translator.services.heattotosca.helper.ContrailTranslationHelper;
62 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
64 import java.util.ArrayList;
65 import java.util.Arrays;
66 import java.util.HashMap;
67 import java.util.List;
69 import java.util.Objects;
70 import java.util.Optional;
72 public class ResourceTranslationContrailServiceInstanceImpl extends ResourceTranslationBase {
74 protected static Logger logger = LoggerFactory.getLogger(ResourceTranslationContrailServiceInstanceImpl.class);
77 public void translate(TranslateTo translateTo) {
78 Resource serviceInstanceResource = translateTo.getResource();
79 AttachedResourceId contrailServiceTemplateAttached =
80 getServiceTemplateAttachedId(translateTo, serviceInstanceResource);
81 if (contrailServiceTemplateAttached.isGetResource()) {
82 String contrailServiceTemplateResourceId =
83 (String) contrailServiceTemplateAttached.getEntityId();
84 Resource contrailServiceTemplateResource = HeatToToscaUtil
85 .getResource(translateTo.getHeatOrchestrationTemplate(),
86 contrailServiceTemplateResourceId, translateTo.getHeatFileName());
87 if (!contrailServiceTemplateResource.getType()
88 .equals(HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource())) {
89 logger.warn("resource id '" + translateTo.getResourceId() + "' with type '"
90 + translateTo.getResource().getType()
91 + "+ has reference to resource '" + contrailServiceTemplateResourceId + "' with type '"
92 + contrailServiceTemplateResource.getType()
93 + "' in property service_template. Invalid type, resource type should be type of '"
94 + HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource()
95 + "', therefore this resource will be ignored in TOSCA translation.");
98 Optional<String> contrailServiceTemplateTranslatedId =
99 ResourceTranslationFactory.getInstance(contrailServiceTemplateResource)
100 .translateResource(translateTo.getHeatFileName(), translateTo.getServiceTemplate(),
101 translateTo.getHeatOrchestrationTemplate(), contrailServiceTemplateResource,
102 contrailServiceTemplateResourceId, translateTo.getContext());
103 if (!contrailServiceTemplateTranslatedId.isPresent()) {
104 logger.warn("Resource id '" + translateTo.getResourceId() + "' with type '"
105 + translateTo.getResource().getType()
106 + "' has reference to unsupported resource '" + contrailServiceTemplateResourceId
107 + "' with type '" + contrailServiceTemplateResource.getType()
108 + "' in property 'service_template'"
109 + ", therefore this resource will be ignored in TOSCA translation.");
113 ServiceTemplate globalSubstitutionServiceTemplate =
114 translateTo.getContext().getTranslatedServiceTemplates().get(
115 Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
116 String contrailStId = ResourceTranslationContrailServiceTemplateImpl
117 .getContrailSubstitutedNodeTypeId(contrailServiceTemplateTranslatedId.get());
118 NodeType substitutedNodeType =
119 DataModelUtil.getNodeType(globalSubstitutionServiceTemplate, contrailStId);
121 int numberOfPorts = getServiceInstanceNumberOfPorts(serviceInstanceResource);
122 if (substitutedNodeType.getRequirements() != null
123 && substitutedNodeType.getRequirements().size() != numberOfPorts) {
124 logger.warn("More than one ServiceInstance pointing to the same ServiceTemplate '"
125 + contrailServiceTemplateResourceId + " ' with different number of interfaces."
126 + ", therefore this resource will be ignored in TOSCA translation.");
130 addNetworkLinkRequirements(substitutedNodeType, numberOfPorts);
131 NodeTemplate substitutedNodeTemplate =
132 createSubstitutedNodeTemplate(translateTo, contrailServiceTemplateResource, contrailStId,
135 String computeNodeTypeId = new ContrailTranslationHelper()
136 .getComputeNodeTypeId(contrailServiceTemplateResource, contrailServiceTemplateResourceId,
137 contrailServiceTemplateTranslatedId.get(), translateTo.getContext());
138 boolean orderedInterfaces = getOrderedInterfaces(contrailServiceTemplateResource);
139 ServiceTemplate nestedServiceTemplate =
140 createNestedServiceTemplate(translateTo, computeNodeTypeId, contrailStId,
141 substitutedNodeTemplate, orderedInterfaces);
142 addAbstractSubstitutionProperty(translateTo, substitutedNodeTemplate.getProperties(),
143 nestedServiceTemplate, contrailServiceTemplateResource);
144 translateTo.getContext().getTranslatedServiceTemplates().put(new ContrailTranslationHelper()
145 .getSubstitutionContrailServiceTemplateMetadata(translateTo.getHeatFileName(),
146 translateTo.getTranslatedId()), nestedServiceTemplate);
149 logger.warn("Heat resource: '" + translateTo.getResourceId() + "' with type: '"
150 + translateTo.getResource().getType()
151 + "' include 'service_template' property without 'get_resource' function, currently not"
152 + " supported, therefore this resource will be ignored in TOSCA translation.");
156 private void addAbstractSubstitutionProperty(TranslateTo translateTo,
157 Map<String, Object> substitutionProperties,
158 ServiceTemplate nestedServiceTemplate,
159 Resource contrailServiceTemplateResource) {
160 Map<String, Object> innerProps = new HashMap<>();
161 innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME,
162 ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate));
164 Object countValue = handleScaleOutProperty(translateTo, innerProps);
165 handleServiceScalingProperty(translateTo, innerProps, contrailServiceTemplateResource);
167 boolean mandatory = false;
168 if (countValue instanceof Integer && (Integer) countValue > 0) {
171 if (countValue == null) {
174 innerProps.put("mandatory", mandatory);
175 substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
178 private Object handleScaleOutProperty(TranslateTo translateTo, Map<String, Object> innerProps) {
179 Object scaleOutPropertyValue =
180 translateTo.getResource().getProperties().get(HeatConstants.SCALE_OUT_PROPERTY_NAME);
181 Object countValue = null;
182 if (scaleOutPropertyValue != null && scaleOutPropertyValue instanceof Map) {
183 countValue = TranslatorHeatToToscaPropertyConverter
184 .getToscaPropertyValue(translateTo.getServiceTemplate(), translateTo.getTranslatedId(),
185 Constants.MAX_INSTANCES_PROPERTY_NAME,
186 ((Map) scaleOutPropertyValue).get(Constants.MAX_INSTANCES_PROPERTY_NAME), null,
187 translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(), null,
188 translateTo.getContext());
189 if (countValue != null) {
190 innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, countValue);
192 innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
195 innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
200 private void handleServiceScalingProperty(TranslateTo translateTo, Map<String, Object> innerProps,
201 Resource contrailServiceTemplateResource) {
202 Object serviceScalingPropertyValue = contrailServiceTemplateResource.getProperties()
203 .get(HeatConstants.SERVICE_SCALING_PROPERTY_NAME);
204 Object serviceScalingValue;
205 if (serviceScalingPropertyValue != null) {
206 serviceScalingValue = TranslatorHeatToToscaPropertyConverter
207 .getToscaPropertyValue(translateTo.getServiceTemplate(), translateTo.getTranslatedId(),
208 HeatConstants.SERVICE_SCALING_PROPERTY_NAME, serviceScalingPropertyValue, null,
209 translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(), null,
210 translateTo.getContext());
211 if (serviceScalingValue != null) {
212 innerProps.put(ToscaConstants.SCALING_ENABLED_PROPERTY_NAME,
213 (HeatBoolean.isValueBoolean(serviceScalingValue)) ? HeatBoolean
214 .eval(serviceScalingValue) : serviceScalingValue);
219 private boolean getOrderedInterfaces(Resource contrailServiceTemplate) {
220 Object orderedInterfaces = contrailServiceTemplate.getProperties().get("ordered_interfaces");
221 if (orderedInterfaces == null) {
224 if (orderedInterfaces instanceof String) {
225 return HeatBoolean.eval(orderedInterfaces);
227 //if get_param, set default value to true
231 private ServiceTemplate createNestedServiceTemplate(TranslateTo translateTo,
232 String computeNodeTypeId,
233 String substitutedNodeTypeId,
234 NodeTemplate substitutedNodeTemplate,
235 boolean orderedInterfaces) {
236 ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
237 setNestedServiceTemplateGeneralDetails(translateTo, nestedSubstitutionServiceTemplate);
238 String heatStackGroupKey = addHeatStackGroup(translateTo, nestedSubstitutionServiceTemplate);
239 addSubstitutionMappingEntry(nestedSubstitutionServiceTemplate, substitutedNodeTypeId);
241 handleInputParameters(nestedSubstitutionServiceTemplate, translateTo);
242 String computeNodeTemplateId =
243 handleComputeNodeTemplate(translateTo, computeNodeTypeId, nestedSubstitutionServiceTemplate,
245 handleOutputParameters(nestedSubstitutionServiceTemplate, computeNodeTemplateId, translateTo);
246 handleServiceInstanceInterfaces(translateTo, nestedSubstitutionServiceTemplate,
247 substitutedNodeTemplate, heatStackGroupKey, orderedInterfaces, computeNodeTemplateId);
248 return nestedSubstitutionServiceTemplate;
251 private void handleOutputParameters(ServiceTemplate nestedSubstitutionServiceTemplate,
252 String nodeTemplateId, TranslateTo translateTo) {
253 if (nodeTemplateId == null) {
256 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
258 Optional<NodeType> contrailAbstractNodeType =
259 toscaAnalyzerService.fetchNodeType(ToscaNodeType.CONTRAIL_ABSTRACT_SUBSTITUTE, translateTo
260 .getContext().getGlobalServiceTemplates().values());
262 if (!contrailAbstractNodeType.isPresent()) {
265 Map<String, AttributeDefinition> contrailAbstractAttributes =
266 contrailAbstractNodeType.get().getAttributes();
267 Map<String, ParameterDefinition> nestedSubstitutionServiceTemplateOutputs = new HashMap<>();
269 if (contrailAbstractAttributes == null) {
273 for (String attributeKey : contrailAbstractAttributes.keySet()) {
274 AttributeDefinition abstractAttributeDef = contrailAbstractAttributes.get(attributeKey);
275 if (abstractAttributeDef != null) {
276 Map<String, List> outputValue = new HashMap<>();
277 List outputGetAttributeList = new ArrayList<>();
278 outputGetAttributeList.add(nodeTemplateId);
279 outputGetAttributeList.add(attributeKey);
280 outputValue.put(ToscaFunctions.GET_ATTRIBUTE.getDisplayName(), outputGetAttributeList);
281 nestedSubstitutionServiceTemplateOutputs.put(attributeKey,
282 DataModelUtil.convertAttributeDefToParameterDef(abstractAttributeDef, outputValue));
285 if (!nestedSubstitutionServiceTemplateOutputs.isEmpty()) {
286 nestedSubstitutionServiceTemplate.getTopology_template()
287 .setOutputs(nestedSubstitutionServiceTemplateOutputs);
291 private void handleServiceInstanceInterfaces(TranslateTo translateTo,
292 ServiceTemplate nestedSubstitutionServiceTemplate,
293 NodeTemplate substitutedNodeTemplate,
294 String heatStackGroupKey, boolean orderedInterfaces,
295 String computeNodeTemplateId) {
296 Resource serviceInstanceResource = translateTo.getResource();
297 Object interfaceListProperty =
298 serviceInstanceResource.getProperties().get(HeatConstants.INTERFACE_LIST_PROPERTY_NAME);
299 if (interfaceListProperty == null) {
302 if (interfaceListProperty instanceof List) {
303 for (int index = 0; index < ((List) interfaceListProperty).size(); index++) {
304 Object interfaceEntry = ((List) interfaceListProperty).get(index);
305 handleInterface(translateTo, interfaceEntry, index, nestedSubstitutionServiceTemplate,
306 heatStackGroupKey, substitutedNodeTemplate, orderedInterfaces, computeNodeTemplateId);
308 } else if (interfaceListProperty instanceof Map) {
309 handleInterface(translateTo, interfaceListProperty, null, nestedSubstitutionServiceTemplate,
310 heatStackGroupKey, substitutedNodeTemplate, orderedInterfaces, computeNodeTemplateId);
314 private void handleInterface(TranslateTo translateTo, Object interfacePropertyValue,
316 ServiceTemplate nestedSubstitutionServiceTemplate,
317 String heatStackGroupKey, NodeTemplate substitutedNodeTemplate,
318 boolean orderedInterfaces, String computeNodeTemplateId) {
322 NodeTemplate portNodeTemplate =
323 createPortNodeTemplate(index, orderedInterfaces, computeNodeTemplateId);
324 String portNodeTemplateId = Constants.SERVICE_INSTANCE_PORT_PREFIX + index;
325 String portReqMappingKey = Constants.SERVICE_INSTANCE_LINK_PREFIX + portNodeTemplateId;
328 .addNodeTemplate(nestedSubstitutionServiceTemplate, portNodeTemplateId, portNodeTemplate);
329 updateSubstitutionMappingRequirement(nestedSubstitutionServiceTemplate, portReqMappingKey,
331 updateHeatStackGroup(nestedSubstitutionServiceTemplate, heatStackGroupKey, portNodeTemplateId);
332 connectPortToNetwork(translateTo, interfacePropertyValue, substitutedNodeTemplate,
336 private void connectPortToNetwork(TranslateTo translateTo, Object interfacePropertyValue,
337 NodeTemplate substitutedNodeTemplate,
338 String portReqMappingKey) {
339 List<String> validNetworksForConnections = Arrays
340 .asList(HeatResourcesTypes.NEUTRON_NET_RESOURCE_TYPE.getHeatResource(),
341 HeatResourcesTypes.CONTRAIL_VIRTUAL_NETWORK_RESOURCE_TYPE.getHeatResource());
343 if (interfacePropertyValue instanceof Map) {
344 Object virtualNetworkValue =
345 ((Map) interfacePropertyValue).get(HeatConstants.VIRTUAL_NETWORK_PROPERTY_NAME);
346 if (virtualNetworkValue != null) {
347 Optional<AttachedResourceId> networkAttachedResourceId = HeatToToscaUtil
348 .extractAttachedResourceId(translateTo.getHeatFileName(),
349 translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(),
350 virtualNetworkValue);
351 if (networkAttachedResourceId.isPresent()) {
352 Optional<String> networkResourceId =
353 HeatToToscaUtil.getContrailAttachedHeatResourceId(networkAttachedResourceId.get());
354 if (networkResourceId.isPresent()) {
355 Resource networkResource = HeatToToscaUtil
356 .getResource(translateTo.getHeatOrchestrationTemplate(), networkResourceId.get(),
357 translateTo.getHeatFileName());
358 if (validNetworksForConnections.contains(networkResource.getType())) {
359 Optional<String> networkTranslatedId =
360 getResourceTranslatedId(translateTo.getHeatFileName(),
361 translateTo.getHeatOrchestrationTemplate(), networkResourceId.get(),
362 translateTo.getContext());
365 translatedId -> addLinkToNetworkRequirementAssignment(substitutedNodeTemplate,
366 translatedId, portReqMappingKey));
369 logger.warn("Heat resource " + translateTo.getResourceId() + " with type "
370 + translateTo.getResource().getType()
371 + " has connection to invalid/not supported network resource, therefore, this "
372 + "connection will be ignored in the translation.");
374 } else if (networkAttachedResourceId.get().isGetParam()
375 && networkAttachedResourceId.get().getEntityId() instanceof String) {
376 TranslatedHeatResource
377 translatedSharedResourceId =
378 translateTo.getContext().getHeatSharedResourcesByParam()
379 .get(networkAttachedResourceId.get().getEntityId());
380 if (Objects.nonNull(translatedSharedResourceId)
381 && !HeatToToscaUtil.isHeatFileNested(translateTo, translateTo.getHeatFileName())) {
382 addLinkToNetworkRequirementAssignment(substitutedNodeTemplate,
383 translatedSharedResourceId.getTranslatedId(), portReqMappingKey);
386 logger.warn("Heat resource: '" + translateTo.getResourceId() + "' with type: '"
387 + translateTo.getResource().getType()
388 + "' include 'virtual_network' property with value '"
389 + virtualNetworkValue.toString()
390 + "', the connection to this network wasn't found/not supported therefore this "
391 + "connection will be ignored in TOSCA translation for this property.");
395 logger.warn("Heat resource: '" + translateTo.getResourceId() + "' with type: '"
396 + translateTo.getResource().getType()
397 + "' missing 'virtual_network' property in 'interface_list' entry, therefore, no "
398 + "network connection is define for this entry.");
403 private NodeTemplate createPortNodeTemplate(Integer index, boolean orderedInterfaces,
404 String computeNodeTemplateId) {
405 NodeTemplate portNodeTemplate = new NodeTemplate();
406 portNodeTemplate.setType(ToscaNodeType.CONTRAIL_PORT);
407 Map<String, Object> portProperties = new HashMap<>();
408 portProperties.put("static_routes", DataModelUtil
409 .createGetInputPropertyValueFromListParameter("interface_list", index, "static_routes"));
410 portProperties.put("virtual_network", DataModelUtil
411 .createGetInputPropertyValueFromListParameter("interface_list", index, "virtual_network"));
412 portProperties.put("allowed_address_pairs", DataModelUtil
413 .createGetInputPropertyValueFromListParameter("interface_list", index,
414 "allowed_address_pairs"));
415 portProperties.put("ip_address", DataModelUtil
416 .createGetInputPropertyValueFromListParameter("interface_list", index, "ip_address"));
417 portProperties.put("static_route",
418 DataModelUtil.createGetInputPropertyValueFromListParameter("static_routes_list", index));
419 portProperties.put("shared_ip",
420 DataModelUtil.createGetInputPropertyValueFromListParameter("shared_ip_list", index));
421 portProperties.put("interface_type", DataModelUtil
422 .createGetInputPropertyValueFromListParameter("service_interface_type_list", index));
423 if (orderedInterfaces) {
424 portProperties.put("order", index);
426 portNodeTemplate.setProperties(portProperties);
427 DataModelUtil.addBindingReqFromPortToCompute(computeNodeTemplateId, portNodeTemplate);
428 return portNodeTemplate;
432 private void addLinkToNetworkRequirementAssignment(NodeTemplate nodeTemplate,
433 String connectedNodeTranslatedId,
434 String requirementId) {
435 if (nodeTemplate == null || connectedNodeTranslatedId == null) {
439 RequirementAssignment requirement = new RequirementAssignment();
440 requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE);
441 requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_LINK_TO);
442 requirement.setNode(connectedNodeTranslatedId);
443 DataModelUtil.addRequirementAssignment(nodeTemplate, requirementId, requirement);
446 private void updateHeatStackGroup(ServiceTemplate serviceTemplate, String heatStackGroupKey,
448 serviceTemplate.getTopology_template().getGroups().get(heatStackGroupKey).getMembers()
452 private void updateSubstitutionMappingRequirement(ServiceTemplate serviceTemplate,
453 String portReqMappingKey,
454 String portNodeTemplateId) {
455 List<String> portReqMappingValue = new ArrayList<>();
456 portReqMappingValue.add(portNodeTemplateId);
457 portReqMappingValue.add(ToscaConstants.LINK_REQUIREMENT_ID);
459 .addSubstitutionMappingReq(serviceTemplate, portReqMappingKey, portReqMappingValue);
462 private void addSubstitutionMappingEntry(ServiceTemplate nestedSubstitutionServiceTemplate,
463 String substitutedNodeTypeId) {
464 SubstitutionMapping substitutionMappings = new SubstitutionMapping();
465 substitutionMappings.setNode_type(substitutedNodeTypeId);
466 DataModelUtil.addSubstitutionMapping(nestedSubstitutionServiceTemplate, substitutionMappings);
469 private void handleInputParameters(ServiceTemplate nestedSubstitutionServiceTemplate,
470 TranslateTo translateTo) {
471 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
473 Optional<NodeType> contrailAbstractNodeType =
474 toscaAnalyzerService.fetchNodeType(ToscaNodeType.CONTRAIL_ABSTRACT_SUBSTITUTE, translateTo
475 .getContext().getGlobalServiceTemplates().values());
476 Map<String, ParameterDefinition> nestedSubstitutionServiceTemplateInputs = new HashMap<>();
477 if (contrailAbstractNodeType.isPresent()) {
478 Map<String, PropertyDefinition> contrailAbstractProperties =
479 contrailAbstractNodeType.get().getProperties();
481 for (String propertyKey : contrailAbstractProperties.keySet()) {
482 PropertyDefinition abstractPropertyDef = contrailAbstractProperties.get(propertyKey);
483 if (abstractPropertyDef != null) {
484 nestedSubstitutionServiceTemplateInputs
486 DataModelUtil.convertPropertyDefToParameterDef(abstractPropertyDef));
491 if (!nestedSubstitutionServiceTemplateInputs.isEmpty()) {
492 nestedSubstitutionServiceTemplate.getTopology_template()
493 .setInputs(nestedSubstitutionServiceTemplateInputs);
497 private String handleComputeNodeTemplate(TranslateTo translateTo, String computeNodeTypeId,
498 ServiceTemplate nestedSubstitutionServiceTemplate,
499 String heatStackGroupKey) {
500 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
501 Optional<NodeType> contrailComputeNodeType = toscaAnalyzerService
502 .fetchNodeType(ToscaNodeType.CONTRAIL_COMPUTE,
503 translateTo.getContext().getGlobalServiceTemplates().values());
505 Map<String, Object> computeNodeTemplateProperties = null;
506 if (contrailComputeNodeType.isPresent()) {
507 Map<String, PropertyDefinition> contrailComputeProperties =
508 contrailComputeNodeType.get().getProperties();
509 computeNodeTemplateProperties = new HashMap<>();
511 if (contrailComputeProperties != null) {
512 for (String computePropertyKey : contrailComputeProperties.keySet()) {
513 Map getInputProperty = new HashMap<>();
514 getInputProperty.put(ToscaFunctions.GET_INPUT.getDisplayName(), computePropertyKey);
515 computeNodeTemplateProperties.put(computePropertyKey, getInputProperty);
520 NodeTemplate computeNodeTemplate = new NodeTemplate();
521 computeNodeTemplate.setType(computeNodeTypeId);
522 if (computeNodeTemplateProperties != null && !computeNodeTemplateProperties.isEmpty()) {
523 computeNodeTemplate.setProperties(computeNodeTemplateProperties);
525 String computeNodeTemplateId = translateTo.getTranslatedId();
526 DataModelUtil.addNodeTemplate(nestedSubstitutionServiceTemplate, computeNodeTemplateId,
527 computeNodeTemplate);
528 nestedSubstitutionServiceTemplate.getTopology_template().getGroups().get(heatStackGroupKey)
529 .getMembers().add(computeNodeTemplateId);
530 return computeNodeTemplateId;
533 private String addHeatStackGroup(TranslateTo translateTo, ServiceTemplate serviceTemplate) {
534 GroupDefinition serviceInstanceGroupDefinition = new GroupDefinition();
535 serviceInstanceGroupDefinition.setType(ToscaGroupType.HEAT_STACK);
536 Map<String, Object> groupProperties = new HashMap<>();
537 groupProperties.put("heat_file",
538 "../" + (new ToscaFileOutputServiceCsarImpl()).getArtifactsFolderName() + "/"
539 + translateTo.getHeatFileName());
540 serviceInstanceGroupDefinition.setProperties(groupProperties);
541 serviceInstanceGroupDefinition.setMembers(new ArrayList<>());
542 String heatStackGroupKey = translateTo.getTranslatedId() + "_group";
543 DataModelUtil.addGroupDefinitionToTopologyTemplate(serviceTemplate, heatStackGroupKey,
544 serviceInstanceGroupDefinition);
545 return heatStackGroupKey;
549 private void setNestedServiceTemplateGeneralDetails(TranslateTo translateTo,
551 nestedSubstitutionServiceTemplate) {
552 Map<String, String> nestedTemplateMetadata = new HashMap<>();
553 String nestedTemplateName = new ContrailTranslationHelper()
554 .getSubstitutionContrailServiceTemplateMetadata(translateTo.getHeatFileName(),
555 translateTo.getResourceId());
556 nestedTemplateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, nestedTemplateName);
557 nestedSubstitutionServiceTemplate.setMetadata(nestedTemplateMetadata);
558 nestedSubstitutionServiceTemplate
559 .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
560 nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
561 List<Map<String, Import>> globalTypesImportList =
562 GlobalTypesGenerator.getGlobalTypesImportList();
563 globalTypesImportList.addAll(
564 HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
565 nestedSubstitutionServiceTemplate.setImports(globalTypesImportList);
568 private NodeTemplate createSubstitutedNodeTemplate(TranslateTo translateTo,
569 Resource contrailServiceTemplateResource,
570 String contrailServiceTemplateTranslatedId,
572 boolean isImportAddedToServiceTemplate =
574 .isImportAddedToServiceTemplate(translateTo.getServiceTemplate().getImports(), Constants
575 .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
576 if (!isImportAddedToServiceTemplate) {
577 translateTo.getServiceTemplate().getImports()
578 .addAll(HeatToToscaUtil
579 .createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
581 NodeTemplate substitutesNodeTemplate = new NodeTemplate();
582 substitutesNodeTemplate.setType(contrailServiceTemplateTranslatedId);
583 List<String> directiveList = new ArrayList<>();
584 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
585 substitutesNodeTemplate.setDirectives(directiveList);
586 substitutesNodeTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
587 .getToscaPropertiesSimpleConversion(translateTo.getServiceTemplate(), translateTo.
588 getResourceId(), translateTo.getResource().getProperties(),
589 substitutesNodeTemplate.getProperties(), translateTo.getHeatFileName(),
590 translateTo.getHeatOrchestrationTemplate(),
591 HeatResourcesTypes.CONTRAIL_SERVICE_INSTANCE.getHeatResource(), substitutesNodeTemplate,
592 translateTo.getContext()));
593 substitutesNodeTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
594 .getToscaPropertiesSimpleConversion(translateTo.getServiceTemplate(), translateTo.
595 getResourceId(), contrailServiceTemplateResource.getProperties(),
596 substitutesNodeTemplate.getProperties(), translateTo.getHeatFileName(),
597 translateTo.getHeatOrchestrationTemplate(),
598 HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource(), substitutesNodeTemplate,
599 translateTo.getContext()));
600 HeatToToscaUtil.mapBoolean(substitutesNodeTemplate, HeatToToscaUtil
601 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
602 HeatConstants.AVAILABILITY_ZONE_ENABLE_PROPERTY_NAME));
603 HeatToToscaUtil.mapBoolean(substitutesNodeTemplate, HeatToToscaUtil
604 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
605 HeatConstants.ORDERED_INTERFACES_PROPERTY_NAME));
607 Object sharedIpListPropertyValue =
608 contrailServiceTemplateResource.getProperties()
609 .get(HeatConstants.SHARED_IP_LIST_PROPERTY_NAME);
610 String toscaSharedIpListPropertyName = HeatToToscaUtil
611 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
612 HeatConstants.SHARED_IP_LIST_PROPERTY_NAME);
613 Optional<List<Map<String, List>>> sharedIpTranslatedSplitFun =
614 new ContrailTranslationHelper()
615 .translateFnSplitFunction(sharedIpListPropertyValue, numberOfPorts, true);
616 if (sharedIpTranslatedSplitFun.isPresent()) {
617 substitutesNodeTemplate.getProperties()
618 .put(toscaSharedIpListPropertyName, sharedIpTranslatedSplitFun.get());
620 HeatToToscaUtil.mapBooleanList(substitutesNodeTemplate, toscaSharedIpListPropertyName);
623 Object staticRouteListPropertyValue =
624 contrailServiceTemplateResource.getProperties()
625 .get(HeatConstants.STATIC_ROUTES_LIST_PROPERTY_NAME);
626 String toscaStaticRoutesListPropertyName = HeatToToscaUtil
627 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
628 HeatConstants.STATIC_ROUTES_LIST_PROPERTY_NAME);
629 Optional<List<Map<String, List>>> staticRouteTranslatedSplitFun =
630 new ContrailTranslationHelper()
631 .translateFnSplitFunction(staticRouteListPropertyValue, numberOfPorts, true);
632 if (staticRouteTranslatedSplitFun.isPresent()) {
633 substitutesNodeTemplate.getProperties()
634 .put(toscaStaticRoutesListPropertyName, staticRouteTranslatedSplitFun.get());
636 HeatToToscaUtil.mapBooleanList(substitutesNodeTemplate, toscaStaticRoutesListPropertyName);
639 Object serviceInterfaceTypeListPropertyValue =
640 contrailServiceTemplateResource.getProperties()
641 .get(HeatConstants.SERVICE_INTERFCAE_TYPE_LIST_PROPERTY_NAME);
642 String toscaServiceInterfaceTypeListPropertyName = HeatToToscaUtil
643 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
644 HeatConstants.SERVICE_INTERFCAE_TYPE_LIST_PROPERTY_NAME);
645 Optional<List<Map<String, List>>> serviceInterfaceTypeTranslatedSplitFun =
646 new ContrailTranslationHelper()
647 .translateFnSplitFunction(serviceInterfaceTypeListPropertyValue, numberOfPorts, false);
648 serviceInterfaceTypeTranslatedSplitFun
649 .ifPresent(translatedSplitFun -> substitutesNodeTemplate.getProperties()
650 .put(toscaServiceInterfaceTypeListPropertyName, translatedSplitFun));
652 String substitutedNodeTemplateId = translateTo.getTranslatedId();
653 DataModelUtil.addNodeTemplate(translateTo.getServiceTemplate(), substitutedNodeTemplateId,
654 substitutesNodeTemplate);
655 return substitutesNodeTemplate;
658 private void addNetworkLinkRequirements(NodeType nodeType, int numberOfPorts) {
659 if (nodeType.getRequirements() == null) {
660 List<Map<String, RequirementDefinition>> requirementList = new ArrayList<>();
661 for (int i = 0; i < numberOfPorts; i++) {
662 Map<String, RequirementDefinition> requirementDefinitionMap = new HashMap<>();
663 requirementDefinitionMap.put(ToscaConstants.LINK_REQUIREMENT_ID + "_port_" + i,
664 DataModelUtil.createRequirement(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE,
665 ToscaNodeType.NATIVE_ROOT,
666 ToscaRelationshipType.NATIVE_NETWORK_LINK_TO, null));
667 requirementList.add(requirementDefinitionMap);
669 if (numberOfPorts > 0) {
670 nodeType.setRequirements(requirementList);
675 private int getServiceInstanceNumberOfPorts(Resource serviceInstanceResource) {
677 Object interfaceTypeProperty =
678 serviceInstanceResource.getProperties().get(HeatConstants.INTERFACE_LIST_PROPERTY_NAME);
679 if (interfaceTypeProperty == null) {
681 } else if (interfaceTypeProperty instanceof List) {
682 numberOfPorts = ((List) interfaceTypeProperty).size();
683 } else if (interfaceTypeProperty instanceof Map) {
688 return numberOfPorts;
691 private AttachedResourceId getServiceTemplateAttachedId(TranslateTo translateTo,
692 Resource serviceInstanceResource) {
693 Object serviceTemplateProperty =
694 serviceInstanceResource.getProperties().get("service_template");
695 Optional<AttachedResourceId> serviceTemplateId = HeatToToscaUtil
696 .extractAttachedResourceId(translateTo.getHeatFileName(),
697 translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(),
698 serviceTemplateProperty);
699 if (serviceTemplateId.isPresent()) {
700 return serviceTemplateId.get();
702 throw new CoreException(new MissingMandatoryPropertyErrorBuilder("service_template").build());