[SDC] Onboarding 1710 rebase.
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / services / heattotosca / impl / resourcetranslation / ResourceTranslationContrailServiceInstanceImpl.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation;
22
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.context.impl.MdcDataErrorMessage;
32 import org.openecomp.sdc.logging.types.LoggerConstants;
33 import org.openecomp.sdc.logging.types.LoggerErrorCode;
34 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
35 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
36 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
37 import org.openecomp.sdc.tosca.datatypes.ToscaFunctions;
38 import org.openecomp.sdc.tosca.datatypes.ToscaGroupType;
39 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
40 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
41 import org.openecomp.sdc.tosca.datatypes.model.AttributeDefinition;
42 import org.openecomp.sdc.tosca.datatypes.model.GroupDefinition;
43 import org.openecomp.sdc.tosca.datatypes.model.Import;
44 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
45 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
46 import org.openecomp.sdc.tosca.datatypes.model.ParameterDefinition;
47 import org.openecomp.sdc.tosca.datatypes.model.PropertyDefinition;
48 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
49 import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition;
50 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
51 import org.openecomp.sdc.tosca.datatypes.model.SubstitutionMapping;
52 import org.openecomp.sdc.tosca.datatypes.model.TopologyTemplate;
53 import org.openecomp.sdc.tosca.services.DataModelUtil;
54 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
55 import org.openecomp.sdc.tosca.services.ToscaConstants;
56 import org.openecomp.sdc.tosca.services.ToscaUtil;
57 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
58 import org.openecomp.sdc.tosca.services.impl.ToscaFileOutputServiceCsarImpl;
59 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
60 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
61 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslatedHeatResource;
62 import org.openecomp.sdc.translator.services.heattotosca.Constants;
63 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
64 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
65 import org.openecomp.sdc.translator.services.heattotosca.errors.MissingMandatoryPropertyErrorBuilder;
66 import org.openecomp.sdc.translator.services.heattotosca.globaltypes.GlobalTypesGenerator;
67 import org.openecomp.sdc.translator.services.heattotosca.helper.ContrailTranslationHelper;
68 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
69
70 import java.util.ArrayList;
71 import java.util.Arrays;
72 import java.util.HashMap;
73 import java.util.List;
74 import java.util.Map;
75 import java.util.Objects;
76 import java.util.Optional;
77
78 public class ResourceTranslationContrailServiceInstanceImpl extends ResourceTranslationBase {
79   protected static Logger logger =
80       (Logger) LoggerFactory.getLogger(ResourceTranslationContrailServiceInstanceImpl.class);
81
82   @Override
83   public void translate(TranslateTo translateTo) {
84
85
86     mdcDataDebugMessage.debugEntryMessage(null, null);
87
88     Resource serviceInstanceResource = translateTo.getResource();
89     AttachedResourceId contrailServiceTemplateAttached =
90         getServiceTemplateAttachedId(translateTo, serviceInstanceResource);
91     if (contrailServiceTemplateAttached.isGetResource()) {
92       String contrailServiceTemplateResourceId =
93           (String) contrailServiceTemplateAttached.getEntityId();
94       Resource contrailServiceTemplateResource = HeatToToscaUtil
95           .getResource(translateTo.getHeatOrchestrationTemplate(),
96               contrailServiceTemplateResourceId, translateTo.getHeatFileName());
97       if (!contrailServiceTemplateResource.getType()
98           .equals(HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource())) {
99         logger.warn("resource id '" + translateTo.getResourceId() + "' with type '"
100             + translateTo.getResource().getType()
101             + "+ has reference to resource '" + contrailServiceTemplateResourceId + "' with type '"
102             + contrailServiceTemplateResource.getType()
103             + "' in property service_template. Invalid type, resource type should be type of '"
104             + HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource()
105             + "', therefore this resource will be ignored in TOSCA translation.");
106
107         mdcDataDebugMessage.debugExitMessage(null, null);
108         return;
109       }
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("Resource id '" + translateTo.getResourceId() + "' with type '"
117             + translateTo.getResource().getType()
118             + "' has reference to unsupported resource '" + contrailServiceTemplateResourceId
119             + "' with type '" + contrailServiceTemplateResource.getType()
120             + "' in property 'service_template'"
121             + ", therefore this resource will be ignored in TOSCA translation.");
122
123         mdcDataDebugMessage.debugExitMessage(null, null);
124         return;
125         /*throw new CoreException(new ReferenceToUnsupportedResourceErrorBuilder
126         (translateTo.getResourceId(), translateTo.getResource().getType(),
127          contrailServiceTemplateResourceId, contrailServiceTemplateResource
128          .getType(), "service_template").build());*/
129       }
130
131       ServiceTemplate globalSubstitutionServiceTemplate =
132           translateTo.getContext().getTranslatedServiceTemplates().get(
133               Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
134       String contrailStId = ResourceTranslationContrailServiceTemplateImpl
135           .getContrailSubstitutedNodeTypeId(contrailServiceTemplateTranslatedId.get());
136       NodeType substitutedNodeType =
137           DataModelUtil.getNodeType(globalSubstitutionServiceTemplate, contrailStId);
138
139       int numberOfPorts = getServiceInstanceNumberOfPorts(serviceInstanceResource);
140       if (substitutedNodeType.getRequirements() != null
141           && substitutedNodeType.getRequirements().size() != numberOfPorts) {
142         logger.warn("More than one ServiceInstance pointing to the same ServiceTemplate '"
143             + contrailServiceTemplateResourceId + " ' with different number of interfaces."
144             + ", therefore this resource will be ignored in TOSCA translation.");
145
146         mdcDataDebugMessage.debugExitMessage(null, null);
147         return;
148       }
149
150       addNetworkLinkRequirements(substitutedNodeType, numberOfPorts);
151       NodeTemplate substitutedNodeTemplate =
152           createSubstitutedNodeTemplate(translateTo, contrailServiceTemplateResource, contrailStId,
153               numberOfPorts);
154
155       String computeNodeTypeId = new ContrailTranslationHelper()
156           .getComputeNodeTypeId(contrailServiceTemplateResource, contrailServiceTemplateResourceId,
157               contrailServiceTemplateTranslatedId.get(), translateTo.getContext());
158       boolean orderedInterfaces = getOrderedInterfaces(contrailServiceTemplateResource);
159       ServiceTemplate nestedServiceTemplate =
160           createNestedServiceTemplate(translateTo, computeNodeTypeId, contrailStId,
161               substitutedNodeTemplate, orderedInterfaces);
162       addAbstractSubstitutionProperty(translateTo, substitutedNodeTemplate.getProperties(),
163           nestedServiceTemplate, contrailServiceTemplateResource);
164       translateTo.getContext().getTranslatedServiceTemplates().put(new ContrailTranslationHelper()
165           .getSubstitutionContrailServiceTemplateMetadata(translateTo.getHeatFileName(),
166               translateTo.getTranslatedId()), nestedServiceTemplate);
167
168     } else {
169       logger.warn("Heat resource: '" + translateTo.getResourceId() + "' with type: '"
170           + translateTo.getResource().getType()
171           + "' include 'service_template' property without 'get_resource' function, currently not"
172           + " supported, therefore this resource will be ignored in TOSCA translation.");
173     }
174
175     mdcDataDebugMessage.debugExitMessage(null, null);
176   }
177
178   private void addAbstractSubstitutionProperty(TranslateTo translateTo,
179                                                Map<String, Object> substitutionProperties,
180                                                ServiceTemplate nestedServiceTemplate,
181                                                Resource contrailServiceTemplateResource) {
182
183
184     mdcDataDebugMessage.debugEntryMessage(null, null);
185
186     Map<String, Object> innerProps = new HashMap<>();
187     innerProps.put(ToscaConstants.SUBSTITUTE_SERVICE_TEMPLATE_PROPERTY_NAME,
188         ToscaUtil.getServiceTemplateFileName(nestedServiceTemplate));
189
190     Object countValue = handleScaleOutProperty(translateTo, innerProps);
191     handleServiceScalingProperty(translateTo, innerProps, contrailServiceTemplateResource);
192
193     boolean mandatory = false;
194     if (countValue instanceof Integer && (Integer) countValue > 0) {
195       mandatory = true;
196     }
197     if (countValue == null) {
198       mandatory = true;
199     }
200     innerProps.put("mandatory", mandatory);
201     substitutionProperties.put(ToscaConstants.SERVICE_TEMPLATE_FILTER_PROPERTY_NAME, innerProps);
202
203     mdcDataDebugMessage.debugExitMessage(null, null);
204   }
205
206   private Object handleScaleOutProperty(TranslateTo translateTo, Map<String, Object> innerProps) {
207
208
209     mdcDataDebugMessage.debugEntryMessage(null, null);
210
211     Object scaleOutPropertyValue =
212         translateTo.getResource().getProperties().get(HeatConstants.SCALE_OUT_PROPERTY_NAME);
213     Object countValue = null;
214     if (scaleOutPropertyValue != null && scaleOutPropertyValue instanceof Map) {
215       countValue = TranslatorHeatToToscaPropertyConverter
216           .getToscaPropertyValue(translateTo.getServiceTemplate(), translateTo.getTranslatedId(),
217               Constants.MAX_INSTANCES_PROPERTY_NAME,
218               ((Map) scaleOutPropertyValue).get(Constants.MAX_INSTANCES_PROPERTY_NAME), null,
219               translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(), null,
220               translateTo.getContext());
221       if (countValue != null) {
222         innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, countValue);
223       } else {
224         innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
225       }
226     } else {
227       innerProps.put(ToscaConstants.COUNT_PROPERTY_NAME, 1);
228     }
229
230     mdcDataDebugMessage.debugExitMessage(null, null);
231     return countValue;
232   }
233
234   private void handleServiceScalingProperty(TranslateTo translateTo, Map<String, Object> innerProps,
235                                             Resource contrailServiceTemplateResource) {
236
237
238     mdcDataDebugMessage.debugEntryMessage(null, null);
239
240     Object serviceScalingPropertyValue = contrailServiceTemplateResource.getProperties()
241         .get(HeatConstants.SERVICE_SCALING_PROPERTY_NAME);
242     Object serviceScalingValue = null;
243     if (serviceScalingPropertyValue != null) {
244       serviceScalingValue = TranslatorHeatToToscaPropertyConverter
245           .getToscaPropertyValue(translateTo.getServiceTemplate(), translateTo.getTranslatedId(),
246               HeatConstants.SERVICE_SCALING_PROPERTY_NAME, serviceScalingPropertyValue, null,
247               translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(), null,
248               translateTo.getContext());
249       if (serviceScalingValue != null) {
250         innerProps.put(ToscaConstants.SCALING_ENABLED_PROPERTY_NAME,
251             (HeatBoolean.isValueBoolean(serviceScalingValue)) ? HeatBoolean
252                 .eval(serviceScalingValue) : serviceScalingValue);
253       }
254     }
255
256     mdcDataDebugMessage.debugExitMessage(null, null);
257   }
258
259   private boolean getOrderedInterfaces(Resource contrailServiceTemplate) {
260
261
262     mdcDataDebugMessage.debugEntryMessage(null, null);
263
264     Object orderedInterfaces = contrailServiceTemplate.getProperties().get("ordered_interfaces");
265     if (orderedInterfaces == null) {
266       mdcDataDebugMessage.debugExitMessage(null, null);
267       return false;
268     }
269     if (orderedInterfaces instanceof String) {
270       mdcDataDebugMessage.debugExitMessage(null, null);
271       return HeatBoolean.eval(orderedInterfaces);
272     }
273     //if get_param, set default value to true
274     mdcDataDebugMessage.debugExitMessage(null, null);
275     return true;
276   }
277
278   private ServiceTemplate createNestedServiceTemplate(TranslateTo translateTo,
279                                                       String computeNodeTypeId,
280                                                       String substitutedNodeTypeId,
281                                                       NodeTemplate substitutedNodeTemplate,
282                                                       boolean orderedInterfaces) {
283
284
285     mdcDataDebugMessage.debugEntryMessage(null, null);
286
287     ServiceTemplate nestedSubstitutionServiceTemplate = new ServiceTemplate();
288     setNestedServiceTemplateGeneralDetails(translateTo, nestedSubstitutionServiceTemplate);
289     String heatStackGroupKey = addHeatStackGroup(translateTo, nestedSubstitutionServiceTemplate);
290     addSubstitutionMappingEntry(nestedSubstitutionServiceTemplate, substitutedNodeTypeId);
291
292     handleInputParameters(nestedSubstitutionServiceTemplate, translateTo);
293     String computeNodeTemplateId =
294         handleComputeNodeTemplate(translateTo, computeNodeTypeId, nestedSubstitutionServiceTemplate,
295             heatStackGroupKey);
296     handleOutputParameters(nestedSubstitutionServiceTemplate, computeNodeTemplateId, translateTo);
297     handleServiceInstanceInterfaces(translateTo, nestedSubstitutionServiceTemplate,
298         substitutedNodeTemplate, heatStackGroupKey, orderedInterfaces, computeNodeTemplateId);
299
300     mdcDataDebugMessage.debugExitMessage(null, null);
301     return nestedSubstitutionServiceTemplate;
302   }
303
304   private void handleOutputParameters(ServiceTemplate nestedSubstitutionServiceTemplate,
305                                       String nodeTemplateId, TranslateTo translateTo) {
306
307
308     mdcDataDebugMessage.debugEntryMessage(null, null);
309
310     if (nodeTemplateId == null) {
311       return;
312     }
313     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
314
315     Optional<NodeType> contrailAbstractNodeType =
316         toscaAnalyzerService.fetchNodeType(ToscaNodeType.CONTRAIL_ABSTRACT_SUBSTITUTE, translateTo
317             .getContext().getGlobalServiceTemplates().values());
318
319     if (!contrailAbstractNodeType.isPresent()) {
320       return;
321     }
322     Map<String, AttributeDefinition> contrailAbstractAttributes =
323         contrailAbstractNodeType.get().getAttributes();
324     Map<String, ParameterDefinition> nestedSubstitutionServiceTemplateOutputs = new HashMap<>();
325
326     if (contrailAbstractAttributes == null) {
327       return;
328     }
329
330     for (String attributeKey : contrailAbstractAttributes.keySet()) {
331       AttributeDefinition abstractAttributeDef = contrailAbstractAttributes.get(attributeKey);
332       if (abstractAttributeDef != null) {
333         Map<String, List> outputValue = new HashMap<>();
334         List outputGetAttributeList = new ArrayList<>();
335         outputGetAttributeList.add(nodeTemplateId);
336         outputGetAttributeList.add(attributeKey);
337         outputValue.put(ToscaFunctions.GET_ATTRIBUTE.getDisplayName(), outputGetAttributeList);
338         nestedSubstitutionServiceTemplateOutputs.put(attributeKey,
339             DataModelUtil.convertAttributeDefToParameterDef(abstractAttributeDef, outputValue));
340       }
341     }
342     if (!nestedSubstitutionServiceTemplateOutputs.isEmpty()) {
343       nestedSubstitutionServiceTemplate.getTopology_template()
344           .setOutputs(nestedSubstitutionServiceTemplateOutputs);
345     }
346
347     mdcDataDebugMessage.debugExitMessage(null, null);
348   }
349
350   private void handleServiceInstanceInterfaces(TranslateTo translateTo,
351                                                ServiceTemplate nestedSubstitutionServiceTemplate,
352                                                NodeTemplate substitutedNodeTemplate,
353                                                String heatStackGroupKey, boolean orderedInterfaces,
354                                                String computeNodeTemplateId) {
355
356
357     mdcDataDebugMessage.debugEntryMessage(null, null);
358
359     Resource serviceInstanceResource = translateTo.getResource();
360     Object interfaceListProperty =
361         serviceInstanceResource.getProperties().get(HeatConstants.INTERFACE_LIST_PROPERTY_NAME);
362     if (interfaceListProperty == null) {
363       return;
364     }
365     if (interfaceListProperty instanceof List) {
366       for (int index = 0; index < ((List) interfaceListProperty).size(); index++) {
367         Object interfaceEntry = ((List) interfaceListProperty).get(index);
368         handleInterface(translateTo, interfaceEntry, index, nestedSubstitutionServiceTemplate,
369             heatStackGroupKey, substitutedNodeTemplate, orderedInterfaces, computeNodeTemplateId);
370       }
371     } else if (interfaceListProperty instanceof Map) {
372       handleInterface(translateTo, interfaceListProperty, null, nestedSubstitutionServiceTemplate,
373           heatStackGroupKey, substitutedNodeTemplate, orderedInterfaces, computeNodeTemplateId);
374     }
375
376     mdcDataDebugMessage.debugExitMessage(null, null);
377   }
378
379   private void handleInterface(TranslateTo translateTo, Object interfacePropertyValue,
380                                Integer index,
381                                ServiceTemplate nestedSubstitutionServiceTemplate,
382                                String heatStackGroupKey, NodeTemplate substitutedNodeTemplate,
383                                boolean orderedInterfaces, String computeNodeTemplateId) {
384
385
386     mdcDataDebugMessage.debugEntryMessage(null, null);
387
388     if (index == null) {
389       index = new Integer(0);
390     }
391     NodeTemplate portNodeTemplate =
392         createPortNodeTemplate(index, orderedInterfaces, computeNodeTemplateId);
393     String portNodeTemplateId = Constants.SERVICE_INSTANCE_PORT_PREFIX + index;
394     String portReqMappingKey = Constants.SERVICE_INSTANCE_LINK_PREFIX + portNodeTemplateId;
395
396     DataModelUtil
397         .addNodeTemplate(nestedSubstitutionServiceTemplate, portNodeTemplateId, portNodeTemplate);
398     updateSubstitutionMappingRequirement(nestedSubstitutionServiceTemplate, portReqMappingKey,
399         portNodeTemplateId);
400     updateHeatStackGroup(nestedSubstitutionServiceTemplate, heatStackGroupKey, portNodeTemplateId);
401     connectPortToNetwork(translateTo, interfacePropertyValue, substitutedNodeTemplate,
402         portReqMappingKey);
403
404     mdcDataDebugMessage.debugExitMessage(null, null);
405   }
406
407   private void connectPortToNetwork(TranslateTo translateTo, Object interfacePropertyValue,
408                                     NodeTemplate substitutedNodeTemplate,
409                                     String portReqMappingKey) {
410
411
412     mdcDataDebugMessage.debugEntryMessage(null, null);
413
414     List<String> validNetworksForConnections = Arrays
415         .asList(HeatResourcesTypes.NEUTRON_NET_RESOURCE_TYPE.getHeatResource(),
416             HeatResourcesTypes.CONTRAIL_VIRTUAL_NETWORK_RESOURCE_TYPE.getHeatResource());
417
418     if (interfacePropertyValue instanceof Map) {
419       Object virtualNetworkValue =
420           ((Map) interfacePropertyValue).get(HeatConstants.VIRTUAL_NETWORK_PROPERTY_NAME);
421       if (virtualNetworkValue != null) {
422         Optional<AttachedResourceId> networkAttachedResourceId = HeatToToscaUtil
423             .extractAttachedResourceId(translateTo.getHeatFileName(),
424                 translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(),
425                 virtualNetworkValue);
426         if (networkAttachedResourceId.isPresent()) {
427           Optional<String> networkResourceId =
428               HeatToToscaUtil.getContrailAttachedHeatResourceId(networkAttachedResourceId.get());
429           if (networkResourceId.isPresent()) {
430             Resource networkResource = HeatToToscaUtil
431                 .getResource(translateTo.getHeatOrchestrationTemplate(), networkResourceId.get(),
432                     translateTo.getHeatFileName());
433             if (validNetworksForConnections.contains(networkResource.getType())) {
434               Optional<String> networkTranslatedId =
435                   getResourceTranslatedId(translateTo.getHeatFileName(),
436                       translateTo.getHeatOrchestrationTemplate(), networkResourceId.get(),
437                       translateTo.getContext());
438               networkTranslatedId
439                   .ifPresent(
440                       translatedId -> addLinkToNetworkRequirementAssignment(substitutedNodeTemplate,
441                           translatedId, portReqMappingKey));
442
443             } else {
444               logger.warn("Heat resource " + translateTo.getResourceId() + " with type "
445                   + translateTo.getResource().getType()
446                   + " has connection to invalid/not supported network resource, therefore, this "
447                   + "connection will be ignored in the translation.");
448             }
449           } else if (networkAttachedResourceId.get().isGetParam()
450               && networkAttachedResourceId.get().getEntityId() instanceof String) {
451             TranslatedHeatResource
452                 translatedSharedResourceId =
453                 translateTo.getContext().getHeatSharedResourcesByParam()
454                     .get(networkAttachedResourceId.get().getEntityId());
455             if (Objects.nonNull(translatedSharedResourceId)
456                 && !HeatToToscaUtil.isHeatFileNested(translateTo, translateTo.getHeatFileName())) {
457               addLinkToNetworkRequirementAssignment(substitutedNodeTemplate,
458                   translatedSharedResourceId.getTranslatedId(), portReqMappingKey);
459             }
460           } else {
461             logger.warn("Heat resource: '" + translateTo.getResourceId() + "' with type: '"
462                 + translateTo.getResource().getType()
463                 + "' include 'virtual_network' property with value '"
464                 + virtualNetworkValue.toString()
465                 + "', the connection to this network wasn't found/not supported therefore this "
466                 + "connection will be ignored in TOSCA translation for this property.");
467           }
468         }
469       } else {
470         logger.warn("Heat resource: '" + translateTo.getResourceId() + "' with type: '"
471             + translateTo.getResource().getType()
472             + "' missing 'virtual_network' property in 'interface_list' entry, therefore, no "
473             + "network connection is define for this entry.");
474         //throw new CoreException(new
475         // MissingMandatoryPropertyErrorBuilder("virtual_network").build());
476       }
477     }
478
479     mdcDataDebugMessage.debugExitMessage(null, null);
480   }
481
482   private NodeTemplate createPortNodeTemplate(Integer index, boolean orderedInterfaces,
483                                               String computeNodeTemplateId) {
484
485
486     mdcDataDebugMessage.debugEntryMessage(null, null);
487
488     NodeTemplate portNodeTemplate = new NodeTemplate();
489     portNodeTemplate.setType(ToscaNodeType.CONTRAIL_PORT);
490     Map<String, Object> portProperties = new HashMap<>();
491     portProperties.put("static_routes", DataModelUtil
492         .createGetInputPropertyValueFromListParameter("interface_list", index, "static_routes"));
493     portProperties.put("virtual_network", DataModelUtil
494         .createGetInputPropertyValueFromListParameter("interface_list", index, "virtual_network"));
495     portProperties.put("allowed_address_pairs", DataModelUtil
496         .createGetInputPropertyValueFromListParameter("interface_list", index,
497             "allowed_address_pairs"));
498     portProperties.put("ip_address", DataModelUtil
499         .createGetInputPropertyValueFromListParameter("interface_list", index, "ip_address"));
500     portProperties.put("static_route",
501         DataModelUtil.createGetInputPropertyValueFromListParameter("static_routes_list", index));
502     portProperties.put("shared_ip",
503         DataModelUtil.createGetInputPropertyValueFromListParameter("shared_ip_list", index));
504     portProperties.put("interface_type", DataModelUtil
505         .createGetInputPropertyValueFromListParameter("service_interface_type_list", index));
506     if (orderedInterfaces) {
507       portProperties.put("order", index);
508     }
509     portNodeTemplate.setProperties(portProperties);
510     DataModelUtil.addBindingReqFromPortToCompute(computeNodeTemplateId, portNodeTemplate);
511
512     mdcDataDebugMessage.debugExitMessage(null, null);
513     return portNodeTemplate;
514   }
515
516
517   private void addLinkToNetworkRequirementAssignment(NodeTemplate nodeTemplate,
518                                                      String connectedNodeTranslatedId,
519                                                      String requirementId) {
520
521
522     mdcDataDebugMessage.debugEntryMessage(null, null);
523
524     if (nodeTemplate == null || connectedNodeTranslatedId == null) {
525       return;
526     }
527
528     RequirementAssignment requirement = new RequirementAssignment();
529     requirement.setCapability(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE);
530     requirement.setRelationship(ToscaRelationshipType.NATIVE_NETWORK_LINK_TO);
531     requirement.setNode(connectedNodeTranslatedId);
532     DataModelUtil.addRequirementAssignment(nodeTemplate, requirementId, requirement);
533
534     mdcDataDebugMessage.debugExitMessage(null, null);
535   }
536
537   private void updateHeatStackGroup(ServiceTemplate serviceTemplate, String heatStackGroupKey,
538                                     String memberId) {
539
540
541     mdcDataDebugMessage.debugEntryMessage(null, null);
542
543     serviceTemplate.getTopology_template().getGroups().get(heatStackGroupKey).getMembers()
544         .add(memberId);
545
546     mdcDataDebugMessage.debugExitMessage(null, null);
547   }
548
549   private void updateSubstitutionMappingRequirement(ServiceTemplate serviceTemplate,
550                                                     String portReqMappingKey,
551                                                     String portNodeTemplateId) {
552
553
554     mdcDataDebugMessage.debugEntryMessage(null, null);
555
556     List<String> portReqMappingValue = new ArrayList<>();
557     portReqMappingValue.add(portNodeTemplateId);
558     portReqMappingValue.add(ToscaConstants.LINK_REQUIREMENT_ID);
559     DataModelUtil
560         .addSubstitutionMappingReq(serviceTemplate, portReqMappingKey, portReqMappingValue);
561
562     mdcDataDebugMessage.debugExitMessage(null, null);
563   }
564
565   private void addSubstitutionMappingEntry(ServiceTemplate nestedSubstitutionServiceTemplate,
566                                            String substitutedNodeTypeId) {
567
568
569     mdcDataDebugMessage.debugEntryMessage(null, null);
570
571     SubstitutionMapping substitutionMappings = new SubstitutionMapping();
572     substitutionMappings.setNode_type(substitutedNodeTypeId);
573     DataModelUtil.addSubstitutionMapping(nestedSubstitutionServiceTemplate, substitutionMappings);
574
575     mdcDataDebugMessage.debugExitMessage(null, null);
576   }
577
578   private void handleInputParameters(ServiceTemplate nestedSubstitutionServiceTemplate,
579                                      TranslateTo translateTo) {
580
581
582     mdcDataDebugMessage.debugEntryMessage(null, null);
583
584     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
585
586     Optional<NodeType> contrailAbstractNodeType =
587         toscaAnalyzerService.fetchNodeType(ToscaNodeType.CONTRAIL_ABSTRACT_SUBSTITUTE, translateTo
588             .getContext().getGlobalServiceTemplates().values());
589     Map<String, ParameterDefinition> nestedSubstitutionServiceTemplateInputs = new HashMap<>();
590     if (contrailAbstractNodeType.isPresent()) {
591       Map<String, PropertyDefinition> contrailAbstractProperties =
592           contrailAbstractNodeType.get().getProperties();
593
594       for (String propertyKey : contrailAbstractProperties.keySet()) {
595         PropertyDefinition abstractPropertyDef = contrailAbstractProperties.get(propertyKey);
596         if (abstractPropertyDef != null) {
597           nestedSubstitutionServiceTemplateInputs
598               .put(propertyKey,
599                   DataModelUtil.convertPropertyDefToParameterDef(abstractPropertyDef));
600
601         }
602       }
603     }
604     if (!nestedSubstitutionServiceTemplateInputs.isEmpty()) {
605       nestedSubstitutionServiceTemplate.getTopology_template()
606           .setInputs(nestedSubstitutionServiceTemplateInputs);
607     }
608
609     mdcDataDebugMessage.debugExitMessage(null, null);
610   }
611
612   private String handleComputeNodeTemplate(TranslateTo translateTo, String computeNodeTypeId,
613                                            ServiceTemplate nestedSubstitutionServiceTemplate,
614                                            String heatStackGroupKey) {
615
616
617     mdcDataDebugMessage.debugEntryMessage(null, null);
618
619     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
620     Optional<NodeType> contrailComputeNodeType = toscaAnalyzerService
621         .fetchNodeType(ToscaNodeType.CONTRAIL_COMPUTE,
622             translateTo.getContext().getGlobalServiceTemplates().values());
623
624     Map<String, Object> computeNodeTemplateProperties = null;
625     if (contrailComputeNodeType.isPresent()) {
626       Map<String, PropertyDefinition> contrailComputeProperties =
627           contrailComputeNodeType.get().getProperties();
628       computeNodeTemplateProperties = new HashMap<>();
629
630       if (contrailComputeProperties != null) {
631         for (String computePropertyKey : contrailComputeProperties.keySet()) {
632           Map getInputProperty = new HashMap<>();
633           getInputProperty.put(ToscaFunctions.GET_INPUT.getDisplayName(), computePropertyKey);
634           computeNodeTemplateProperties.put(computePropertyKey, getInputProperty);
635         }
636       }
637     }
638
639     NodeTemplate computeNodeTemplate = new NodeTemplate();
640     computeNodeTemplate.setType(computeNodeTypeId);
641     if (!computeNodeTemplateProperties.isEmpty()) {
642       computeNodeTemplate.setProperties(computeNodeTemplateProperties);
643     }
644     String computeNodeTemplateId = translateTo.getTranslatedId();
645     DataModelUtil.addNodeTemplate(nestedSubstitutionServiceTemplate, computeNodeTemplateId,
646         computeNodeTemplate);
647     nestedSubstitutionServiceTemplate.getTopology_template().getGroups().get(heatStackGroupKey)
648         .getMembers().add(computeNodeTemplateId);
649
650     mdcDataDebugMessage.debugExitMessage(null, null);
651     return computeNodeTemplateId;
652   }
653
654   private String addHeatStackGroup(TranslateTo translateTo, ServiceTemplate serviceTemplate) {
655
656
657     mdcDataDebugMessage.debugEntryMessage(null, null);
658
659     GroupDefinition serviceInstanceGroupDefinition = new GroupDefinition();
660     serviceInstanceGroupDefinition.setType(ToscaGroupType.HEAT_STACK);
661     Map<String, Object> groupProperties = new HashMap<>();
662     groupProperties.put("heat_file",
663         "../" + (new ToscaFileOutputServiceCsarImpl()).getArtifactsFolderName() + "/"
664             + translateTo.getHeatFileName());
665     serviceInstanceGroupDefinition.setProperties(groupProperties);
666     serviceInstanceGroupDefinition.setMembers(new ArrayList<>());
667     String heatStackGroupKey = translateTo.getTranslatedId() + "_group";
668     DataModelUtil.addGroupDefinitionToTopologyTemplate(serviceTemplate, heatStackGroupKey,
669         serviceInstanceGroupDefinition);
670
671     mdcDataDebugMessage.debugExitMessage(null, null);
672     return heatStackGroupKey;
673   }
674
675
676   private void setNestedServiceTemplateGeneralDetails(TranslateTo translateTo,
677                                                       ServiceTemplate
678                                                           nestedSubstitutionServiceTemplate) {
679     mdcDataDebugMessage.debugEntryMessage(null, null);
680
681     Map<String, String> nestedTemplateMetadata = new HashMap<>();
682     String nestedTemplateName = new ContrailTranslationHelper()
683         .getSubstitutionContrailServiceTemplateMetadata(translateTo.getHeatFileName(),
684             translateTo.getResourceId());
685     nestedTemplateMetadata.put(ToscaConstants.ST_METADATA_TEMPLATE_NAME, nestedTemplateName);
686     nestedSubstitutionServiceTemplate.setMetadata(nestedTemplateMetadata);
687     nestedSubstitutionServiceTemplate
688         .setTosca_definitions_version(ToscaConstants.TOSCA_DEFINITIONS_VERSION);
689     nestedSubstitutionServiceTemplate.setTopology_template(new TopologyTemplate());
690     List<Map<String, Import>> globalTypesImportList =
691         GlobalTypesGenerator.getGlobalTypesImportList();
692     globalTypesImportList.addAll(
693         HeatToToscaUtil.createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
694     nestedSubstitutionServiceTemplate.setImports(globalTypesImportList);
695     mdcDataDebugMessage.debugExitMessage(null, null);
696   }
697
698   private NodeTemplate createSubstitutedNodeTemplate(TranslateTo translateTo,
699                                                      Resource contrailServiceTemplateResource,
700                                                      String contrailServiceTemplateTranslatedId,
701                                                      int numberOfPorts) {
702
703
704     mdcDataDebugMessage.debugEntryMessage(null, null);
705     boolean isImportAddedToServiceTemplate =
706         DataModelUtil
707             .isImportAddedToServiceTemplate(translateTo.getServiceTemplate().getImports(), Constants
708                 .GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME);
709     if (!isImportAddedToServiceTemplate) {
710       translateTo.getServiceTemplate().getImports()
711           .addAll(HeatToToscaUtil
712               .createImportList(Constants.GLOBAL_SUBSTITUTION_TYPES_TEMPLATE_NAME));
713     }
714     NodeTemplate substitutesNodeTemplate = new NodeTemplate();
715     substitutesNodeTemplate.setType(contrailServiceTemplateTranslatedId);
716     List<String> directiveList = new ArrayList<>();
717     directiveList.add(ToscaConstants.NODE_TEMPLATE_DIRECTIVE_SUBSTITUTABLE);
718     substitutesNodeTemplate.setDirectives(directiveList);
719     substitutesNodeTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
720         .getToscaPropertiesSimpleConversion(translateTo.getServiceTemplate(), translateTo.
721                 getResourceId(), translateTo.getResource().getProperties(),
722             substitutesNodeTemplate.getProperties(), translateTo.getHeatFileName(),
723             translateTo.getHeatOrchestrationTemplate(),
724             HeatResourcesTypes.CONTRAIL_SERVICE_INSTANCE.getHeatResource(), substitutesNodeTemplate,
725             translateTo.getContext()));
726     substitutesNodeTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
727         .getToscaPropertiesSimpleConversion(translateTo.getServiceTemplate(), translateTo.
728                 getResourceId(), contrailServiceTemplateResource.getProperties(),
729             substitutesNodeTemplate.getProperties(), translateTo.getHeatFileName(),
730             translateTo.getHeatOrchestrationTemplate(),
731             HeatResourcesTypes.CONTRAIL_SERVICE_TEMPLATE.getHeatResource(), substitutesNodeTemplate,
732             translateTo.getContext()));
733     HeatToToscaUtil.mapBoolean(substitutesNodeTemplate, HeatToToscaUtil
734         .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
735             HeatConstants.AVAILABILITY_ZONE_ENABLE_PROPERTY_NAME));
736     HeatToToscaUtil.mapBoolean(substitutesNodeTemplate, HeatToToscaUtil
737         .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
738             HeatConstants.ORDERED_INTERFACES_PROPERTY_NAME));
739
740     Object sharedIpListPropertyValue =
741         contrailServiceTemplateResource.getProperties()
742             .get(HeatConstants.SHARED_IP_LIST_PROPERTY_NAME);
743     String toscaSharedIpListPropertyName = HeatToToscaUtil
744         .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
745             HeatConstants.SHARED_IP_LIST_PROPERTY_NAME);
746     Optional<List<Map<String, List>>> sharedIpTranslatedSplitFun =
747         new ContrailTranslationHelper()
748             .translateFnSplitFunction(sharedIpListPropertyValue, numberOfPorts, true);
749     if (sharedIpTranslatedSplitFun.isPresent()) {
750       substitutesNodeTemplate.getProperties()
751           .put(toscaSharedIpListPropertyName, sharedIpTranslatedSplitFun.get());
752     } else {
753       HeatToToscaUtil.mapBooleanList(substitutesNodeTemplate, toscaSharedIpListPropertyName);
754     }
755
756     Object staticRouteListPropertyValue =
757         contrailServiceTemplateResource.getProperties()
758             .get(HeatConstants.STATIC_ROUTES_LIST_PROPERTY_NAME);
759     String toscaStaticRoutesListPropertyName = HeatToToscaUtil
760         .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
761             HeatConstants.STATIC_ROUTES_LIST_PROPERTY_NAME);
762     Optional<List<Map<String, List>>> staticRouteTranslatedSplitFun =
763         new ContrailTranslationHelper()
764             .translateFnSplitFunction(staticRouteListPropertyValue, numberOfPorts, true);
765     if (staticRouteTranslatedSplitFun.isPresent()) {
766       substitutesNodeTemplate.getProperties()
767           .put(toscaStaticRoutesListPropertyName, staticRouteTranslatedSplitFun.get());
768     } else {
769       HeatToToscaUtil.mapBooleanList(substitutesNodeTemplate, toscaStaticRoutesListPropertyName);
770     }
771
772     Object serviceInterfaceTypeListPropertyValue =
773         contrailServiceTemplateResource.getProperties()
774             .get(HeatConstants.SERVICE_INTERFCAE_TYPE_LIST_PROPERTY_NAME);
775     String toscaServiceInterfaceTypeListPropertyName = HeatToToscaUtil
776         .getToscaPropertyName(translateTo.getContext(), contrailServiceTemplateResource.getType(),
777             HeatConstants.SERVICE_INTERFCAE_TYPE_LIST_PROPERTY_NAME);
778     Optional<List<Map<String, List>>> serviceInterfaceTypeTranslatedSplitFun =
779         new ContrailTranslationHelper()
780             .translateFnSplitFunction(serviceInterfaceTypeListPropertyValue, numberOfPorts, false);
781     serviceInterfaceTypeTranslatedSplitFun
782         .ifPresent(translatedSplitFun -> substitutesNodeTemplate.getProperties()
783             .put(toscaServiceInterfaceTypeListPropertyName, translatedSplitFun));
784
785     String substitutedNodeTemplateId = translateTo.getTranslatedId();
786     DataModelUtil.addNodeTemplate(translateTo.getServiceTemplate(), substitutedNodeTemplateId,
787         substitutesNodeTemplate);
788
789     mdcDataDebugMessage.debugExitMessage(null, null);
790     return substitutesNodeTemplate;
791   }
792
793   private void addNetworkLinkRequirements(NodeType nodeType, int numberOfPorts) {
794
795
796     mdcDataDebugMessage.debugEntryMessage(null, null);
797
798     if (nodeType.getRequirements() == null) {
799       List<Map<String, RequirementDefinition>> requirementList = new ArrayList<>();
800       for (int i = 0; i < numberOfPorts; i++) {
801         Map<String, RequirementDefinition> requirementDefinitionMap = new HashMap<>();
802         requirementDefinitionMap.put(ToscaConstants.LINK_REQUIREMENT_ID + "_port_" + i,
803             DataModelUtil.createRequirement(ToscaCapabilityType.NATIVE_NETWORK_LINKABLE,
804                 ToscaNodeType.NATIVE_ROOT,
805                 ToscaRelationshipType.NATIVE_NETWORK_LINK_TO, null));
806         requirementList.add(requirementDefinitionMap);
807       }
808       if (numberOfPorts > 0) {
809         nodeType.setRequirements(requirementList);
810       }
811     }
812
813     mdcDataDebugMessage.debugExitMessage(null, null);
814   }
815
816   private int getServiceInstanceNumberOfPorts(Resource serviceInstanceResource) {
817
818
819     mdcDataDebugMessage.debugEntryMessage(null, null);
820
821     int numberOfPorts;
822     Object interfaceTypeProperty =
823         serviceInstanceResource.getProperties().get(HeatConstants.INTERFACE_LIST_PROPERTY_NAME);
824     if (interfaceTypeProperty == null) {
825       numberOfPorts = 0;
826     } else if (interfaceTypeProperty instanceof List) {
827       numberOfPorts = ((List) interfaceTypeProperty).size();
828     } else if (interfaceTypeProperty instanceof Map) {
829       numberOfPorts = 1;
830     } else {
831       numberOfPorts = 0;
832     }
833
834     mdcDataDebugMessage.debugExitMessage(null, null);
835     return numberOfPorts;
836   }
837
838   private AttachedResourceId getServiceTemplateAttachedId(TranslateTo translateTo,
839                                                           Resource serviceInstanceResource) {
840
841
842     mdcDataDebugMessage.debugEntryMessage(null, null);
843
844     Object serviceTemplateProperty =
845         serviceInstanceResource.getProperties().get("service_template");
846     Optional<AttachedResourceId> serviceTemplateId = HeatToToscaUtil
847         .extractAttachedResourceId(translateTo.getHeatFileName(),
848             translateTo.getHeatOrchestrationTemplate(), translateTo.getContext(),
849             serviceTemplateProperty);
850     if (serviceTemplateId.isPresent()) {
851       mdcDataDebugMessage.debugExitMessage(null, null);
852       return serviceTemplateId.get();
853     } else {
854       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
855           LoggerTragetServiceName.GET_SERVICE_TEMPLATE, ErrorLevel.ERROR.name(),
856           LoggerErrorCode.DATA_ERROR.getErrorCode(),
857           LoggerErrorDescription.MISSING_MANDATORY_PROPERTY);
858       throw new CoreException(new MissingMandatoryPropertyErrorBuilder("service_template").build());
859     }
860   }
861
862
863 }