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