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