aboutsummaryrefslogtreecommitdiffstats
path: root/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/main/java/org/openecomp/sdc/translator/services/heattotosca/impl/ResourceTranslationNovaServerImpl.java
diff options
context:
space:
mode:
Diffstat (limited to 'openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/main/java/org/openecomp/sdc/translator/services/heattotosca/impl/ResourceTranslationNovaServerImpl.java')
-rw-r--r--openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/main/java/org/openecomp/sdc/translator/services/heattotosca/impl/ResourceTranslationNovaServerImpl.java419
1 files changed, 419 insertions, 0 deletions
diff --git a/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/main/java/org/openecomp/sdc/translator/services/heattotosca/impl/ResourceTranslationNovaServerImpl.java b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/main/java/org/openecomp/sdc/translator/services/heattotosca/impl/ResourceTranslationNovaServerImpl.java
new file mode 100644
index 0000000000..59e0691b2b
--- /dev/null
+++ b/openecomp-be/lib/openecomp-sdc-translator-lib/openecomp-sdc-translator-core/src/main/java/org/openecomp/sdc/translator/services/heattotosca/impl/ResourceTranslationNovaServerImpl.java
@@ -0,0 +1,419 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.translator.services.heattotosca.impl;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.collections4.MapUtils;
+import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
+import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
+import org.openecomp.sdc.heat.datatypes.model.Resource;
+import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
+import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
+import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
+import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
+import org.openecomp.sdc.tosca.datatypes.model.NodeType;
+import org.openecomp.sdc.tosca.datatypes.model.RelationshipTemplate;
+import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
+import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
+import org.openecomp.sdc.tosca.services.DataModelUtil;
+import org.openecomp.sdc.tosca.services.ToscaConstants;
+import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
+import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
+import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslatedHeatResource;
+import org.openecomp.sdc.translator.services.heattotosca.Constants;
+import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
+import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
+import org.openecomp.sdc.translator.services.heattotosca.TranslationContext;
+import org.openecomp.sdc.translator.services.heattotosca.helper.NameExtractorService;
+import org.openecomp.sdc.translator.services.heattotosca.helper.PropertyRegexMatcher;
+import org.openecomp.sdc.translator.services.heattotosca.helper.impl.NameExtractorServiceImpl;
+import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+
+public class ResourceTranslationNovaServerImpl extends ResourceTranslationBase {
+ protected static Logger logger = LoggerFactory.getLogger(ResourceTranslationNovaServerImpl.class);
+
+ @Override
+ protected void translate(TranslateTo translateTo) {
+ TranslationContext context = translateTo.getContext();
+ Map<String, Object> properties = translateTo.getResource().getProperties();
+ String heatFileName = translateTo.getHeatFileName();
+
+ ServiceTemplate serviceTemplate = translateTo.getServiceTemplate();
+
+ String nodeTypeRef =
+ createLocalNodeType(serviceTemplate, translateTo.getResource().getProperties(),
+ translateTo.getTranslatedId());
+
+ NodeTemplate novaNodeTemplate = new NodeTemplate();
+ novaNodeTemplate.setType(nodeTypeRef);
+ HeatOrchestrationTemplate heatOrchestrationTemplate =
+ translateTo.getHeatOrchestrationTemplate();
+ novaNodeTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
+ .getToscaPropertiesSimpleConversion(properties, novaNodeTemplate.getProperties(),
+ heatFileName, heatOrchestrationTemplate, translateTo.getResource().getType(),
+ novaNodeTemplate, context));
+
+ manageNovaServerNetwork(heatFileName, serviceTemplate, heatOrchestrationTemplate,
+ translateTo.getResource(), translateTo.getTranslatedId(), context, novaNodeTemplate);
+ manageNovaServerBlockDeviceMapping(heatFileName, serviceTemplate, novaNodeTemplate,
+ heatOrchestrationTemplate, translateTo.getResource(), translateTo.getResourceId(),
+ translateTo.getTranslatedId(), context);
+
+ manageNovaServerGroupMapping(translateTo, context, properties, heatFileName, serviceTemplate,
+ heatOrchestrationTemplate);
+ DataModelUtil.addNodeTemplate(serviceTemplate, translateTo.getTranslatedId(), novaNodeTemplate);
+ }
+
+ private void manageNovaServerGroupMapping(TranslateTo translateTo, TranslationContext context,
+ Map<String, Object> properties, String heatFileName,
+ ServiceTemplate serviceTemplate,
+ HeatOrchestrationTemplate heatOrchestrationTemplate) {
+ if (isSchedulerHintsPropExist(properties)) {
+ Object schedulerHints = properties.get("scheduler_hints");
+ if (schedulerHints instanceof Map) {
+ addServerGroupHintsToPoliciesProups(translateTo, context, heatFileName, serviceTemplate,
+ heatOrchestrationTemplate, (Map<String, Object>) schedulerHints);
+ } else {
+ logger.warn("'scheduler_hints' property of resource '" + translateTo.getResourceId()
+ + "' is not valid. This property should be a map");
+ }
+ }
+ }
+
+ private void addServerGroupHintsToPoliciesProups(TranslateTo translateTo,
+ TranslationContext context, String heatFileName,
+ ServiceTemplate serviceTemplate,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ Map<String, Object> schedulerHints) {
+ for (Object hint : schedulerHints.values()) {
+ Optional<AttachedResourceId> attachedResourceId = HeatToToscaUtil
+ .extractAttachedResourceId(heatFileName, heatOrchestrationTemplate, context, hint);
+ if (attachedResourceId.isPresent()) {
+ AttachedResourceId serverGroupResourceId = attachedResourceId.get();
+ Object serverGroupResourceToTranslate = serverGroupResourceId.getEntityId();
+ if (serverGroupResourceId.isGetResource()) {
+ boolean isHintOfTypeNovaServerGroup =
+ isHintOfTypeNovaServerGroup(heatOrchestrationTemplate,
+ serverGroupResourceToTranslate);
+ if (isHintOfTypeNovaServerGroup) {
+ addNovaServerToPolicyGroup(translateTo, context, heatFileName, serviceTemplate,
+ heatOrchestrationTemplate, (String) serverGroupResourceToTranslate);
+ }
+ } else if (serverGroupResourceId.isGetParam()) {
+ TranslatedHeatResource translatedServerGroupResource =
+ context.getHeatSharedResourcesByParam().get(serverGroupResourceToTranslate);
+ if (Objects.nonNull(translatedServerGroupResource)
+ && !HeatToToscaUtil.isHeatFileNested(translateTo, translateTo.getHeatFileName())) {
+ serviceTemplate.getTopology_template().getGroups()
+ .get(translatedServerGroupResource.getTranslatedId()).getMembers()
+ .add(translateTo.getTranslatedId());
+ }
+ }
+ }
+ }
+ }
+
+ private boolean isHintOfTypeNovaServerGroup(HeatOrchestrationTemplate heatOrchestrationTemplate,
+ Object resourceToTranslate) {
+ return heatOrchestrationTemplate.getResources().get(resourceToTranslate).getType()
+ .equals(HeatResourcesTypes.NOVA_SERVER_GROUP_RESOURCE_TYPE.getHeatResource());
+ }
+
+ private void addNovaServerToPolicyGroup(TranslateTo translateTo, TranslationContext context,
+ String heatFileName, ServiceTemplate serviceTemplate,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ String resourceToTranslate) {
+ Resource serverGroup =
+ HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceToTranslate, heatFileName);
+ Optional<String> serverGroupTranslatedId = ResourceTranslationFactory.getInstance(serverGroup)
+ .translateResource(heatFileName, serviceTemplate, heatOrchestrationTemplate, serverGroup,
+ resourceToTranslate, context);
+ if (serverGroupTranslatedId.isPresent()) {
+ serviceTemplate.getTopology_template().getGroups().get(serverGroupTranslatedId.get())
+ .getMembers().add(translateTo.getTranslatedId());
+ }
+ }
+
+ private boolean isSchedulerHintsPropExist(Map<String, Object> properties) {
+ return !MapUtils.isEmpty(properties) && Objects.nonNull(properties.get("scheduler_hints"));
+ }
+
+ private void manageNovaServerBlockDeviceMapping(String heatFileName,
+ ServiceTemplate serviceTemplate,
+ NodeTemplate novaNodeTemplate,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ Resource resource, String resourceId,
+ String novaServerTranslatedId,
+ TranslationContext context) {
+
+ List<Map<String, Object>> blockDeviceMappingList = getBlockDeviceMappingList(resource);
+ if (CollectionUtils.isEmpty(blockDeviceMappingList)) {
+ return;
+ }
+
+ Object volumeIdObject;
+ Object snapshotIdObject;
+ String volumeResourceId;
+ int index = 0;
+ for (Map<String, Object> blockDeviceMapping : blockDeviceMappingList) {
+ volumeIdObject = blockDeviceMapping.get("volume_id");
+ snapshotIdObject = blockDeviceMapping.get("snapshot_id");
+
+ if (volumeIdObject == null && snapshotIdObject == null) {
+ logger.warn("Resource '" + resourceId
+ + "' has block_device_mapping property with empty/missing volume_id and snapshot_id "
+ + "properties. Entry number "
+ + (index + 1) + ", this entry will be ignored in TOSCA translation.");
+ index++;
+ continue;
+ }
+ if (volumeIdObject == null) {
+ String deviceName = (String) blockDeviceMapping.get("device_name");
+ String relationshipId = novaServerTranslatedId + "_" + index;
+
+ Optional<AttachedResourceId> attachedSnapshotId = HeatToToscaUtil
+ .extractAttachedResourceId(heatFileName, heatOrchestrationTemplate, context,
+ snapshotIdObject);
+ volumeResourceId = novaServerTranslatedId + "_" + attachedSnapshotId.get().getEntityId();
+ createVolumeAttachesToRelationship(serviceTemplate, deviceName, novaServerTranslatedId,
+ volumeResourceId, relationshipId);
+ createCinderVolumeNodeTemplate(serviceTemplate, volumeResourceId, heatFileName,
+ blockDeviceMapping, heatOrchestrationTemplate, context);
+ connectNovaServerToVolume(novaNodeTemplate, volumeResourceId, relationshipId);
+ } else {
+ Optional<AttachedResourceId> attachedVolumeId = HeatToToscaUtil
+ .extractAttachedResourceId(heatFileName, heatOrchestrationTemplate, context,
+ volumeIdObject);
+ if (attachedVolumeId.get().isGetResource()) {
+ connectNovaServerToVolume(novaNodeTemplate,
+ (String) attachedVolumeId.get().getTranslatedId(), null);
+ }
+ }
+ index++;
+ }
+ }
+
+ private void connectNovaServerToVolume(NodeTemplate novaNodeTemplate, String volumeResourceId,
+ String relationshipId) {
+ RequirementAssignment requirementAssignment = new RequirementAssignment();
+ requirementAssignment.setCapability(ToscaCapabilityType.ATTACHMENT.getDisplayName());
+ requirementAssignment.setNode(volumeResourceId);
+ if (relationshipId != null) {
+ requirementAssignment.setRelationship(relationshipId);
+ } else {
+ requirementAssignment
+ .setRelationship(ToscaRelationshipType.NATIVE_ATTACHES_TO.getDisplayName());
+ }
+ DataModelUtil
+ .addRequirementAssignment(novaNodeTemplate, ToscaConstants.LOCAL_STORAGE_REQUIREMENT_ID,
+ requirementAssignment);
+ }
+
+ private void createCinderVolumeNodeTemplate(ServiceTemplate serviceTemplate,
+ String volumeResourceId, String heatFileName,
+ Map<String, Object> blockDeviceMapping,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ TranslationContext context) {
+ NodeTemplate cinderVolumeNodeTemplate = new NodeTemplate();
+ cinderVolumeNodeTemplate.setType(ToscaNodeType.CINDER_VOLUME.getDisplayName());
+ cinderVolumeNodeTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
+ .getToscaPropertiesSimpleConversion(blockDeviceMapping, null, heatFileName,
+ heatOrchestrationTemplate,
+ HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource(),
+ cinderVolumeNodeTemplate, context));
+ DataModelUtil.addNodeTemplate(serviceTemplate, volumeResourceId, cinderVolumeNodeTemplate);
+ }
+
+ private void createVolumeAttachesToRelationship(ServiceTemplate serviceTemplate,
+ String deviceName, String novaServerTranslatedId,
+ String volumeId, String relationshipId) {
+ RelationshipTemplate relationshipTemplate = new RelationshipTemplate();
+ relationshipTemplate.setType(ToscaRelationshipType.CINDER_VOLUME_ATTACHES_TO.getDisplayName());
+ Map<String, Object> properties = new HashMap<>();
+ properties.put("instance_uuid", novaServerTranslatedId);
+ properties.put("volume_id", volumeId);
+ if (deviceName != null) {
+ properties.put("device", deviceName);
+ }
+ relationshipTemplate.setProperties(properties);
+
+ DataModelUtil.addRelationshipTemplate(serviceTemplate, relationshipId, relationshipTemplate);
+ }
+
+ private List<Map<String, Object>> getBlockDeviceMappingList(Resource resource) {
+
+ if (Objects.isNull(resource.getProperties())) {
+ return Collections.emptyList();
+ }
+ List<Map<String, Object>> blockDeviceMappingList =
+ (List<Map<String, Object>>) resource.getProperties().get("block_device_mapping");
+ List<Map<String, Object>> blockDeviceMappingV2List =
+ (List<Map<String, Object>>) resource.getProperties().get("block_device_mapping_v2");
+
+ if (blockDeviceMappingList != null && blockDeviceMappingV2List != null) {
+ blockDeviceMappingList.addAll(blockDeviceMappingV2List);
+ } else if (CollectionUtils.isEmpty(blockDeviceMappingList)
+ && CollectionUtils.isEmpty(blockDeviceMappingV2List)) {
+ return null;
+
+ } else {
+ blockDeviceMappingList =
+ blockDeviceMappingList != null ? blockDeviceMappingList : blockDeviceMappingV2List;
+ }
+ return blockDeviceMappingList;
+ }
+
+ private void manageNovaServerNetwork(String heatFileName, ServiceTemplate serviceTemplate,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ Resource resource, String translatedId,
+ TranslationContext context, NodeTemplate novaNodeTemplate) {
+
+ if (resource.getProperties() == null) {
+ return;
+ }
+ List<Map<String, Object>> heatNetworkList =
+ (List<Map<String, Object>>) resource.getProperties().get("networks");
+
+ if (CollectionUtils.isEmpty(heatNetworkList)) {
+ return;
+ }
+
+ for (Map<String, Object> heatNetwork : heatNetworkList) {
+ getOrTranslatePortTemplate(heatFileName, heatOrchestrationTemplate,
+ heatNetwork.get(Constants.PORT_PROPERTY_NAME), serviceTemplate, translatedId, context,
+ novaNodeTemplate);
+ }
+
+ }
+
+ private void getOrTranslatePortTemplate(String heatFileName,
+ HeatOrchestrationTemplate heatOrchestrationTemplate,
+ Object port, ServiceTemplate serviceTemplate,
+ String novaServerResourceId, TranslationContext context,
+ NodeTemplate novaNodeTemplate) {
+ Optional<AttachedResourceId> attachedPortId = HeatToToscaUtil
+ .extractAttachedResourceId(heatFileName, heatOrchestrationTemplate, context, port);
+
+ if (!attachedPortId.isPresent()) {
+ return;
+ }
+
+ if (attachedPortId.get().isGetResource()) {
+ String resourceId = (String) attachedPortId.get().getEntityId();
+ Resource portResource =
+ HeatToToscaUtil.getResource(heatOrchestrationTemplate, resourceId, heatFileName);
+ if (!Arrays.asList(HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource(),
+ HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE.getHeatResource())
+ .contains(portResource.getType())) {
+ logger.warn("NovaServer connect to port resource with id : " + resourceId + " and type : "
+ + portResource.getType()
+ + ". This resource type is not supported, therefore the connection to the port is "
+ + "ignored. "
+ + "Supported types are: "
+ + HeatResourcesTypes.NEUTRON_PORT_RESOURCE_TYPE.getHeatResource() + ", "
+ + HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE
+ .getHeatResource());
+ return;
+ } else if (HeatResourcesTypes.CONTRAIL_V2_VIRTUAL_MACHINE_INTERFACE_RESOURCE_TYPE
+ .getHeatResource().equals(portResource.getType())) {
+ Map<String, Object> properties = portResource.getProperties();
+ if (!MapUtils.isEmpty(properties) && Objects.nonNull(properties.get("port_tuple_refs"))) {
+ novaNodeTemplate.getProperties().put("contrail_service_instance_ind", true);
+ }
+ }
+ Optional<String> translatedPortId = ResourceTranslationFactory.getInstance(portResource)
+ .translateResource(heatFileName, serviceTemplate, heatOrchestrationTemplate, portResource,
+ resourceId, context);
+ if (translatedPortId.isPresent()) {
+ NodeTemplate portNodeTemplate =
+ DataModelUtil.getNodeTemplate(serviceTemplate, translatedPortId.get());
+ addBindingReqFromPortToCompute(novaServerResourceId, portNodeTemplate);
+ } else {
+ logger.warn("NovaServer connect to port resource with id : " + resourceId + " and type : "
+ + portResource.getType()
+ + ". This resource type is not supported, therefore the connection to the port is "
+ + "ignored.");
+ }
+ }
+ }
+
+ /**
+ * Create local node type string.
+ *
+ * @param serviceTemplate the service template
+ * @param properties the properties
+ * @param resourceTranslatedId the resource translated id
+ * @return the string
+ */
+ public String createLocalNodeType(ServiceTemplate serviceTemplate, Map<String, Object> properties,
+ String resourceTranslatedId) {
+ NameExtractorService nodeTypeNameExtractor = new NameExtractorServiceImpl();
+ List<PropertyRegexMatcher> propertyRegexMatchers =
+ getPropertiesAndRegexMatchers(nodeTypeNameExtractor);
+ Optional<String> extractedNodeTypeName = nodeTypeNameExtractor
+ .extractNodeTypeNameByPropertiesPriority(properties, propertyRegexMatchers);
+
+ String nodeTypeName = ToscaConstants.NODES_PREFIX
+ + (extractedNodeTypeName.isPresent() ? extractedNodeTypeName.get()
+ : resourceTranslatedId.replace(".", "_"));
+ if (!isNodeTypeCreated(serviceTemplate, nodeTypeName)) {
+ DataModelUtil.addNodeType(serviceTemplate, nodeTypeName, createNodeType());
+ }
+ return nodeTypeName;
+ }
+
+ private List<PropertyRegexMatcher> getPropertiesAndRegexMatchers(
+ NameExtractorService nodeTypeNameExtractor) {
+ List<PropertyRegexMatcher> propertyRegexMatchers = new ArrayList<>();
+ propertyRegexMatchers.add(nodeTypeNameExtractor
+ .getPropertyRegexMatcher(Constants.NAME_PROPERTY_NAME,
+ Arrays.asList(".+_name$", ".+_names$", ".+_name_[0-9]+"), "_name"));
+ propertyRegexMatchers.add(nodeTypeNameExtractor
+ .getPropertyRegexMatcher("image", Collections.singletonList(".+_image_name$"),
+ "_image_name"));
+ propertyRegexMatchers.add(nodeTypeNameExtractor
+ .getPropertyRegexMatcher("flavor", Collections.singletonList(".+_flavor_name$"),
+ "_flavor_name"));
+ return propertyRegexMatchers;
+ }
+
+ private boolean isNodeTypeCreated(ServiceTemplate serviceTemplate, String nodeTypeName) {
+ return !MapUtils.isEmpty(serviceTemplate.getNode_types())
+ && Objects.nonNull(serviceTemplate.getNode_types().get(nodeTypeName));
+ }
+
+ private NodeType createNodeType() {
+ NodeType nodeType = new NodeType();
+ nodeType.setDerived_from(ToscaNodeType.NOVA_SERVER.getDisplayName());
+ return nodeType;
+ }
+}