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.datatypes.error.ErrorLevel;
25 import org.openecomp.sdc.heat.datatypes.HeatBoolean;
26 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
27 import org.openecomp.sdc.heat.datatypes.model.Resource;
28 import org.openecomp.sdc.heat.services.HeatConstants;
29 import org.openecomp.sdc.logging.api.Logger;
30 import org.openecomp.sdc.logging.api.LoggerFactory;
31 import org.openecomp.sdc.logging.types.LoggerConstants;
32 import org.openecomp.sdc.logging.types.LoggerErrorCode;
33 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
34 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
35 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
36 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
37 import org.openecomp.sdc.tosca.datatypes.ToscaGroupType;
38 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
39 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
40 import org.openecomp.sdc.tosca.datatypes.model.AttributeDefinition;
41 import org.openecomp.sdc.tosca.datatypes.model.GroupDefinition;
42 import org.openecomp.sdc.tosca.datatypes.model.Import;
43 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
44 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
45 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
46 import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition;
47 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
48 import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition;
49 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
50 import org.openecomp.sdc.tosca.datatypes.model.SubstitutionMapping;
51 import org.openecomp.sdc.tosca.datatypes.model.TopologyTemplate;
52 import org.openecomp.sdc.tosca.services.DataModelUtil;
53 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
54 import org.openecomp.sdc.tosca.services.ToscaConstants;
55 import org.openecomp.sdc.tosca.services.ToscaUtil;
56 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
57 import org.openecomp.sdc.tosca.services.impl.ToscaFileOutputServiceCsarImpl;
58 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
59 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
60 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslatedHeatResource;
61 import org.openecomp.sdc.translator.services.heattotosca.Constants;
62 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
63 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
64 import org.openecomp.sdc.translator.services.heattotosca.errors.MissingMandatoryPropertyErrorBuilder;
65 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
66 import org.openecomp.sdc.translator.services.heattotosca.helper.ContrailTranslationHelper;
67 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
69 import java.util.ArrayList;
70 import java.util.Arrays;
71 import java.util.HashMap;
72 import java.util.List;
74 import java.util.Objects;
75 import java.util.Optional;
77 public class ResourceTranslationContrailServiceInstanceImpl extends ResourceTranslationBase {
78 protected static Logger logger =
79 (Logger) LoggerFactory.getLogger(ResourceTranslationContrailServiceInstanceImpl.class);
82 public void translate(TranslateTo translateTo) {
83 Resource serviceInstanceResource = translateTo.getResource();
84 AttachedResourceId contrailServiceTemplateAttached =
85 getServiceTemplateAttachedId(translateTo, serviceInstanceResource);
86 if (contrailServiceTemplateAttached.isGetResource()) {
87 String contrailServiceTemplateResourceId =
88 (String) contrailServiceTemplateAttached.getEntityId();
89 Resource contrailServiceTemplateResource = HeatToToscaUtil
90 .getResource(translateTo.getHeatOrchestrationTemplate(),
91 contrailServiceTemplateResourceId, translateTo.getHeatFileName());
92 if (!contrailServiceTemplateResource.getType()
93 .equals(HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource())) {
94 logger.warn("resource id '" + translateTo.getResourceId() + "' with type '"
95 + translateTo.getResource().getType()
96 + "+ has reference to resource '" + contrailServiceTemplateResourceId + "' with type '"
97 + contrailServiceTemplateResource.getType()
98 + "' in property service_template. Invalid type, resource type should be type of '"
99 + HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource()
100 + "', therefore this resource will be ignored in TOSCA translation.");
103 Optional<String> contrailServiceTemplateTranslatedId =
104 ResourceTranslationFactory.getInstance(contrailServiceTemplateResource)
105 .translateResource(translateTo.getHeatFileName(), translateTo.getServiceTemplate(),
106 translateTo.getHeatOrchestrationTemplate(), contrailServiceTemplateResource,
107 contrailServiceTemplateResourceId, translateTo.getContext());
108 if (!contrailServiceTemplateTranslatedId.isPresent()) {
109 logger.warn("Resource id '" + translateTo.getResourceId() + "' with type '"
110 + translateTo.getResource().getType()
111 + "' has reference to unsupported resource '" + contrailServiceTemplateResourceId
112 + "' with type '" + contrailServiceTemplateResource.getType()
113 + "' in property 'service_template'"
114 + ", therefore this resource will be ignored in TOSCA translation.");
116 /*throw new CoreException(new ReferenceToUnsupportedResourceErrorBuilder
117 (translateTo.getResourceId(), translateTo.getResource().getType(),
118 contrailServiceTemplateResourceId, contrailServiceTemplateResource
119 .getType(), "service_template").build());*/
122 ServiceTemplate globalSubstitutionServiceTemplate =
123 translateTo.getContext().getTranslatedServiceTemplates().get(
124 Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
125 String contrailStId = ResourceTranslationContrailServiceTemplateImpl
126 .getContrailSubstitutedNodeTypeId(contrailServiceTemplateTranslatedId.get());
127 NodeType substitutedNodeType =
128 DataModelUtil.getNodeType(globalSubstitutionServiceTemplate, contrailStId);
130 int numberOfPorts = getServiceInstanceNumberOfPorts(serviceInstanceResource);
131 if (substitutedNodeType.getRequirements() != null
132 && substitutedNodeType.getRequirements().size() != numberOfPorts) {
133 logger.warn("More than one ServiceInstance pointing to the same ServiceTemplate '"
134 + contrailServiceTemplateResourceId + " ' with different number of interfaces."
135 + ", therefore this resource will be ignored in TOSCA translation.");
139 addNetworkLinkRequirements(substitutedNodeType, numberOfPorts);
140 NodeTemplate substitutedNodeTemplate =
141 createSubstitutedNodeTemplate(translateTo, contrailServiceTemplateResource, contrailStId,
144 String computeNodeTypeId = new ContrailTranslationHelper()
145 .getComputeNodeTypeId(contrailServiceTemplateResource, contrailServiceTemplateResourceId,
146 contrailServiceTemplateTranslatedId.get(), translateTo.getContext());
147 boolean orderedInterfaces = getOrderedInterfaces(contrailServiceTemplateResource);
148 ServiceTemplate nestedServiceTemplate =
149 createNestedServiceTemplate(translateTo, computeNodeTypeId, contrailStId,
150 substitutedNodeTemplate, orderedInterfaces);
151 addAbstractSubstitutionProperty(translateTo, substitutedNodeTemplate.getProperties(),
152 nestedServiceTemplate, contrailServiceTemplateResource);
153 translateTo.getContext().getTranslatedServiceTemplates().put(new ContrailTranslationHelper()
154 .getSubstitutionContrailServiceTemplateMetadata(translateTo.getHeatFileName(),
155 translateTo.getTranslatedId()), nestedServiceTemplate);
158 logger.warn("Heat resource: '" + translateTo.getResourceId() + "' with type: '"
159 + translateTo.getResource().getType()
160 + "' include 'service_template' property without 'get_resource' function, currently not"
161 + " supported, therefore this resource will be ignored in TOSCA translation.");
165 private void addAbstractSubstitutionProperty(TranslateTo translateTo,
166 Map<String, Object> substitutionProperties,
167 ServiceTemplate nestedServiceTemplate,
168 Resource contrailServiceTemplateResource) {
169 Map<String, Object> innerProps = new HashMap<>();
170 innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME,
171 ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate));
173 Object countValue = handleScaleOutProperty(translateTo, innerProps);
174 handleServiceScalingProperty(translateTo, innerProps, contrailServiceTemplateResource);
176 boolean mandatory = false;
177 if (countValue instanceof Integer && (Integer) countValue > 0) {
180 if (countValue == null) {
183 innerProps.put("mandatory", mandatory);
184 substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
187 private Object handleScaleOutProperty(TranslateTo translateTo, Map<String, Object> innerProps) {
188 Object scaleOutPropertyValue =
189 translateTo.getResource().getProperties().get(HeatConstants.SCALE_OUT_PROPERTY_NAME);
190 Object countValue = null;
191 if (scaleOutPropertyValue != null && scaleOutPropertyValue instanceof Map) {
192 countValue = TranslatorHeatToToscaPropertyConverter
193 .getToscaPropertyValue(translateTo.getServiceTemplate(), translateTo.getTranslatedId(),
194 Constants.MAX_INSTANCES_PROPERTY_NAME,
195 ((Map) scaleOutPropertyValue).get(Constants.MAX_INSTANCES_PROPERTY_NAME), null,
196 translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(), null,
197 translateTo.getContext());
198 if (countValue != null) {
199 innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, countValue);
201 innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
204 innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
209 private void handleServiceScalingProperty(TranslateTo translateTo, Map<String, Object> innerProps,
210 Resource contrailServiceTemplateResource) {
211 Object serviceScalingPropertyValue = contrailServiceTemplateResource.getProperties()
212 .get(HeatConstants.SERVICE_SCALING_PROPERTY_NAME);
213 Object serviceScalingValue = null;
214 if (serviceScalingPropertyValue != null) {
215 serviceScalingValue = TranslatorHeatToToscaPropertyConverter
216 .getToscaPropertyValue(translateTo.getServiceTemplate(), translateTo.getTranslatedId(),
217 HeatConstants.SERVICE_SCALING_PROPERTY_NAME, serviceScalingPropertyValue, null,
218 translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(), null,
219 translateTo.getContext());
220 if (serviceScalingValue != null) {
221 innerProps.put(ToscaConstants.SCALING_ENABLED_PROPERTY_NAME,
222 (HeatBoolean.isValueBoolean(serviceScalingValue)) ? HeatBoolean
223 .eval(serviceScalingValue) : serviceScalingValue);
228 private boolean getOrderedInterfaces(Resource contrailServiceTemplate) {
229 Object orderedInterfaces = contrailServiceTemplate.getProperties().get("ordered_interfaces");
230 if (orderedInterfaces == null) {
233 if (orderedInterfaces instanceof String) {
234 return HeatBoolean.eval(orderedInterfaces);
236 //if get_param, set default value to true
240 private ServiceTemplate createNestedServiceTemplate(TranslateTo translateTo,
241 String computeNodeTypeId,
242 String substitutedNodeTypeId,
243 NodeTemplate substitutedNodeTemplate,
244 boolean orderedInterfaces) {
245 ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
246 setNestedServiceTemplateGeneralDetails(translateTo, nestedSubstitutionServiceTemplate);
247 String heatStackGroupKey = addHeatStackGroup(translateTo, nestedSubstitutionServiceTemplate);
248 addSubstitutionMappingEntry(nestedSubstitutionServiceTemplate, substitutedNodeTypeId);
250 handleInputParameters(nestedSubstitutionServiceTemplate, translateTo);
251 String computeNodeTemplateId =
252 handleComputeNodeTemplate(translateTo, computeNodeTypeId, nestedSubstitutionServiceTemplate,
254 handleOutputParameters(nestedSubstitutionServiceTemplate, computeNodeTemplateId, translateTo);
255 handleServiceInstanceInterfaces(translateTo, nestedSubstitutionServiceTemplate,
256 substitutedNodeTemplate, heatStackGroupKey, orderedInterfaces, computeNodeTemplateId);
257 return nestedSubstitutionServiceTemplate;
260 private void handleOutputParameters(ServiceTemplate nestedSubstitutionServiceTemplate,
261 String nodeTemplateId, TranslateTo translateTo) {
262 if (nodeTemplateId == null) {
265 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
267 Optional<NodeType> contrailAbstractNodeType =
268 toscaAnalyzerService.fetchNodeType(ToscaNodeType.CONTRAIL_ABSTRACT_SUBSTITUTE, translateTo
269 .getContext().getGlobalServiceTemplates().values());
271 if (!contrailAbstractNodeType.isPresent()) {
274 Map<String, AttributeDefinition> contrailAbstractAttributes =
275 contrailAbstractNodeType.get().getAttributes();
276 Map<String, ParameterDefinition> nestedSubstitutionServiceTemplateOutputs = new HashMap<>();
278 if (contrailAbstractAttributes == null) {
282 for (String attributeKey : contrailAbstractAttributes.keySet()) {
283 AttributeDefinition abstractAttributeDef = contrailAbstractAttributes.get(attributeKey);
284 if (abstractAttributeDef != null) {
285 Map<String, List> outputValue = new HashMap<>();
286 List outputGetAttributeList = new ArrayList<>();
287 outputGetAttributeList.add(nodeTemplateId);
288 outputGetAttributeList.add(attributeKey);
289 outputValue.put(ToscaFunctions.GET_ATTRIBUTE.getDisplayName(), outputGetAttributeList);
290 nestedSubstitutionServiceTemplateOutputs.put(attributeKey,
291 DataModelUtil.convertAttributeDefToParameterDef(abstractAttributeDef, outputValue));
294 if (!nestedSubstitutionServiceTemplateOutputs.isEmpty()) {
295 nestedSubstitutionServiceTemplate.getTopology_template()
296 .setOutputs(nestedSubstitutionServiceTemplateOutputs);
300 private void handleServiceInstanceInterfaces(TranslateTo translateTo,
301 ServiceTemplate nestedSubstitutionServiceTemplate,
302 NodeTemplate substitutedNodeTemplate,
303 String heatStackGroupKey, boolean orderedInterfaces,
304 String computeNodeTemplateId) {
305 Resource serviceInstanceResource = translateTo.getResource();
306 Object interfaceListProperty =
307 serviceInstanceResource.getProperties().get(HeatConstants.INTERFACE_LIST_PROPERTY_NAME);
308 if (interfaceListProperty == null) {
311 if (interfaceListProperty instanceof List) {
312 for (int index = 0; index < ((List) interfaceListProperty).size(); index++) {
313 Object interfaceEntry = ((List) interfaceListProperty).get(index);
314 handleInterface(translateTo, interfaceEntry, index, nestedSubstitutionServiceTemplate,
315 heatStackGroupKey, substitutedNodeTemplate, orderedInterfaces, computeNodeTemplateId);
317 } else if (interfaceListProperty instanceof Map) {
318 handleInterface(translateTo, interfaceListProperty, null, nestedSubstitutionServiceTemplate,
319 heatStackGroupKey, substitutedNodeTemplate, orderedInterfaces, computeNodeTemplateId);
323 private void handleInterface(TranslateTo translateTo, Object interfacePropertyValue,
325 ServiceTemplate nestedSubstitutionServiceTemplate,
326 String heatStackGroupKey, NodeTemplate substitutedNodeTemplate,
327 boolean orderedInterfaces, String computeNodeTemplateId) {
329 index = new Integer(0);
331 NodeTemplate portNodeTemplate =
332 createPortNodeTemplate(index, orderedInterfaces, computeNodeTemplateId);
333 String portNodeTemplateId = Constants.SERVICE_INSTANCE_PORT_PREFIX + index;
334 String portReqMappingKey = Constants.SERVICE_INSTANCE_LINK_PREFIX + portNodeTemplateId;
337 .addNodeTemplate(nestedSubstitutionServiceTemplate, portNodeTemplateId, portNodeTemplate);
338 updateSubstitutionMappingRequirement(nestedSubstitutionServiceTemplate, portReqMappingKey,
340 updateHeatStackGroup(nestedSubstitutionServiceTemplate, heatStackGroupKey, portNodeTemplateId);
341 connectPortToNetwork(translateTo, interfacePropertyValue, substitutedNodeTemplate,
345 private void connectPortToNetwork(TranslateTo translateTo, Object interfacePropertyValue,
346 NodeTemplate substitutedNodeTemplate,
347 String portReqMappingKey) {
348 List<String> validNetworksForConnections = Arrays
349 .asList(HeatResourcesTypes.NEUTRON_NET_RESOURCE_TYPE.getHeatResource(),
350 HeatResourcesTypes.CONTRAIL_VIRTUAL_NETWORK_RESOURCE_TYPE.getHeatResource());
352 if (interfacePropertyValue instanceof Map) {
353 Object virtualNetworkValue =
354 ((Map) interfacePropertyValue).get(HeatConstants.VIRTUAL_NETWORK_PROPERTY_NAME);
355 if (virtualNetworkValue != null) {
356 Optional<AttachedResourceId> networkAttachedResourceId = HeatToToscaUtil
357 .extractAttachedResourceId(translateTo.getHeatFileName(),
358 translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(),
359 virtualNetworkValue);
360 if (networkAttachedResourceId.isPresent()) {
361 Optional<String> networkResourceId =
362 HeatToToscaUtil.getContrailAttachedHeatResourceId(networkAttachedResourceId.get());
363 if (networkResourceId.isPresent()) {
364 Resource networkResource = HeatToToscaUtil
365 .getResource(translateTo.getHeatOrchestrationTemplate(), networkResourceId.get(),
366 translateTo.getHeatFileName());
367 if (validNetworksForConnections.contains(networkResource.getType())) {
368 Optional<String> networkTranslatedId =
369 getResourceTranslatedId(translateTo.getHeatFileName(),
370 translateTo.getHeatOrchestrationTemplate(), networkResourceId.get(),
371 translateTo.getContext());
374 translatedId -> addLinkToNetworkRequirementAssignment(substitutedNodeTemplate,
375 translatedId, portReqMappingKey));
378 logger.warn("Heat resource " + translateTo.getResourceId() + " with type "
379 + translateTo.getResource().getType()
380 + " has connection to invalid/not supported network resource, therefore, this "
381 + "connection will be ignored in the translation.");
383 } else if (networkAttachedResourceId.get().isGetParam()
384 && networkAttachedResourceId.get().getEntityId() instanceof String) {
385 TranslatedHeatResource
386 translatedSharedResourceId =
387 translateTo.getContext().getHeatSharedResourcesByParam()
388 .get(networkAttachedResourceId.get().getEntityId());
389 if (Objects.nonNull(translatedSharedResourceId)
390 && !HeatToToscaUtil.isHeatFileNested(translateTo, translateTo.getHeatFileName())) {
391 addLinkToNetworkRequirementAssignment(substitutedNodeTemplate,
392 translatedSharedResourceId.getTranslatedId(), portReqMappingKey);
395 logger.warn("Heat resource: '" + translateTo.getResourceId() + "' with type: '"
396 + translateTo.getResource().getType()
397 + "' include 'virtual_network' property with value '"
398 + virtualNetworkValue.toString()
399 + "', the connection to this network wasn't found/not supported therefore this "
400 + "connection will be ignored in TOSCA translation for this property.");
404 logger.warn("Heat resource: '" + translateTo.getResourceId() + "' with type: '"
405 + translateTo.getResource().getType()
406 + "' missing 'virtual_network' property in 'interface_list' entry, therefore, no "
407 + "network connection is define for this entry.");
408 //throw new CoreException(new
409 // MissingMandatoryPropertyErrorBuilder("virtual_network").build());
414 private NodeTemplate createPortNodeTemplate(Integer index, boolean orderedInterfaces,
415 String computeNodeTemplateId) {
416 NodeTemplate portNodeTemplate = new NodeTemplate();
417 portNodeTemplate.setType(ToscaNodeType.CONTRAIL_PORT);
418 Map<String, Object> portProperties = new HashMap<>();
419 portProperties.put("static_routes", DataModelUtil
420 .createGetInputPropertyValueFromListParameter("interface_list", index, "static_routes"));
421 portProperties.put("virtual_network", DataModelUtil
422 .createGetInputPropertyValueFromListParameter("interface_list", index, "virtual_network"));
423 portProperties.put("allowed_address_pairs", DataModelUtil
424 .createGetInputPropertyValueFromListParameter("interface_list", index,
425 "allowed_address_pairs"));
426 portProperties.put("ip_address", DataModelUtil
427 .createGetInputPropertyValueFromListParameter("interface_list", index, "ip_address"));
428 portProperties.put("static_route",
429 DataModelUtil.createGetInputPropertyValueFromListParameter("static_routes_list", index));
430 portProperties.put("shared_ip",
431 DataModelUtil.createGetInputPropertyValueFromListParameter("shared_ip_list", index));
432 portProperties.put("interface_type", DataModelUtil
433 .createGetInputPropertyValueFromListParameter("service_interface_type_list", index));
434 if (orderedInterfaces) {
435 portProperties.put("order", index);
437 portNodeTemplate.setProperties(portProperties);
438 DataModelUtil.addBindingReqFromPortToCompute(computeNodeTemplateId, portNodeTemplate);
439 return portNodeTemplate;
443 private void addLinkToNetworkRequirementAssignment(NodeTemplate nodeTemplate,
444 String connectedNodeTranslatedId,
445 String requirementId) {
446 if (nodeTemplate == null || connectedNodeTranslatedId == null) {
450 RequirementAssignment requirement = new RequirementAssignment();
451 requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE);
452 requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_LINK_TO);
453 requirement.setNode(connectedNodeTranslatedId);
454 DataModelUtil.addRequirementAssignment(nodeTemplate, requirementId, requirement);
457 private void updateHeatStackGroup(ServiceTemplate serviceTemplate, String heatStackGroupKey,
459 serviceTemplate.getTopology_template().getGroups().get(heatStackGroupKey).getMembers()
463 private void updateSubstitutionMappingRequirement(ServiceTemplate serviceTemplate,
464 String portReqMappingKey,
465 String portNodeTemplateId) {
466 List<String> portReqMappingValue = new ArrayList<>();
467 portReqMappingValue.add(portNodeTemplateId);
468 portReqMappingValue.add(ToscaConstants.LINK_REQUIREMENT_ID);
470 .addSubstitutionMappingReq(serviceTemplate, portReqMappingKey, portReqMappingValue);
473 private void addSubstitutionMappingEntry(ServiceTemplate nestedSubstitutionServiceTemplate,
474 String substitutedNodeTypeId) {
475 SubstitutionMapping substitutionMappings = new SubstitutionMapping();
476 substitutionMappings.setNode_type(substitutedNodeTypeId);
477 DataModelUtil.addSubstitutionMapping(nestedSubstitutionServiceTemplate, substitutionMappings);
480 private void handleInputParameters(ServiceTemplate nestedSubstitutionServiceTemplate,
481 TranslateTo translateTo) {
482 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
484 Optional<NodeType> contrailAbstractNodeType =
485 toscaAnalyzerService.fetchNodeType(ToscaNodeType.CONTRAIL_ABSTRACT_SUBSTITUTE, translateTo
486 .getContext().getGlobalServiceTemplates().values());
487 Map<String, ParameterDefinition> nestedSubstitutionServiceTemplateInputs = new HashMap<>();
488 if (contrailAbstractNodeType.isPresent()) {
489 Map<String, PropertyDefinition> contrailAbstractProperties =
490 contrailAbstractNodeType.get().getProperties();
492 for (String propertyKey : contrailAbstractProperties.keySet()) {
493 PropertyDefinition abstractPropertyDef = contrailAbstractProperties.get(propertyKey);
494 if (abstractPropertyDef != null) {
495 nestedSubstitutionServiceTemplateInputs
497 DataModelUtil.convertPropertyDefToParameterDef(abstractPropertyDef));
502 if (!nestedSubstitutionServiceTemplateInputs.isEmpty()) {
503 nestedSubstitutionServiceTemplate.getTopology_template()
504 .setInputs(nestedSubstitutionServiceTemplateInputs);
508 private String handleComputeNodeTemplate(TranslateTo translateTo, String computeNodeTypeId,
509 ServiceTemplate nestedSubstitutionServiceTemplate,
510 String heatStackGroupKey) {
511 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
512 Optional<NodeType> contrailComputeNodeType = toscaAnalyzerService
513 .fetchNodeType(ToscaNodeType.CONTRAIL_COMPUTE,
514 translateTo.getContext().getGlobalServiceTemplates().values());
516 Map<String, Object> computeNodeTemplateProperties = null;
517 if (contrailComputeNodeType.isPresent()) {
518 Map<String, PropertyDefinition> contrailComputeProperties =
519 contrailComputeNodeType.get().getProperties();
520 computeNodeTemplateProperties = new HashMap<>();
522 if (contrailComputeProperties != null) {
523 for (String computePropertyKey : contrailComputeProperties.keySet()) {
524 Map getInputProperty = new HashMap<>();
525 getInputProperty.put(ToscaFunctions.GET_INPUT.getDisplayName(), computePropertyKey);
526 computeNodeTemplateProperties.put(computePropertyKey, getInputProperty);
531 NodeTemplate computeNodeTemplate = new NodeTemplate();
532 computeNodeTemplate.setType(computeNodeTypeId);
533 if (computeNodeTemplateProperties != null && !computeNodeTemplateProperties.isEmpty()) {
534 computeNodeTemplate.setProperties(computeNodeTemplateProperties);
536 String computeNodeTemplateId = translateTo.getTranslatedId();
537 DataModelUtil.addNodeTemplate(nestedSubstitutionServiceTemplate, computeNodeTemplateId,
538 computeNodeTemplate);
539 nestedSubstitutionServiceTemplate.getTopology_template().getGroups().get(heatStackGroupKey)
540 .getMembers().add(computeNodeTemplateId);
541 return computeNodeTemplateId;
544 private String addHeatStackGroup(TranslateTo translateTo, ServiceTemplate serviceTemplate) {
545 GroupDefinition serviceInstanceGroupDefinition = new GroupDefinition();
546 serviceInstanceGroupDefinition.setType(ToscaGroupType.HEAT_STACK);
547 Map<String, Object> groupProperties = new HashMap<>();
548 groupProperties.put("heat_file",
549 "../" + (new ToscaFileOutputServiceCsarImpl()).getArtifactsFolderName() + "/"
550 + translateTo.getHeatFileName());
551 serviceInstanceGroupDefinition.setProperties(groupProperties);
552 serviceInstanceGroupDefinition.setMembers(new ArrayList<>());
553 String heatStackGroupKey = translateTo.getTranslatedId() + "_group";
554 DataModelUtil.addGroupDefinitionToTopologyTemplate(serviceTemplate, heatStackGroupKey,
555 serviceInstanceGroupDefinition);
556 return heatStackGroupKey;
560 private void setNestedServiceTemplateGeneralDetails(TranslateTo translateTo,
562 nestedSubstitutionServiceTemplate) {
563 Map<String, String> nestedTemplateMetadata = new HashMap<>();
564 String nestedTemplateName = new ContrailTranslationHelper()
565 .getSubstitutionContrailServiceTemplateMetadata(translateTo.getHeatFileName(),
566 translateTo.getResourceId());
567 nestedTemplateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, nestedTemplateName);
568 nestedSubstitutionServiceTemplate.setMetadata(nestedTemplateMetadata);
569 nestedSubstitutionServiceTemplate
570 .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
571 nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
572 List<Map<String, Import>> globalTypesImportList =
573 GlobalTypesGenerator.getGlobalTypesImportList();
574 globalTypesImportList.addAll(
575 HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
576 nestedSubstitutionServiceTemplate.setImports(globalTypesImportList);
579 private NodeTemplate createSubstitutedNodeTemplate(TranslateTo translateTo,
580 Resource contrailServiceTemplateResource,
581 String contrailServiceTemplateTranslatedId,
583 boolean isImportAddedToServiceTemplate =
585 .isImportAddedToServiceTemplate(translateTo.getServiceTemplate().getImports(), Constants
586 .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
587 if (!isImportAddedToServiceTemplate) {
588 translateTo.getServiceTemplate().getImports()
589 .addAll(HeatToToscaUtil
590 .createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
592 NodeTemplate substitutesNodeTemplate = new NodeTemplate();
593 substitutesNodeTemplate.setType(contrailServiceTemplateTranslatedId);
594 List<String> directiveList = new ArrayList<>();
595 directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
596 substitutesNodeTemplate.setDirectives(directiveList);
597 substitutesNodeTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
598 .getToscaPropertiesSimpleConversion(translateTo.getServiceTemplate(), translateTo.
599 getResourceId(), translateTo.getResource().getProperties(),
600 substitutesNodeTemplate.getProperties(), translateTo.getHeatFileName(),
601 translateTo.getHeatOrchestrationTemplate(),
602 HeatResourcesTypes.CONTRAIL_SERVICE_INSTANCE.getHeatResource(), substitutesNodeTemplate,
603 translateTo.getContext()));
604 substitutesNodeTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
605 .getToscaPropertiesSimpleConversion(translateTo.getServiceTemplate(), translateTo.
606 getResourceId(), contrailServiceTemplateResource.getProperties(),
607 substitutesNodeTemplate.getProperties(), translateTo.getHeatFileName(),
608 translateTo.getHeatOrchestrationTemplate(),
609 HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource(), substitutesNodeTemplate,
610 translateTo.getContext()));
611 HeatToToscaUtil.mapBoolean(substitutesNodeTemplate, HeatToToscaUtil
612 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
613 HeatConstants.AVAILABILITY_ZONE_ENABLE_PROPERTY_NAME));
614 HeatToToscaUtil.mapBoolean(substitutesNodeTemplate, HeatToToscaUtil
615 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
616 HeatConstants.ORDERED_INTERFACES_PROPERTY_NAME));
618 Object sharedIpListPropertyValue =
619 contrailServiceTemplateResource.getProperties()
620 .get(HeatConstants.SHARED_IP_LIST_PROPERTY_NAME);
621 String toscaSharedIpListPropertyName = HeatToToscaUtil
622 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
623 HeatConstants.SHARED_IP_LIST_PROPERTY_NAME);
624 Optional<List<Map<String, List>>> sharedIpTranslatedSplitFun =
625 new ContrailTranslationHelper()
626 .translateFnSplitFunction(sharedIpListPropertyValue, numberOfPorts, true);
627 if (sharedIpTranslatedSplitFun.isPresent()) {
628 substitutesNodeTemplate.getProperties()
629 .put(toscaSharedIpListPropertyName, sharedIpTranslatedSplitFun.get());
631 HeatToToscaUtil.mapBooleanList(substitutesNodeTemplate, toscaSharedIpListPropertyName);
634 Object staticRouteListPropertyValue =
635 contrailServiceTemplateResource.getProperties()
636 .get(HeatConstants.STATIC_ROUTES_LIST_PROPERTY_NAME);
637 String toscaStaticRoutesListPropertyName = HeatToToscaUtil
638 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
639 HeatConstants.STATIC_ROUTES_LIST_PROPERTY_NAME);
640 Optional<List<Map<String, List>>> staticRouteTranslatedSplitFun =
641 new ContrailTranslationHelper()
642 .translateFnSplitFunction(staticRouteListPropertyValue, numberOfPorts, true);
643 if (staticRouteTranslatedSplitFun.isPresent()) {
644 substitutesNodeTemplate.getProperties()
645 .put(toscaStaticRoutesListPropertyName, staticRouteTranslatedSplitFun.get());
647 HeatToToscaUtil.mapBooleanList(substitutesNodeTemplate, toscaStaticRoutesListPropertyName);
650 Object serviceInterfaceTypeListPropertyValue =
651 contrailServiceTemplateResource.getProperties()
652 .get(HeatConstants.SERVICE_INTERFCAE_TYPE_LIST_PROPERTY_NAME);
653 String toscaServiceInterfaceTypeListPropertyName = HeatToToscaUtil
654 .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
655 HeatConstants.SERVICE_INTERFCAE_TYPE_LIST_PROPERTY_NAME);
656 Optional<List<Map<String, List>>> serviceInterfaceTypeTranslatedSplitFun =
657 new ContrailTranslationHelper()
658 .translateFnSplitFunction(serviceInterfaceTypeListPropertyValue, numberOfPorts, false);
659 serviceInterfaceTypeTranslatedSplitFun
660 .ifPresent(translatedSplitFun -> substitutesNodeTemplate.getProperties()
661 .put(toscaServiceInterfaceTypeListPropertyName, translatedSplitFun));
663 String substitutedNodeTemplateId = translateTo.getTranslatedId();
664 DataModelUtil.addNodeTemplate(translateTo.getServiceTemplate(), substitutedNodeTemplateId,
665 substitutesNodeTemplate);
666 return substitutesNodeTemplate;
669 private void addNetworkLinkRequirements(NodeType nodeType, int numberOfPorts) {
670 if (nodeType.getRequirements() == null) {
671 List<Map<String, RequirementDefinition>> requirementList = new ArrayList<>();
672 for (int i = 0; i < numberOfPorts; i++) {
673 Map<String, RequirementDefinition> requirementDefinitionMap = new HashMap<>();
674 requirementDefinitionMap.put(ToscaConstants.LINK_REQUIREMENT_ID + "_port_" + i,
675 DataModelUtil.createRequirement(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE,
676 ToscaNodeType.NATIVE_ROOT,
677 ToscaRelationshipType.NATIVE_NETWORK_LINK_TO, null));
678 requirementList.add(requirementDefinitionMap);
680 if (numberOfPorts > 0) {
681 nodeType.setRequirements(requirementList);
686 private int getServiceInstanceNumberOfPorts(Resource serviceInstanceResource) {
688 Object interfaceTypeProperty =
689 serviceInstanceResource.getProperties().get(HeatConstants.INTERFACE_LIST_PROPERTY_NAME);
690 if (interfaceTypeProperty == null) {
692 } else if (interfaceTypeProperty instanceof List) {
693 numberOfPorts = ((List) interfaceTypeProperty).size();
694 } else if (interfaceTypeProperty instanceof Map) {
699 return numberOfPorts;
702 private AttachedResourceId getServiceTemplateAttachedId(TranslateTo translateTo,
703 Resource serviceInstanceResource) {
704 Object serviceTemplateProperty =
705 serviceInstanceResource.getProperties().get("service_template");
706 Optional<AttachedResourceId> serviceTemplateId = HeatToToscaUtil
707 .extractAttachedResourceId(translateTo.getHeatFileName(),
708 translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(),
709 serviceTemplateProperty);
710 if (serviceTemplateId.isPresent()) {
711 return serviceTemplateId.get();
713 throw new CoreException(new MissingMandatoryPropertyErrorBuilder("service_template").build());