2 * Copyright © 2016-2018 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.translator.services.heattotosca.impl.resourcetranslation;
19 import static org.openecomp.sdc.tosca.services.ToscaConstants.MANDATORY_PROPERTY_NAME;
20 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_INVALID_NETWORK_CONNECTION;
21 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_MISSING_VIRTUAL_NETWORK_INTERFACE_LIST;
22 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_MULTIPLE_SERVICE_INSTANCE_DIFF_INTERFACES;
23 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_SERVICE_TEMPLATE_PROPERTY_GET_RESOURCE;
24 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_SERVICE_TEMPLATE_PROPERTY_INVALID_TYPE;
25 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_SERVICE_TEMPLATE_PROPERTY_UNSUPPORTED_RESOURCE;
26 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_UNSUPPORTED_NETWORK_RESOURCE_CONNECTION;
28 import java.util.ArrayList;
29 import java.util.Arrays;
30 import java.util.HashMap;
31 import java.util.List;
33 import java.util.Objects;
34 import java.util.Optional;
36 import org.onap.sdc.tosca.datatypes.model.AttributeDefinition;
37 import org.onap.sdc.tosca.datatypes.model.GroupDefinition;
38 import org.onap.sdc.tosca.datatypes.model.Import;
39 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
40 import org.onap.sdc.tosca.datatypes.model.NodeType;
41 import org.onap.sdc.tosca.datatypes.model.ParameterDefinition;
42 import org.onap.sdc.tosca.datatypes.model.PropertyDefinition;
43 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
44 import org.onap.sdc.tosca.datatypes.model.RequirementDefinition;
45 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
46 import org.onap.sdc.tosca.datatypes.model.SubstitutionMapping;
47 import org.onap.sdc.tosca.datatypes.model.TopologyTemplate;
48 import org.openecomp.sdc.common.errors.CoreException;
49 import org.openecomp.sdc.heat.datatypes.HeatBoolean;
50 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
51 import org.openecomp.sdc.heat.datatypes.model.Resource;
52 import org.openecomp.sdc.heat.services.HeatConstants;
53 import org.openecomp.sdc.logging.api.Logger;
54 import org.openecomp.sdc.logging.api.LoggerFactory;
55 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
56 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
57 import org.openecomp.sdc.tosca.datatypes.ToscaGroupType;
58 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
59 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
60 import org.openecomp.sdc.tosca.services.DataModelUtil;
61 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
62 import org.openecomp.sdc.tosca.services.ToscaConstants;
63 import org.openecomp.sdc.tosca.services.ToscaUtil;
64 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
65 import org.openecomp.sdc.tosca.services.impl.ToscaFileOutputServiceCsarImpl;
66 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
67 import org.openecomp.sdc.translator.datatypes.heattotosca.to.ContrailServiceInstanceTo;
68 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
69 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslatedHeatResource;
70 import org.openecomp.sdc.translator.services.heattotosca.Constants;
71 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
72 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
73 import org.openecomp.sdc.translator.services.heattotosca.errors.MissingMandatoryPropertyErrorBuilder;
74 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
75 import org.openecomp.sdc.translator.services.heattotosca.helper.ContrailTranslationHelper;
76 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
78 public class ResourceTranslationContrailServiceInstanceImpl extends ResourceTranslationBase {
80 private static final String INTERFACE_LIST = "interface_list";
81 protected static Logger logger = LoggerFactory.getLogger(ResourceTranslationContrailServiceInstanceImpl.class);
84 public void translate(TranslateTo translateTo) {
85 Resource serviceInstanceResource = translateTo.getResource();
86 AttachedResourceId contrailServiceTemplateAttached = getServiceTemplateAttachedId(translateTo,
87 serviceInstanceResource);
88 if (contrailServiceTemplateAttached.isGetResource()) {
89 translateContrailServiceInstance(translateTo, serviceInstanceResource, contrailServiceTemplateAttached);
91 logger.warn(LOG_SERVICE_TEMPLATE_PROPERTY_GET_RESOURCE, translateTo.getResourceId(),
92 translateTo.getResource().getType());
96 private void translateContrailServiceInstance(TranslateTo translateTo, Resource serviceInstanceResource,
97 AttachedResourceId contrailServiceTemplateAttached) {
98 String contrailServiceTemplateResourceId = (String) contrailServiceTemplateAttached.getEntityId();
99 Resource contrailServiceTemplateResource = HeatToToscaUtil
100 .getResource(translateTo.getHeatOrchestrationTemplate(),
101 contrailServiceTemplateResourceId, translateTo.getHeatFileName());
102 if (!contrailServiceTemplateResource.getType()
103 .equals(HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource())) {
104 logger.warn(LOG_SERVICE_TEMPLATE_PROPERTY_INVALID_TYPE, translateTo.getResourceId(),
105 translateTo.getResource().getType(), contrailServiceTemplateResourceId,
106 contrailServiceTemplateResource.getType(),
107 HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource());
110 Optional<String> contrailServiceTemplateTranslatedId =
111 ResourceTranslationFactory.getInstance(contrailServiceTemplateResource)
112 .translateResource(translateTo.getHeatFileName(), translateTo.getServiceTemplate(),
113 translateTo.getHeatOrchestrationTemplate(), contrailServiceTemplateResource,
114 contrailServiceTemplateResourceId, translateTo.getContext());
115 if (!contrailServiceTemplateTranslatedId.isPresent()) {
116 logger.warn(LOG_SERVICE_TEMPLATE_PROPERTY_UNSUPPORTED_RESOURCE, translateTo.getResourceId(),
117 translateTo.getResource().getType(), contrailServiceTemplateResourceId,
118 contrailServiceTemplateResource.getType());
122 ServiceTemplate globalSubstitutionServiceTemplate = translateTo.getContext().getTranslatedServiceTemplates()
123 .get(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
124 String contrailStId = ResourceTranslationContrailServiceTemplateImpl
125 .getContrailSubstitutedNodeTypeId(contrailServiceTemplateTranslatedId.get());
126 NodeType substitutedNodeType = DataModelUtil.getNodeType(globalSubstitutionServiceTemplate, contrailStId);
127 int numberOfPorts = getServiceInstanceNumberOfPorts(serviceInstanceResource);
128 if (substitutedNodeType.getRequirements() != null
129 && substitutedNodeType.getRequirements().size() != numberOfPorts) {
130 logger.warn(LOG_MULTIPLE_SERVICE_INSTANCE_DIFF_INTERFACES, contrailServiceTemplateResourceId);
133 addNetworkLinkRequirements(substitutedNodeType, numberOfPorts);
134 NodeTemplate substitutedNodeTemplate = createSubstitutedNodeTemplate(translateTo,
135 contrailServiceTemplateResource, contrailStId, numberOfPorts);
136 String computeNodeTypeId = new ContrailTranslationHelper()
137 .getComputeNodeTypeId(contrailServiceTemplateResource, contrailServiceTemplateResourceId,
138 contrailServiceTemplateTranslatedId.get(), translateTo.getContext());
139 boolean orderedInterfaces = getOrderedInterfaces(contrailServiceTemplateResource);
140 ServiceTemplate nestedServiceTemplate = createNestedServiceTemplate(translateTo, computeNodeTypeId,
141 contrailStId, 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 private void addAbstractSubstitutionProperty(TranslateTo translateTo,
150 Map<String, Object> substitutionProperties,
151 ServiceTemplate nestedServiceTemplate,
152 Resource contrailServiceTemplateResource) {
153 Map<String, Object> innerProps = new HashMap<>();
154 innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME,
155 ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate));
156 Object countValue = handleScaleOutProperty(translateTo, innerProps);
157 handleServiceScalingProperty(translateTo, innerProps, contrailServiceTemplateResource);
158 boolean mandatory = false;
159 if (countValue instanceof Integer && (Integer) countValue > 0) {
162 if (countValue == null) {
165 innerProps.put(MANDATORY_PROPERTY_NAME, mandatory);
166 substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
169 private Object handleScaleOutProperty(TranslateTo translateTo, Map<String, Object> innerProps) {
170 Object scaleOutPropertyValue =
171 translateTo.getResource().getProperties().get(HeatConstants.SCALE_OUT_PROPERTY_NAME);
172 Object countValue = null;
173 if (scaleOutPropertyValue instanceof Map) {
174 countValue = TranslatorHeatToToscaPropertyConverter
175 .getToscaPropertyValue(translateTo.getServiceTemplate(), translateTo.getTranslatedId(),
176 Constants.MAX_INSTANCES_PROPERTY_NAME,
177 ((Map) scaleOutPropertyValue).get(Constants.MAX_INSTANCES_PROPERTY_NAME), null,
178 translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(), null,
179 translateTo.getContext());
180 if (countValue != null) {
181 innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, countValue);
183 innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
186 innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
191 private void handleServiceScalingProperty(TranslateTo translateTo, Map<String, Object> innerProps,
192 Resource contrailServiceTemplateResource) {
193 Object serviceScalingPropertyValue = contrailServiceTemplateResource.getProperties()
194 .get(HeatConstants.SERVICE_SCALING_PROPERTY_NAME);
195 Object serviceScalingValue;
196 if (serviceScalingPropertyValue != null) {
197 serviceScalingValue = TranslatorHeatToToscaPropertyConverter
198 .getToscaPropertyValue(translateTo.getServiceTemplate(), translateTo.getTranslatedId(),
199 HeatConstants.SERVICE_SCALING_PROPERTY_NAME, serviceScalingPropertyValue, null,
200 translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(), null,
201 translateTo.getContext());
202 if (serviceScalingValue != null) {
203 innerProps.put(ToscaConstants.SCALING_ENABLED_PROPERTY_NAME,
204 (HeatBoolean.isValueBoolean(serviceScalingValue)) ? HeatBoolean.eval(serviceScalingValue) :
205 serviceScalingValue);
210 private boolean getOrderedInterfaces(Resource contrailServiceTemplate) {
211 Object orderedInterfaces = contrailServiceTemplate.getProperties().get("ordered_interfaces");
212 if (orderedInterfaces == null) {
215 if (orderedInterfaces instanceof String) {
216 return HeatBoolean.eval(orderedInterfaces);
218 //if get_param, set default value to true
222 private ServiceTemplate createNestedServiceTemplate(TranslateTo translateTo,
223 String computeNodeTypeId,
224 String substitutedNodeTypeId,
225 NodeTemplate substitutedNodeTemplate,
226 boolean orderedInterfaces) {
227 ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
228 setNestedServiceTemplateGeneralDetails(translateTo, nestedSubstitutionServiceTemplate);
229 String heatStackGroupKey = addHeatStackGroup(translateTo, nestedSubstitutionServiceTemplate);
230 addSubstitutionMappingEntry(nestedSubstitutionServiceTemplate, substitutedNodeTypeId);
231 handleInputParameters(nestedSubstitutionServiceTemplate, translateTo);
232 String computeNodeTemplateId = handleComputeNodeTemplate(translateTo, computeNodeTypeId,
233 nestedSubstitutionServiceTemplate, heatStackGroupKey);
234 handleOutputParameters(nestedSubstitutionServiceTemplate, computeNodeTemplateId, translateTo);
235 handleServiceInstanceInterfaces(translateTo,
236 new ContrailServiceInstanceTo(nestedSubstitutionServiceTemplate, substitutedNodeTemplate,
237 heatStackGroupKey, orderedInterfaces, computeNodeTemplateId));
238 return nestedSubstitutionServiceTemplate;
241 private void handleOutputParameters(ServiceTemplate nestedSubstitutionServiceTemplate,
242 String nodeTemplateId, TranslateTo translateTo) {
243 if (nodeTemplateId == null) {
246 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
248 Optional<NodeType> contrailAbstractNodeType =
249 toscaAnalyzerService.fetchNodeType(ToscaNodeType.CONTRAIL_ABSTRACT_SUBSTITUTE, translateTo
250 .getContext().getGlobalServiceTemplates().values());
252 if (!contrailAbstractNodeType.isPresent()) {
255 Map<String, AttributeDefinition> contrailAbstractAttributes =
256 contrailAbstractNodeType.get().getAttributes();
257 Map<String, ParameterDefinition> nestedSubstitutionServiceTemplateOutputs = new HashMap<>();
259 if (contrailAbstractAttributes == null) {
263 for (Map.Entry<String, AttributeDefinition> attributeDefinitionEntry : contrailAbstractAttributes.entrySet()) {
264 AttributeDefinition abstractAttributeDef = attributeDefinitionEntry.getValue();
265 if (abstractAttributeDef != null) {
266 Map<String, List> outputValue = new HashMap<>();
267 List<String> outputGetAttributeList = new ArrayList<>();
268 outputGetAttributeList.add(nodeTemplateId);
269 outputGetAttributeList.add(attributeDefinitionEntry.getKey());
270 outputValue.put(ToscaFunctions.GET_ATTRIBUTE.getDisplayName(), outputGetAttributeList);
271 nestedSubstitutionServiceTemplateOutputs.put(attributeDefinitionEntry.getKey(),
272 DataModelUtil.convertAttributeDefToParameterDef(abstractAttributeDef, outputValue));
276 if (!nestedSubstitutionServiceTemplateOutputs.isEmpty()) {
277 nestedSubstitutionServiceTemplate.getTopology_template()
278 .setOutputs(nestedSubstitutionServiceTemplateOutputs);
282 private void handleServiceInstanceInterfaces(TranslateTo translateTo,
283 ContrailServiceInstanceTo contrailServiceInstanceTo) {
284 Resource serviceInstanceResource = translateTo.getResource();
285 Object interfaceListProperty =
286 serviceInstanceResource.getProperties().get(HeatConstants.INTERFACE_LIST_PROPERTY_NAME);
287 if (interfaceListProperty == null) {
290 if (interfaceListProperty instanceof List) {
291 for (int index = 0; index < ((List) interfaceListProperty).size(); index++) {
292 Object interfaceEntry = ((List) interfaceListProperty).get(index);
293 handleInterface(translateTo, interfaceEntry, index, contrailServiceInstanceTo);
295 } else if (interfaceListProperty instanceof Map) {
296 handleInterface(translateTo, interfaceListProperty, null, contrailServiceInstanceTo);
300 private void handleInterface(TranslateTo translateTo, Object interfacePropertyValue,
301 Integer index, ContrailServiceInstanceTo contrailServiceInstanceTo) {
305 NodeTemplate portNodeTemplate = createPortNodeTemplate(index, contrailServiceInstanceTo.isOrderedInterfaces(),
306 contrailServiceInstanceTo.getComputeNodeTemplateId());
307 String portNodeTemplateId = Constants.SERVICE_INSTANCE_PORT_PREFIX + index;
308 String portReqMappingKey = Constants.SERVICE_INSTANCE_LINK_PREFIX + portNodeTemplateId;
310 DataModelUtil.addNodeTemplate(contrailServiceInstanceTo.getNestedSubstitutionServiceTemplate(),
311 portNodeTemplateId, portNodeTemplate);
312 updateSubstitutionMappingRequirement(contrailServiceInstanceTo.getNestedSubstitutionServiceTemplate(),
313 portReqMappingKey, portNodeTemplateId);
314 updateHeatStackGroup(contrailServiceInstanceTo.getNestedSubstitutionServiceTemplate(),
315 contrailServiceInstanceTo.getHeatStackGroupKey(), portNodeTemplateId);
316 connectPortToNetwork(translateTo, interfacePropertyValue, contrailServiceInstanceTo
317 .getSubstitutedNodeTemplate(), portReqMappingKey);
320 private void connectPortToNetwork(TranslateTo translateTo, Object interfacePropertyValue,
321 NodeTemplate substitutedNodeTemplate,
322 String portReqMappingKey) {
323 List<String> validNetworksForConnections = Arrays
324 .asList(HeatResourcesTypes.NEUTRON_NET_RESOURCE_TYPE.getHeatResource(),
325 HeatResourcesTypes.CONTRAIL_VIRTUAL_NETWORK_RESOURCE_TYPE.getHeatResource());
326 if (!(interfacePropertyValue instanceof Map)) {
329 Object virtualNetworkValue = ((Map) interfacePropertyValue).get(HeatConstants.VIRTUAL_NETWORK_PROPERTY_NAME);
330 if (virtualNetworkValue == null) {
331 logger.warn(LOG_MISSING_VIRTUAL_NETWORK_INTERFACE_LIST, translateTo.getResourceId(),
332 translateTo.getResource().getType());
335 Optional<AttachedResourceId> networkAttachedResourceId = HeatToToscaUtil
336 .extractAttachedResourceId(translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(),
337 translateTo.getContext(), virtualNetworkValue);
338 if (!networkAttachedResourceId.isPresent()) {
341 Optional<String> networkResourceId =
342 HeatToToscaUtil.getContrailAttachedHeatResourceId(networkAttachedResourceId.get());
343 if (networkResourceId.isPresent()) {
344 Resource networkResource = HeatToToscaUtil.getResource(translateTo.getHeatOrchestrationTemplate(),
345 networkResourceId.get(), translateTo.getHeatFileName());
346 if (validNetworksForConnections.contains(networkResource.getType())) {
347 Optional<String> networkTranslatedId =
348 getResourceTranslatedId(translateTo.getHeatFileName(),
349 translateTo.getHeatOrchestrationTemplate(), networkResourceId.get(),
350 translateTo.getContext());
351 networkTranslatedId.ifPresent(translatedId -> addLinkToNetworkRequirementAssignment(
352 substitutedNodeTemplate, translatedId, portReqMappingKey));
355 logger.warn(LOG_UNSUPPORTED_NETWORK_RESOURCE_CONNECTION, translateTo.getResourceId(),
356 translateTo.getResource().getType());
358 } else if (networkAttachedResourceId.get().isGetParam()
359 && networkAttachedResourceId.get().getEntityId() instanceof String) {
360 TranslatedHeatResource translatedSharedResourceId = translateTo.getContext().getHeatSharedResourcesByParam()
361 .get(networkAttachedResourceId.get().getEntityId());
362 if (Objects.nonNull(translatedSharedResourceId)
363 && !HeatToToscaUtil.isHeatFileNested(translateTo, translateTo.getHeatFileName())) {
364 addLinkToNetworkRequirementAssignment(substitutedNodeTemplate,
365 translatedSharedResourceId.getTranslatedId(), portReqMappingKey);
368 logger.warn(LOG_INVALID_NETWORK_CONNECTION, translateTo.getResourceId(),
369 translateTo.getResource().getType(), virtualNetworkValue.toString());
373 private NodeTemplate createPortNodeTemplate(Integer index, boolean orderedInterfaces,
374 String computeNodeTemplateId) {
375 NodeTemplate portNodeTemplate = new NodeTemplate();
376 portNodeTemplate.setType(ToscaNodeType.CONTRAIL_PORT);
377 Map<String, Object> portProperties = new HashMap<>();
378 portProperties.put("static_routes", DataModelUtil
379 .createGetInputPropertyValueFromListParameter(INTERFACE_LIST, index, "static_routes"));
380 portProperties.put("virtual_network", DataModelUtil
381 .createGetInputPropertyValueFromListParameter(INTERFACE_LIST, index, "virtual_network"));
382 portProperties.put("allowed_address_pairs", DataModelUtil
383 .createGetInputPropertyValueFromListParameter(INTERFACE_LIST, index,
384 "allowed_address_pairs"));
385 portProperties.put("ip_address", DataModelUtil
386 .createGetInputPropertyValueFromListParameter(INTERFACE_LIST, index, "ip_address"));
387 portProperties.put("static_route",
388 DataModelUtil.createGetInputPropertyValueFromListParameter("static_routes_list", index));
389 portProperties.put("shared_ip",
390 DataModelUtil.createGetInputPropertyValueFromListParameter("shared_ip_list", index));
391 portProperties.put("interface_type", DataModelUtil
392 .createGetInputPropertyValueFromListParameter("service_interface_type_list", index));
393 if (orderedInterfaces) {
394 portProperties.put("order", index);
396 portNodeTemplate.setProperties(portProperties);
397 DataModelUtil.addBindingReqFromPortToCompute(computeNodeTemplateId, portNodeTemplate);
398 return portNodeTemplate;
402 private void addLinkToNetworkRequirementAssignment(NodeTemplate nodeTemplate,
403 String connectedNodeTranslatedId,
404 String requirementId) {
405 if (nodeTemplate == null || connectedNodeTranslatedId == null) {
408 RequirementAssignment requirement = new RequirementAssignment();
409 requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE);
410 requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_LINK_TO);
411 requirement.setNode(connectedNodeTranslatedId);
412 DataModelUtil.addRequirementAssignment(nodeTemplate, requirementId, requirement);
415 private void updateHeatStackGroup(ServiceTemplate serviceTemplate, String heatStackGroupKey,
417 serviceTemplate.getTopology_template().getGroups().get(heatStackGroupKey).getMembers().add(memberId);
420 private void updateSubstitutionMappingRequirement(ServiceTemplate serviceTemplate,
421 String portReqMappingKey,
422 String portNodeTemplateId) {
423 List<String> portReqMappingValue = new ArrayList<>();
424 portReqMappingValue.add(portNodeTemplateId);
425 portReqMappingValue.add(ToscaConstants.LINK_REQUIREMENT_ID);
426 DataModelUtil.addSubstitutionMappingReq(serviceTemplate, portReqMappingKey, portReqMappingValue);
429 private void addSubstitutionMappingEntry(ServiceTemplate nestedSubstitutionServiceTemplate,
430 String substitutedNodeTypeId) {
431 SubstitutionMapping substitutionMappings = new SubstitutionMapping();
432 substitutionMappings.setNode_type(substitutedNodeTypeId);
433 DataModelUtil.addSubstitutionMapping(nestedSubstitutionServiceTemplate, substitutionMappings);
436 private void handleInputParameters(ServiceTemplate nestedSubstitutionServiceTemplate,
437 TranslateTo translateTo) {
438 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
439 Optional<NodeType> contrailAbstractNodeType = toscaAnalyzerService.fetchNodeType(ToscaNodeType
440 .CONTRAIL_ABSTRACT_SUBSTITUTE, translateTo.getContext().getGlobalServiceTemplates().values());
441 Map<String, ParameterDefinition> nestedSubstitutionServiceTemplateInputs = new HashMap<>();
442 if (contrailAbstractNodeType.isPresent()) {
443 Map<String, PropertyDefinition> contrailAbstractProperties = contrailAbstractNodeType.get().getProperties();
444 for (Map.Entry<String, PropertyDefinition> propertyEntry : contrailAbstractProperties.entrySet()) {
445 PropertyDefinition abstractPropertyDef = contrailAbstractProperties.get(propertyEntry.getKey());
446 if (abstractPropertyDef != null) {
447 nestedSubstitutionServiceTemplateInputs.put(propertyEntry.getKey(),
448 DataModelUtil.convertPropertyDefToParameterDef(abstractPropertyDef));
452 if (!nestedSubstitutionServiceTemplateInputs.isEmpty()) {
453 nestedSubstitutionServiceTemplate.getTopology_template().setInputs(nestedSubstitutionServiceTemplateInputs);
457 private String handleComputeNodeTemplate(TranslateTo translateTo, String computeNodeTypeId,
458 ServiceTemplate nestedSubstitutionServiceTemplate,
459 String heatStackGroupKey) {
460 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
461 Optional<NodeType> contrailComputeNodeType = toscaAnalyzerService.fetchNodeType(ToscaNodeType.CONTRAIL_COMPUTE,
462 translateTo.getContext().getGlobalServiceTemplates().values());
463 Map<String, Object> computeNodeTemplateProperties = null;
464 if (contrailComputeNodeType.isPresent()) {
465 Map<String, PropertyDefinition> contrailComputeProperties = contrailComputeNodeType.get().getProperties();
466 computeNodeTemplateProperties = new HashMap<>();
467 if (contrailComputeProperties != null) {
468 for (String computePropertyKey : contrailComputeProperties.keySet()) {
469 Map<String, Object> getInputProperty = new HashMap<>();
470 getInputProperty.put(ToscaFunctions.GET_INPUT.getDisplayName(), computePropertyKey);
471 computeNodeTemplateProperties.put(computePropertyKey, getInputProperty);
476 NodeTemplate computeNodeTemplate = new NodeTemplate();
477 computeNodeTemplate.setType(computeNodeTypeId);
478 if (computeNodeTemplateProperties != null && !computeNodeTemplateProperties.isEmpty()) {
479 computeNodeTemplate.setProperties(computeNodeTemplateProperties);
481 String computeNodeTemplateId = translateTo.getTranslatedId();
482 DataModelUtil.addNodeTemplate(nestedSubstitutionServiceTemplate, computeNodeTemplateId, computeNodeTemplate);
483 nestedSubstitutionServiceTemplate.getTopology_template().getGroups().get(heatStackGroupKey)
484 .getMembers().add(computeNodeTemplateId);
485 return computeNodeTemplateId;
488 private String addHeatStackGroup(TranslateTo translateTo, ServiceTemplate serviceTemplate) {
489 GroupDefinition serviceInstanceGroupDefinition = new GroupDefinition();
490 serviceInstanceGroupDefinition.setType(ToscaGroupType.HEAT_STACK);
491 Map<String, Object> groupProperties = new HashMap<>();
492 groupProperties.put("heat_file",
493 "../" + (new ToscaFileOutputServiceCsarImpl()).getArtifactsFolderName() + "/"
494 + translateTo.getHeatFileName());
495 serviceInstanceGroupDefinition.setProperties(groupProperties);
496 serviceInstanceGroupDefinition.setMembers(new ArrayList<>());
497 String heatStackGroupKey = translateTo.getTranslatedId() + "_group";
498 DataModelUtil.addGroupDefinitionToTopologyTemplate(serviceTemplate, heatStackGroupKey,
499 serviceInstanceGroupDefinition);
500 return heatStackGroupKey;
504 private void setNestedServiceTemplateGeneralDetails(TranslateTo translateTo,
506 nestedSubstitutionServiceTemplate) {
507 Map<String, String> nestedTemplateMetadata = new HashMap<>();
508 String nestedTemplateName = new ContrailTranslationHelper()
509 .getSubstitutionContrailServiceTemplateMetadata(translateTo.getHeatFileName(),
510 translateTo.getResourceId());
511 nestedTemplateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, nestedTemplateName);
512 nestedSubstitutionServiceTemplate.setMetadata(nestedTemplateMetadata);
513 nestedSubstitutionServiceTemplate.setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
514 nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
515 List<Map<String, Import>> globalTypesImportList = GlobalTypesGenerator.getGlobalTypesImportList();
516 globalTypesImportList.addAll(
517 HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
518 nestedSubstitutionServiceTemplate.setImports(globalTypesImportList);
521 private NodeTemplate createSubstitutedNodeTemplate(TranslateTo translateTo,
522 Resource contrailServiceTemplateResource,
523 String contrailServiceTemplateTranslatedId,
525 boolean isImportAddedToServiceTemplate =
527 .isImportAddedToServiceTemplate(translateTo.getServiceTemplate().getImports(), Constants
528 .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
529 if (!isImportAddedToServiceTemplate) {
530 translateTo.getServiceTemplate().getImports()
531 .addAll(HeatToToscaUtil
532 .createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
534 NodeTemplate substitutesNodeTemplate = new NodeTemplate();
535 substitutesNodeTemplate.setType(contrailServiceTemplateTranslatedId);
536 List<String> directiveList = new ArrayList<>();
537 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
538 substitutesNodeTemplate.setDirectives(directiveList);
539 substitutesNodeTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
540 .getToscaPropertiesSimpleConversion(translateTo.getServiceTemplate(),
541 translateTo.getResourceId(), translateTo.getResource().getProperties(),
542 substitutesNodeTemplate.getProperties(), translateTo.getHeatFileName(),
543 translateTo.getHeatOrchestrationTemplate(),
544 HeatResourcesTypes.CONTRAIL_SERVICE_INSTANCE.getHeatResource(), substitutesNodeTemplate,
545 translateTo.getContext()));
546 substitutesNodeTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
547 .getToscaPropertiesSimpleConversion(translateTo.getServiceTemplate(),
548 translateTo.getResourceId(), contrailServiceTemplateResource.getProperties(),
549 substitutesNodeTemplate.getProperties(), translateTo.getHeatFileName(),
550 translateTo.getHeatOrchestrationTemplate(),
551 HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource(), substitutesNodeTemplate,
552 translateTo.getContext()));
553 HeatToToscaUtil.mapBoolean(substitutesNodeTemplate, HeatToToscaUtil
554 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
555 HeatConstants.AVAILABILITY_ZONE_ENABLE_PROPERTY_NAME));
556 HeatToToscaUtil.mapBoolean(substitutesNodeTemplate, HeatToToscaUtil
557 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
558 HeatConstants.ORDERED_INTERFACES_PROPERTY_NAME));
560 Object sharedIpListPropertyValue =
561 contrailServiceTemplateResource.getProperties()
562 .get(HeatConstants.SHARED_IP_LIST_PROPERTY_NAME);
563 String toscaSharedIpListPropertyName = HeatToToscaUtil
564 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
565 HeatConstants.SHARED_IP_LIST_PROPERTY_NAME);
566 Optional<List<Map<String, List>>> sharedIpTranslatedSplitFun =
567 new ContrailTranslationHelper()
568 .translateFnSplitFunction(sharedIpListPropertyValue, numberOfPorts, true);
569 if (sharedIpTranslatedSplitFun.isPresent()) {
570 substitutesNodeTemplate.getProperties()
571 .put(toscaSharedIpListPropertyName, sharedIpTranslatedSplitFun.get());
573 HeatToToscaUtil.mapBooleanList(substitutesNodeTemplate, toscaSharedIpListPropertyName);
576 Object staticRouteListPropertyValue =
577 contrailServiceTemplateResource.getProperties()
578 .get(HeatConstants.STATIC_ROUTES_LIST_PROPERTY_NAME);
579 String toscaStaticRoutesListPropertyName = HeatToToscaUtil
580 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
581 HeatConstants.STATIC_ROUTES_LIST_PROPERTY_NAME);
582 Optional<List<Map<String, List>>> staticRouteTranslatedSplitFun =
583 new ContrailTranslationHelper()
584 .translateFnSplitFunction(staticRouteListPropertyValue, numberOfPorts, true);
585 if (staticRouteTranslatedSplitFun.isPresent()) {
586 substitutesNodeTemplate.getProperties()
587 .put(toscaStaticRoutesListPropertyName, staticRouteTranslatedSplitFun.get());
589 HeatToToscaUtil.mapBooleanList(substitutesNodeTemplate, toscaStaticRoutesListPropertyName);
592 Object serviceInterfaceTypeListPropertyValue =
593 contrailServiceTemplateResource.getProperties()
594 .get(HeatConstants.SERVICE_INTERFCAE_TYPE_LIST_PROPERTY_NAME);
595 String toscaServiceInterfaceTypeListPropertyName = HeatToToscaUtil
596 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
597 HeatConstants.SERVICE_INTERFCAE_TYPE_LIST_PROPERTY_NAME);
598 Optional<List<Map<String, List>>> serviceInterfaceTypeTranslatedSplitFun =
599 new ContrailTranslationHelper()
600 .translateFnSplitFunction(serviceInterfaceTypeListPropertyValue, numberOfPorts, false);
601 serviceInterfaceTypeTranslatedSplitFun
602 .ifPresent(translatedSplitFun -> substitutesNodeTemplate.getProperties()
603 .put(toscaServiceInterfaceTypeListPropertyName, translatedSplitFun));
605 String substitutedNodeTemplateId = translateTo.getTranslatedId();
606 DataModelUtil.addNodeTemplate(translateTo.getServiceTemplate(), substitutedNodeTemplateId,
607 substitutesNodeTemplate);
608 return substitutesNodeTemplate;
611 private void addNetworkLinkRequirements(NodeType nodeType, int numberOfPorts) {
612 if (nodeType.getRequirements() == null) {
613 List<Map<String, RequirementDefinition>> requirementList = new ArrayList<>();
614 for (int i = 0; i < numberOfPorts; i++) {
615 Map<String, RequirementDefinition> requirementDefinitionMap = new HashMap<>();
616 requirementDefinitionMap.put(ToscaConstants.LINK_REQUIREMENT_ID + "_port_" + i,
617 DataModelUtil.createRequirement(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE,
618 ToscaNodeType.NATIVE_ROOT,
619 ToscaRelationshipType.NATIVE_NETWORK_LINK_TO, null));
620 requirementList.add(requirementDefinitionMap);
622 if (numberOfPorts > 0) {
623 nodeType.setRequirements(requirementList);
628 private int getServiceInstanceNumberOfPorts(Resource serviceInstanceResource) {
630 Object interfaceTypeProperty =
631 serviceInstanceResource.getProperties().get(HeatConstants.INTERFACE_LIST_PROPERTY_NAME);
632 if (interfaceTypeProperty == null) {
634 } else if (interfaceTypeProperty instanceof List) {
635 numberOfPorts = ((List) interfaceTypeProperty).size();
636 } else if (interfaceTypeProperty instanceof Map) {
641 return numberOfPorts;
644 private AttachedResourceId getServiceTemplateAttachedId(TranslateTo translateTo,
645 Resource serviceInstanceResource) {
646 Object serviceTemplateProperty =
647 serviceInstanceResource.getProperties().get("service_template");
648 Optional<AttachedResourceId> serviceTemplateId = HeatToToscaUtil
649 .extractAttachedResourceId(translateTo.getHeatFileName(),
650 translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(),
651 serviceTemplateProperty);
652 if (serviceTemplateId.isPresent()) {
653 return serviceTemplateId.get();
655 throw new CoreException(new MissingMandatoryPropertyErrorBuilder("service_template").build());