2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.translator.services.heattotosca.impl;
23 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil.getResource;
25 import org.apache.commons.lang3.StringUtils;
26 import org.openecomp.sdc.common.errors.CoreException;
27 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
28 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
29 import org.openecomp.sdc.heat.datatypes.model.Resource;
30 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
31 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
32 import org.openecomp.sdc.tosca.datatypes.model.RelationshipTemplate;
33 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
34 import org.openecomp.sdc.tosca.services.DataModelUtil;
35 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
36 import org.openecomp.sdc.translator.datatypes.heattotosca.to.ResourceFileDataAndIDs;
37 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
38 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
39 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
40 import org.openecomp.sdc.translator.services.heattotosca.errors.MissingMandatoryPropertyErrorBuilder;
41 import org.openecomp.sdc.translator.services.heattotosca.helper.VolumeTranslationHelper;
42 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
46 import java.util.List;
47 import java.util.Optional;
49 public class ResourceTranslationCinderVolumeAttachmentImpl extends ResourceTranslationBase {
50 protected static Logger logger =
51 LoggerFactory.getLogger(ResourceTranslationCinderVolumeAttachmentImpl.class);
54 protected void translate(TranslateTo translateTo) {
55 String volumeIdPropertyName = "volume_id";
56 RelationshipTemplate relationTemplate = new RelationshipTemplate();
57 relationTemplate.setType(ToscaRelationshipType.CINDER_VOLUME_ATTACHES_TO.getDisplayName());
58 String relationshipTemplateId = translateTo.getTranslatedId();
59 String heatFileName = translateTo.getHeatFileName();
60 relationTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
61 .getToscaPropertiesSimpleConversion(translateTo.getResource().getProperties(),
62 relationTemplate.getProperties(), heatFileName,
63 translateTo.getHeatOrchestrationTemplate(), translateTo.getResource().getType(),
64 relationTemplate, translateTo.getContext()));
66 AttachedResourceId attachedVolumeId = getAttachedResourceId(translateTo, volumeIdPropertyName);
67 String instanceUuid = "instance_uuid";
68 AttachedResourceId attachedNovaServerId = getAttachedResourceId(translateTo, instanceUuid);
70 if (attachedNovaServerId.isGetResource()) {
71 handleNovaGetResource(translateTo, relationTemplate, relationshipTemplateId, heatFileName,
72 attachedVolumeId, (String) attachedNovaServerId.getEntityId());
74 logger.warn("Heat resource: '" + translateTo.getResourceId() + "' with type: '"
75 + translateTo.getResource().getType()
76 + "' include 'instance_uuid' property without 'get_resource' function, therefore this "
77 + "resource will be ignored in TOSCA translation.");
81 private AttachedResourceId getAttachedResourceId(TranslateTo translateTo, String propertyName) {
82 Optional<AttachedResourceId> attachedResourceId =
83 HeatToToscaUtil.extractAttachedResourceId(translateTo, propertyName);
84 if (!attachedResourceId.isPresent()) {
85 throw new CoreException(new MissingMandatoryPropertyErrorBuilder(propertyName).build());
88 return attachedResourceId.get();
91 private void handleNovaGetResource(TranslateTo translateTo, RelationshipTemplate relationTemplate,
92 String relationshipTemplateId, String heatFileName,
93 AttachedResourceId volResourceId, String novaResourceId) {
94 String toscaCapabilityAttachment = "tosca.capabilities.Attachment";
95 RequirementAssignment requirement = new RequirementAssignment();
96 requirement.setCapability(toscaCapabilityAttachment);
97 if (volResourceId.isGetResource()) {
98 Resource volServerResource = getResource(translateTo.getHeatOrchestrationTemplate(),
99 (String) volResourceId.getTranslatedId(), heatFileName);
100 if (!StringUtils.equals(HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource(),
101 volServerResource.getType())) {
102 logger.warn("Volume attachment with id '" + translateTo.getResourceId()
103 + "' is pointing to unsupported resource type(" + volServerResource.getType()
104 + ") through the property 'volume_id'."
105 + " The connection to the volume is ignored. "
106 + "Supported types are: "
107 + HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource());
110 requirement.setNode((String) volResourceId.getTranslatedId());
111 requirement.setRelationship(relationshipTemplateId);
113 .addRelationshipTemplate(translateTo.getServiceTemplate(), relationshipTemplateId,
115 } else if (volResourceId.isGetParam()) {
116 String volumeResourceIdParamName = (String) volResourceId.getEntityId();
117 if (translateTo.getContext().getHeatSharedResourcesByParam()
118 .containsKey(volumeResourceIdParamName) && !isHeatFileNested(translateTo, heatFileName)) {
119 Resource volServerResource =
120 translateTo.getContext().getHeatSharedResourcesByParam().get(volumeResourceIdParamName)
122 if (!StringUtils.equals(HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource(),
123 volServerResource.getType())) {
124 logger.warn("Volume attachment with id '" + translateTo.getResourceId()
125 + "' is pointing to unsupported resource type(" + volServerResource.getType()
126 + ") through the property 'volume_id'."
127 + " The connection to the volume is ignored. "
128 + "Supported types are: "
129 + HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource());
133 translateTo.getContext().getHeatSharedResourcesByParam().get(volumeResourceIdParamName)
135 requirement.setRelationship(relationshipTemplateId);
137 .addRelationshipTemplate(translateTo.getServiceTemplate(), relationshipTemplateId,
140 handleUnsharedVolume(translateTo, relationTemplate, relationshipTemplateId, heatFileName,
141 requirement, volumeResourceIdParamName);
144 Resource novaServerResource =
145 getResource(translateTo.getHeatOrchestrationTemplate(), novaResourceId, heatFileName);
146 if (!StringUtils.equals(HeatResourcesTypes.NOVA_SERVER_RESOURCE_TYPE.getHeatResource(),
147 novaServerResource.getType())) {
148 logger.warn("Volume attachment with id '" + translateTo.getResourceId()
149 + "' is pointing to unsupported resource type(" + novaServerResource.getType()
150 + ") through the property 'instance_uuid'."
151 + " The connection to the nova server is ignored. "
152 + "Supported types are: " + HeatResourcesTypes.NOVA_SERVER_RESOURCE_TYPE
156 Optional<String> translatedNovaServerId =
157 ResourceTranslationFactory.getInstance(novaServerResource)
158 .translateResource(heatFileName, translateTo.getServiceTemplate(),
159 translateTo.getHeatOrchestrationTemplate(), novaServerResource, novaResourceId,
160 translateTo.getContext());
162 if (translatedNovaServerId.isPresent() && StringUtils.isNotEmpty(requirement.getNode())) {
163 NodeTemplate novaServerNodeTemplate = DataModelUtil
164 .getNodeTemplate(translateTo.getServiceTemplate(), translatedNovaServerId.get());
165 DataModelUtil.addRequirementAssignment(novaServerNodeTemplate, "local_storage", requirement);
169 private void handleUnsharedVolume(TranslateTo translateTo, RelationshipTemplate relationTemplate,
170 String relationshipTemplateId, String heatFileName,
171 RequirementAssignment requirement, String volumeResourceId) {
172 List<FileData> allFilesData = translateTo.getContext().getManifest().getContent().getData();
173 Optional<FileData> fileData = HeatToToscaUtil.getFileData(heatFileName, allFilesData);
174 if (fileData.isPresent()) {
175 Optional<ResourceFileDataAndIDs> fileDataContainingResource =
176 new VolumeTranslationHelper(logger)
177 .getFileDataContainingVolume(fileData.get().getData(), volumeResourceId, translateTo,
178 FileData.Type.HEAT_VOL);
179 if (fileDataContainingResource.isPresent()) {
180 addRelationshipToServiceTemplate(translateTo, relationTemplate, relationshipTemplateId,
181 requirement, fileDataContainingResource.get());
186 private boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
187 return translateTo.getContext().getNestedHeatsFiles().contains(heatFileName);
190 private void addRelationshipToServiceTemplate(TranslateTo translateTo,
191 RelationshipTemplate relationTemplate,
192 String relationshipTemplateId,
193 RequirementAssignment requirement,
194 ResourceFileDataAndIDs resourceFileDataAndIDs) {
195 String translatedId = resourceFileDataAndIDs.getTranslatedResourceId();
196 relationTemplate.getProperties().put("volume_id", translatedId);
197 requirement.setNode(translatedId);
198 requirement.setRelationship(relationshipTemplateId);
199 DataModelUtil.addRelationshipTemplate(translateTo.getServiceTemplate(), relationshipTemplateId,