Toggle for SRIOV
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / services / heattotosca / impl / resourcetranslation / ResourceTranslationNovaServerImpl.java
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation;
18
19 import static org.openecomp.sdc.heat.services.HeatConstants.SNAPSHOT_ID_PROPERTY_NAME;
20 import static org.openecomp.sdc.heat.services.HeatConstants.VOL_ID_PROPERTY_NAME;
21
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Objects;
29 import java.util.Optional;
30
31 import org.apache.commons.collections4.CollectionUtils;
32 import org.apache.commons.collections4.MapUtils;
33 import org.onap.sdc.tosca.datatypes.model.GroupDefinition;
34 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
35 import org.onap.sdc.tosca.datatypes.model.NodeType;
36 import org.onap.sdc.tosca.datatypes.model.RelationshipTemplate;
37 import org.onap.sdc.tosca.datatypes.model.RequirementAssignment;
38 import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
39 import org.onap.sdc.tosca.datatypes.model.CapabilityDefinition;
40 import org.openecomp.sdc.common.togglz.ToggleableFeature;
41 import org.openecomp.sdc.heat.datatypes.HeatBoolean;
42 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
43 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
44 import org.openecomp.sdc.heat.datatypes.model.PropertiesMapKeyTypes;
45 import org.openecomp.sdc.heat.datatypes.model.Resource;
46 import org.openecomp.sdc.heat.datatypes.model.ResourceReferenceFunctions;
47 import org.openecomp.sdc.heat.services.HeatConstants;
48 import org.openecomp.sdc.logging.api.Logger;
49 import org.openecomp.sdc.logging.api.LoggerFactory;
50 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
51 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
52 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
53 import org.openecomp.sdc.tosca.services.DataModelUtil;
54 import org.openecomp.sdc.tosca.services.ToscaConstants;
55 import org.openecomp.sdc.tosca.services.ToscaUtil;
56 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
57 import org.openecomp.sdc.translator.datatypes.heattotosca.PropertyRegexMatcher;
58 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
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.datatypes.heattotosca.unifiedmodel.consolidation.ComputeConsolidationDataHandler;
62 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationDataUtil;
63 import org.openecomp.sdc.translator.services.heattotosca.Constants;
64 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
65 import org.openecomp.sdc.translator.services.heattotosca.NameExtractor;
66 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
67 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
68
69 public class ResourceTranslationNovaServerImpl extends ResourceTranslationBase {
70     private static final Logger logger = LoggerFactory.getLogger(ResourceTranslationNovaServerImpl.class);
71     private static final String BLOCK_DEVICE_MAPPING_DEVICE_NAME = "device_name";
72     private static final String VOL_ATTACH_DEVICE_PROPERTY_NAME = "device";
73     private static final String FABRIC_CONFIGURATION_KEY = "fabric_configuration_monitoring";
74    
75
76     @Override
77     protected void translate(TranslateTo translateTo) {
78         TranslationContext context = translateTo.getContext();
79         Map<String, Object> properties = translateTo.getResource().getProperties();
80         String heatFileName = translateTo.getHeatFileName();
81         ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
82         String nodeTypeRef = createLocalNodeType(serviceTemplate, translateTo.getResource(),
83                 translateTo.getResourceId(), translateTo.getTranslatedId());
84         String serviceTemplateFileName = ToscaUtil.getServiceTemplateFileName(serviceTemplate);
85
86         context.getComputeConsolidationDataHandler().addConsolidationData(
87                 serviceTemplateFileName, nodeTypeRef, translateTo.getTranslatedId());
88
89         NodeTemplate novaNodeTemplate = new NodeTemplate();
90         novaNodeTemplate.setType(nodeTypeRef);
91         HeatOrchestrationTemplate heatOrchestrationTemplate =
92                 translateTo.getHeatOrchestrationTemplate();
93         novaNodeTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
94                 .getToscaPropertiesSimpleConversion(serviceTemplate, translateTo.getResourceId(),
95                         properties, novaNodeTemplate.getProperties(), heatFileName,
96                         heatOrchestrationTemplate, translateTo.getResource().getType(),
97                         novaNodeTemplate, context));
98         HeatToToscaUtil.mapBoolean(novaNodeTemplate, HeatToToscaUtil
99                 .getToscaPropertyName(translateTo, HeatConstants.CONFIG_DRIVE_PROPERTY_NAME));
100         manageNovaServerNetwork(translateTo, novaNodeTemplate);
101         manageNovaServerBlockDeviceMapping(translateTo, novaNodeTemplate);
102         manageNovaServerGroupMapping(translateTo, novaNodeTemplate);
103         DataModelUtil.addNodeTemplate(serviceTemplate, translateTo.getTranslatedId(), novaNodeTemplate);
104     }
105
106     private void manageNovaServerGroupMapping(TranslateTo translateTo,
107                                                      NodeTemplate novaNodeTemplate) {
108         Map properties = translateTo.getResource().getProperties();
109         if (isSchedulerHintsPropExist(properties)) {
110             Object schedulerHints = properties.get(ResourceReferenceFunctions.SCHEDULER_HINTS.getFunction());
111             if (schedulerHints instanceof Map) {
112                 addServerGroupHintsToPoliciesGroups(translateTo,
113                         novaNodeTemplate, (Map) schedulerHints);
114             } else {
115                 logger.warn("'scheduler_hints' property of resource '{}' is not valid. This property should be a map",
116                         translateTo.getResourceId());
117             }
118         }
119     }
120
121     private void addServerGroupHintsToPoliciesGroups(TranslateTo translateTo,
122                                                             NodeTemplate novaNodeTemplate,
123                                                             Map schedulerHints) {
124         for (Object hint : schedulerHints.values()) {
125             Optional<AttachedResourceId> attachedResourceId = HeatToToscaUtil
126                     .extractAttachedResourceId(translateTo.getHeatFileName(), translateTo
127                             .getHeatOrchestrationTemplate(), translateTo.getContext(), hint);
128             if (attachedResourceId.isPresent()) {
129                 AttachedResourceId serverGroupResourceId = attachedResourceId.get();
130                 Object serverGroupResourceToTranslate = serverGroupResourceId.getEntityId();
131                 if (serverGroupResourceId.isGetResource()) {
132                     addServerGroupHintGetResource(translateTo, novaNodeTemplate, serverGroupResourceToTranslate);
133                 } else if (serverGroupResourceId.isGetParam() && serverGroupResourceToTranslate instanceof String) {
134                     addServerGroupHintGetParam(translateTo, novaNodeTemplate, serverGroupResourceToTranslate);
135                 }
136             }
137         }
138     }
139
140     private void addServerGroupHintGetParam(TranslateTo translateTo, NodeTemplate novaNodeTemplate,
141                                                    Object serverGroupResourceToTranslate) {
142         TranslatedHeatResource translatedServerGroupResource = translateTo.getContext()
143                 .getHeatSharedResourcesByParam().get(serverGroupResourceToTranslate);
144         if (Objects.nonNull(translatedServerGroupResource)
145                     && !HeatToToscaUtil.isHeatFileNested(translateTo, translateTo.getHeatFileName())
146                     && isResourceTypeServerGroup(translatedServerGroupResource)) {
147             Map<String, GroupDefinition> groups =
148                     translateTo.getServiceTemplate().getTopology_template().getGroups();
149             if (MapUtils.isNotEmpty(groups) && Objects.nonNull(groups.get(translatedServerGroupResource
150                                                                                   .getTranslatedId()))) {
151                 groups.get(translatedServerGroupResource.getTranslatedId()).getMembers()
152                       .add(translateTo.getTranslatedId());
153                 //Add group Id to compute consolidation data
154                 updateComputeConsolidationDataGroup(translateTo, novaNodeTemplate,
155                         translatedServerGroupResource.getTranslatedId());
156             }
157         }
158     }
159
160     private void addServerGroupHintGetResource(TranslateTo translateTo, NodeTemplate novaNodeTemplate,
161                                                       Object serverGroupResourceToTranslate) {
162         boolean isHintOfTypeNovaServerGroup = isHintOfTypeNovaServerGroup(translateTo
163                 .getHeatOrchestrationTemplate(), serverGroupResourceToTranslate);
164         if (isHintOfTypeNovaServerGroup) {
165             addNovaServerToPolicyGroup(translateTo, (String) serverGroupResourceToTranslate, novaNodeTemplate);
166         }
167     }
168
169     private boolean isResourceTypeServerGroup(TranslatedHeatResource translatedServerGroupResource) {
170         return translatedServerGroupResource.getHeatResource().getType()
171                 .equals(HeatResourcesTypes.NOVA_SERVER_GROUP_RESOURCE_TYPE.getHeatResource());
172     }
173
174     private void updateComputeConsolidationDataGroup(TranslateTo translateTo,
175             NodeTemplate novaNodeTemplate, String groupId) {
176         ComputeConsolidationDataHandler handler = translateTo.getContext().getComputeConsolidationDataHandler();
177         handler.addGroupIdToConsolidationData(translateTo,novaNodeTemplate.getType(),
178                 translateTo.getTranslatedId(), groupId);
179     }
180
181     private boolean isHintOfTypeNovaServerGroup(HeatOrchestrationTemplate heatOrchestrationTemplate,
182                                                        Object resourceToTranslate) {
183         return heatOrchestrationTemplate.getResources().get(resourceToTranslate).getType()
184                                         .equals(HeatResourcesTypes.NOVA_SERVER_GROUP_RESOURCE_TYPE.getHeatResource());
185     }
186
187     private void addNovaServerToPolicyGroup(TranslateTo translateTo,
188                                                    String resourceToTranslate,
189                                                    NodeTemplate novaNodeTemplate) {
190         Resource serverGroup =
191                 HeatToToscaUtil.getResource(translateTo.getHeatOrchestrationTemplate(), resourceToTranslate,
192                         translateTo.getHeatFileName());
193         Optional<String> serverGroupTranslatedId = ResourceTranslationFactory.getInstance(serverGroup)
194                 .translateResource(translateTo.getHeatFileName(), translateTo.getServiceTemplate(),
195                         translateTo.getHeatOrchestrationTemplate(), serverGroup, resourceToTranslate,
196                         translateTo.getContext());
197         if (serverGroupTranslatedId.isPresent()) {
198             translateTo.getServiceTemplate().getTopology_template().getGroups().get(serverGroupTranslatedId.get())
199                        .getMembers().add(translateTo.getTranslatedId());
200             updateComputeConsolidationDataGroup(translateTo, novaNodeTemplate, serverGroupTranslatedId.get());
201         }
202     }
203
204     private boolean isSchedulerHintsPropExist(Map properties) {
205         return !MapUtils.isEmpty(properties)
206                        && Objects.nonNull(properties.get(ResourceReferenceFunctions.SCHEDULER_HINTS.getFunction()));
207     }
208
209     private void manageNovaServerBlockDeviceMapping(TranslateTo translateTo,
210                                                            NodeTemplate novaNodeTemplate) {
211         Resource resource = translateTo.getResource();
212         List<Map<String, Object>> blockDeviceMappingList = getBlockDeviceMappingList(resource);
213         if (CollectionUtils.isEmpty(blockDeviceMappingList)) {
214             return;
215         }
216         int index = 0;
217         for (Map<String, Object> blockDeviceMapping : blockDeviceMappingList) {
218             index = connectBlockDeviceToNovaServer(translateTo, novaNodeTemplate, index, blockDeviceMapping);
219         }
220     }
221
222     private int connectBlockDeviceToNovaServer(TranslateTo translateTo, NodeTemplate novaNodeTemplate, int index,
223                                                       Map<String, Object> blockDeviceMapping) {
224         Object volumeIdObject = blockDeviceMapping.get(VOL_ID_PROPERTY_NAME);
225         Object snapshotIdObject = blockDeviceMapping.get(SNAPSHOT_ID_PROPERTY_NAME);
226
227         if (volumeIdObject == null && snapshotIdObject == null) {
228             logger.warn("Resource '{}' has block_device_mapping property with empty/missing volume_id and snapshot_id "
229                                 + "properties. Entry number {}, this entry will be ignored in TOSCA translation.",
230                     translateTo.getResourceId(), (index + 1));
231             index++;
232             return index;
233         }
234         if (volumeIdObject == null) {
235             connectBlockDeviceUsingSnapshotId(translateTo, novaNodeTemplate, snapshotIdObject, index,
236                     blockDeviceMapping);
237         } else {
238             connectBlockDeviceUsingVolumeId(translateTo, novaNodeTemplate, volumeIdObject);
239         }
240         index++;
241         return index;
242     }
243
244     private void connectBlockDeviceUsingVolumeId(TranslateTo translateTo, NodeTemplate novaNodeTemplate,
245                                                         Object volumeIdObject) {
246         Optional<AttachedResourceId> attachedVolumeId = HeatToToscaUtil
247                 .extractAttachedResourceId(translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(),
248                         translateTo.getContext(), volumeIdObject);
249         if (attachedVolumeId.isPresent() && attachedVolumeId.get().isGetResource()) {
250             connectNovaServerToVolume(novaNodeTemplate, (String) attachedVolumeId.get().getTranslatedId(), null,
251                     translateTo);
252         }
253     }
254
255     private void connectBlockDeviceUsingSnapshotId(TranslateTo translateTo, NodeTemplate novaNodeTemplate,
256                                                           Object snapshotIdObject, int index,
257                                                           Map<String, Object> blockDeviceMapping) {
258         String novaServerTranslatedId = translateTo.getTranslatedId();
259         String volumeResourceId;
260         Optional<AttachedResourceId> attachedSnapshotId = HeatToToscaUtil
261                 .extractAttachedResourceId(translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(),
262                         translateTo.getContext(), snapshotIdObject);
263         if (attachedSnapshotId.isPresent()) {
264             volumeResourceId = novaServerTranslatedId + "_" + attachedSnapshotId.get().getEntityId();
265             String deviceName = (String) blockDeviceMapping.get(BLOCK_DEVICE_MAPPING_DEVICE_NAME);
266             String relationshipId = novaServerTranslatedId + "_" + index;
267             createVolumeAttachesToRelationship(translateTo.getServiceTemplate(), deviceName, novaServerTranslatedId,
268                     volumeResourceId, relationshipId);
269             createCinderVolumeNodeTemplate(translateTo, volumeResourceId, blockDeviceMapping);
270             connectNovaServerToVolume(novaNodeTemplate, volumeResourceId, relationshipId,
271                     translateTo);
272         }
273     }
274
275     private void connectNovaServerToVolume(NodeTemplate novaNodeTemplate, String volumeResourceId,
276                                                   String relationshipId, TranslateTo translateTo) {
277         RequirementAssignment requirementAssignment = new RequirementAssignment();
278         requirementAssignment.setCapability(ToscaCapabilityType.NATIVE_ATTACHMENT);
279         requirementAssignment.setNode(volumeResourceId);
280         if (relationshipId != null) {
281             requirementAssignment.setRelationship(relationshipId);
282         } else {
283             requirementAssignment
284                     .setRelationship(ToscaRelationshipType.NATIVE_ATTACHES_TO);
285         }
286         DataModelUtil.addRequirementAssignment(novaNodeTemplate, ToscaConstants.LOCAL_STORAGE_REQUIREMENT_ID,
287                 requirementAssignment);
288         //Add volume consolidation data
289         ConsolidationDataUtil.updateComputeConsolidationDataVolumes(translateTo, novaNodeTemplate.getType(),
290                 translateTo.getTranslatedId(), ToscaConstants.LOCAL_STORAGE_REQUIREMENT_ID, requirementAssignment);
291     }
292
293     private void createCinderVolumeNodeTemplate(TranslateTo translateTo,
294                                                        String volumeResourceId,
295                                                        Map<String, Object> blockDeviceMapping) {
296         NodeTemplate cinderVolumeNodeTemplate = new NodeTemplate();
297         cinderVolumeNodeTemplate.setType(ToscaNodeType.CINDER_VOLUME);
298         cinderVolumeNodeTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
299                 .getToscaPropertiesSimpleConversion(translateTo.getServiceTemplate(), translateTo.getResourceId(),
300                         blockDeviceMapping, null,
301                         translateTo.getHeatFileName(), translateTo.getHeatOrchestrationTemplate(),
302                         HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource(),
303                         cinderVolumeNodeTemplate, translateTo.getContext()));
304         DataModelUtil.addNodeTemplate(translateTo.getServiceTemplate(), volumeResourceId, cinderVolumeNodeTemplate);
305     }
306
307     private void createVolumeAttachesToRelationship(ServiceTemplate serviceTemplate,
308                                                            String deviceName, String novaServerTranslatedId,
309                                                            String volumeId, String relationshipId) {
310         RelationshipTemplate relationshipTemplate = new RelationshipTemplate();
311         relationshipTemplate.setType(ToscaRelationshipType.CINDER_VOLUME_ATTACHES_TO);
312         Map<String, Object> properties = new HashMap<>();
313         properties.put(ToscaConstants.INSTANCE_UUID_PROPERTY_NAME, novaServerTranslatedId);
314         properties.put(ToscaConstants.VOL_ID_PROPERTY_NAME, volumeId);
315         if (deviceName != null) {
316             properties.put(VOL_ATTACH_DEVICE_PROPERTY_NAME, deviceName);
317         }
318         relationshipTemplate.setProperties(properties);
319         DataModelUtil.addRelationshipTemplate(serviceTemplate, relationshipId, relationshipTemplate);
320     }
321
322     private List<Map<String, Object>> getBlockDeviceMappingList(Resource resource) {
323         if (Objects.isNull(resource.getProperties())) {
324             return Collections.emptyList();
325         }
326         List<Map<String, Object>> blockDeviceMappingList =
327                 (List<Map<String, Object>>) resource.getProperties().get(HeatConstants.BLOCK_DEVICE_MAPPING);
328         List<Map<String, Object>> blockDeviceMappingV2List =
329                 (List<Map<String, Object>>) resource.getProperties().get(HeatConstants.BLOCK_DEVICE_MAPPING_V2);
330
331         if (blockDeviceMappingList != null && blockDeviceMappingV2List != null) {
332             blockDeviceMappingList.addAll(blockDeviceMappingV2List);
333         } else if (CollectionUtils.isEmpty(blockDeviceMappingList)
334                            && CollectionUtils.isEmpty(blockDeviceMappingV2List)) {
335             return Collections.emptyList();
336
337         } else {
338             blockDeviceMappingList =
339                     blockDeviceMappingList != null ? blockDeviceMappingList : blockDeviceMappingV2List;
340         }
341         return blockDeviceMappingList;
342     }
343
344     private void manageNovaServerNetwork(TranslateTo translateTo,
345                                                 NodeTemplate novaNodeTemplate) {
346         Resource resource = translateTo.getResource();
347         String translatedId = translateTo.getTranslatedId();
348
349         if (resource.getProperties() == null) {
350             return;
351         }
352         Object networks = resource.getProperties().get(PropertiesMapKeyTypes.NETWORKS.getKeyMap());
353         if (Objects.isNull(networks) || !(networks instanceof List)) {
354             return;
355         }
356
357         List<Map<String, Object>> heatNetworkList = (List<Map<String, Object>>) networks;
358         
359        
360         for (Map<String, Object> heatNetwork : heatNetworkList) {
361            
362             Optional<Resource> portResourceOp = getOrTranslatePortTemplate(translateTo, heatNetwork.get(
363                     Constants.PORT_PROPERTY_NAME), translatedId, novaNodeTemplate);   
364             
365             if (ToggleableFeature.FABRIC_CONFIGURATION.isActive()) {
366                 portResourceOp.ifPresent(portResource -> handleFabricConfiguration(translateTo, novaNodeTemplate.getType(), portResource));  
367             }
368             
369         }
370         
371     }  
372     
373     private void handleFabricConfiguration(TranslateTo translateTo, String resourceType, Resource portResource ){ 
374        
375        Optional<Object> valueSpacesProperty = HeatToToscaUtil.getResourceProperty(portResource, HeatConstants.VALUE_SPECS_PROPERTY_NAME);
376        
377        valueSpacesProperty.filter(props -> props instanceof Map && MapUtils.isNotEmpty((Map)props)).ifPresent(valueSpecs ->{          
378            Object value = ((Map)(valueSpecs)).get(HeatConstants.ATT_FABRIC_CONFIGURATION_REQUIRED);
379            if(value!= null && HeatBoolean.eval(value )){
380                addFabricConfigurationCapability(translateTo, resourceType);
381            }
382            
383        });
384       
385     }
386     
387     private void addFabricConfigurationCapability(TranslateTo translateTo, String localType){
388         
389         ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
390         Map<String, CapabilityDefinition> mapCapabilities = new HashMap<>();
391         CapabilityDefinition fabricConfigurationCap = new CapabilityDefinition();        
392         fabricConfigurationCap.setType(ToscaCapabilityType.FABRIC_CONFIGURATION);
393         mapCapabilities.put(FABRIC_CONFIGURATION_KEY, fabricConfigurationCap);
394         DataModelUtil.addNodeTypeCapabilitiesDef (DataModelUtil.getNodeType(serviceTemplate, localType), mapCapabilities);            
395     }
396
397     private Optional<Resource> getOrTranslatePortTemplate(TranslateTo translateTo,
398                                                    Object port,
399                                                    String novaServerResourceId,
400                                                    NodeTemplate novaNodeTemplate) {
401         String heatFileName = translateTo.getHeatFileName();
402         HeatOrchestrationTemplate heatOrchestrationTemplate = translateTo.getHeatOrchestrationTemplate();
403         TranslationContext context = translateTo.getContext();
404         Optional<AttachedResourceId> attachedPortId = HeatToToscaUtil
405                 .extractAttachedResourceId(heatFileName, heatOrchestrationTemplate, context, port);
406         if (!attachedPortId.isPresent() || !attachedPortId.get().isGetResource()) {
407             return Optional.empty();
408         }
409         String resourceId = (String) attachedPortId.get().getEntityId();
410         Resource portResource = HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName);
411         if (!isSupportedPortResource(portResource)) {
412             logger.warn("NovaServer connect to port resource with id : {} and type : {}. This resource type is "
413                     + "not " + "supported, therefore the connection to the port is ignored. "
414                     + "Supported types are: {}, {}", resourceId, portResource.getType(),
415                     HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource(),
416                     HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource());
417             return Optional.empty();
418         } else if (HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE
419                            .getHeatResource().equals(portResource.getType())) {
420             Map<String, Object> properties = portResource.getProperties();
421             if (!MapUtils.isEmpty(properties) && Objects.nonNull(properties.get(HeatConstants.PORT_TUPLE_REFS))) {
422                 novaNodeTemplate.getProperties().put(ToscaConstants.CONTRAIL_SERVICE_INSTANCE_IND, true);
423             }
424         }
425         ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
426         Optional<String> translatedPortId = ResourceTranslationFactory.getInstance(portResource)
427                 .translateResource(heatFileName, serviceTemplate, heatOrchestrationTemplate, portResource,
428                         resourceId, context);
429         if (translatedPortId.isPresent()) {
430             NodeTemplate portNodeTemplate =
431                     DataModelUtil.getNodeTemplate(serviceTemplate, translatedPortId.get());
432             DataModelUtil.addBindingReqFromPortToCompute(novaServerResourceId, portNodeTemplate);
433             // Add ports
434             ConsolidationDataUtil.updatePortInConsolidationData(translateTo, novaNodeTemplate.getType(), resourceId,
435                     portResource.getType(), translatedPortId.get());
436         } else {
437             logger.warn("NovaServer connect to port resource with id : {} and type : {}. This resource type"
438                     + " is not supported, therefore the connection to the port is ignored.", resourceId,
439                     portResource.getType());
440             return Optional.empty();
441         }
442         return Optional.ofNullable(portResource);
443     }
444
445     private boolean isSupportedPortResource(Resource portResource) {
446         return Arrays.asList(HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource(),
447                 HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource())
448                      .contains(portResource.getType());
449     }
450
451
452     private String createLocalNodeType(ServiceTemplate serviceTemplate, Resource resource,
453                                               String resourceId, String translatedId) {
454         NameExtractor nodeTypeNameExtractor = TranslationContext.getNameExtractorImpl(resource.getType());
455         String nodeTypeName =
456                 nodeTypeNameExtractor.extractNodeTypeName(resource, resourceId, translatedId);
457
458         if (!isNodeTypeCreated(serviceTemplate, nodeTypeName)) {
459             DataModelUtil.addNodeType(serviceTemplate, nodeTypeName, createNodeType());
460         }
461         return nodeTypeName;
462     }
463
464     /**
465      * Get property Regex matcher list.
466      *
467      * @return Regex expression per nova resource property, while nova node type name is consider when
468      *      setting the name value.
469      */
470     public List<PropertyRegexMatcher> getPropertyRegexMatchersForNovaNodeType() {
471         List<PropertyRegexMatcher> propertyRegexMatchers = new ArrayList<>(3);
472         propertyRegexMatchers
473                 .add(new PropertyRegexMatcher(Constants.NAME_PROPERTY_NAME,
474                         Arrays.asList(".+_name$", ".+_names$", ".+_name_[0-9]+"), "_name"));
475         propertyRegexMatchers
476                 .add(new PropertyRegexMatcher("image", Collections.singletonList(".+_image_name$"),
477                                                      "_image_name"));
478         propertyRegexMatchers
479                 .add(new PropertyRegexMatcher("flavor", Collections.singletonList(".+_flavor_name$"),
480                                                      "_flavor_name"));
481         return propertyRegexMatchers;
482     }
483
484     private boolean isNodeTypeCreated(ServiceTemplate serviceTemplate, String nodeTypeName) {
485         return !MapUtils.isEmpty(serviceTemplate.getNode_types())
486                        && Objects.nonNull(serviceTemplate.getNode_types().get(nodeTypeName));
487     }
488
489     private NodeType createNodeType() {
490         NodeType nodeType = new NodeType();
491         nodeType.setDerived_from(ToscaNodeType.NOVA_SERVER);
492         return nodeType;
493     }
494 }