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.resourcetranslation;
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.datatypes.error.ErrorLevel;
28 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
29 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
30 import org.openecomp.sdc.heat.datatypes.model.Resource;
31 import org.openecomp.sdc.heat.services.HeatConstants;
32 import org.openecomp.sdc.logging.api.Logger;
33 import org.openecomp.sdc.logging.api.LoggerFactory;
34 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
35 import org.openecomp.sdc.logging.types.LoggerConstants;
36 import org.openecomp.sdc.logging.types.LoggerErrorCode;
37 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
38 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
39 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
40 import org.openecomp.sdc.tosca.datatypes.ToscaTopologyTemplateElements;
41 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
42 import org.openecomp.sdc.tosca.datatypes.model.RelationshipTemplate;
43 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
44 import org.openecomp.sdc.tosca.services.DataModelUtil;
45 import org.openecomp.sdc.tosca.services.ToscaConstants;
46 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
47 import org.openecomp.sdc.translator.datatypes.heattotosca.to.ResourceFileDataAndIDs;
48 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
49 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationDataUtil;
50 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
51 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
52 import org.openecomp.sdc.translator.services.heattotosca.errors.MissingMandatoryPropertyErrorBuilder;
53 import org.openecomp.sdc.translator.services.heattotosca.helper.VolumeTranslationHelper;
54 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
56 import java.util.List;
57 import java.util.Optional;
59 public class ResourceTranslationCinderVolumeAttachmentImpl extends ResourceTranslationBase {
60 protected static Logger logger =
61 (Logger) LoggerFactory.getLogger(ResourceTranslationCinderVolumeAttachmentImpl.class);
62 private String volumeIdPropertyName = "volume_id";
63 private String toscaCapabilityAttachment = "tosca.capabilities.Attachment";
66 protected void translate(TranslateTo translateTo) {
69 mdcDataDebugMessage.debugEntryMessage(null, null);
71 RelationshipTemplate relationTemplate = new RelationshipTemplate();
72 relationTemplate.setType(ToscaRelationshipType.CINDER_VOLUME_ATTACHES_TO);
73 String relationshipTemplateId = translateTo.getTranslatedId();
74 String heatFileName = translateTo.getHeatFileName();
75 relationTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
76 .getToscaPropertiesSimpleConversion(translateTo.getServiceTemplate(),translateTo
77 .getResourceId(),translateTo.getResource().getProperties(),
78 relationTemplate.getProperties(), heatFileName,
79 translateTo.getHeatOrchestrationTemplate(), translateTo.getResource().getType(),
80 relationTemplate, translateTo.getContext()));
82 AttachedResourceId attachedVolumeId = getAttachedResourceId(translateTo, volumeIdPropertyName);
83 String instanceUuid = HeatConstants.INSTANCE_UUID_PROPERTY_NAME;
84 AttachedResourceId attachedNovaServerId = getAttachedResourceId(translateTo, instanceUuid);
86 if (attachedNovaServerId.isGetResource()) {
87 handleNovaGetResource(translateTo, relationTemplate, relationshipTemplateId, heatFileName,
88 attachedVolumeId, (String) attachedNovaServerId.getEntityId());
90 logger.warn("Heat resource: '" + translateTo.getResourceId() + "' with type: '"
91 + translateTo.getResource().getType()
92 + "' include 'instance_uuid' property without 'get_resource' function, therefore this "
93 + "resource will be ignored in TOSCA translation.");
96 mdcDataDebugMessage.debugExitMessage(null, null);
100 protected Optional<ToscaTopologyTemplateElements> getTranslatedToscaTopologyElement(
101 TranslateTo translateTo) {
102 if (isEssentialRequirementsValid(translateTo)) {
103 return Optional.of(ToscaTopologyTemplateElements.RELATIONSHIP_TEMPLATE);
105 return Optional.empty();
109 private AttachedResourceId getAttachedResourceId(TranslateTo translateTo, String propertyName) {
112 mdcDataDebugMessage.debugEntryMessage(null, null);
114 Optional<AttachedResourceId> attachedResourceId =
115 HeatToToscaUtil.extractAttachedResourceId(translateTo, propertyName);
116 if (!attachedResourceId.isPresent()) {
117 MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
118 LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
119 LoggerErrorCode.DATA_ERROR.getErrorCode(),
120 LoggerErrorDescription.MISSING_MANDATORY_PROPERTY);
121 throw new CoreException(new MissingMandatoryPropertyErrorBuilder(propertyName).build());
124 mdcDataDebugMessage.debugExitMessage(null, null);
125 return attachedResourceId.get();
128 private void handleNovaGetResource(TranslateTo translateTo, RelationshipTemplate relationTemplate,
129 String relationshipTemplateId, String heatFileName,
130 AttachedResourceId volResourceId, String novaResourceId) {
133 mdcDataDebugMessage.debugEntryMessage(null, null);
135 RequirementAssignment requirement = new RequirementAssignment();
136 requirement.setCapability(toscaCapabilityAttachment);
137 if (volResourceId.isGetResource()) {
138 Resource volServerResource = getResource(translateTo.getHeatOrchestrationTemplate(),
139 (String) volResourceId.getTranslatedId(), heatFileName);
140 if (!StringUtils.equals(HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource(),
141 volServerResource.getType())) {
142 logger.warn("Volume attachment with id '" + translateTo.getResourceId()
143 + "' is pointing to unsupported resource type(" + volServerResource.getType()
144 + ") through the property 'volume_id'."
145 + " The connection to the volume is ignored. "
146 + "Supported types are: "
147 + HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource());
149 mdcDataDebugMessage.debugExitMessage(null, null);
152 requirement.setNode((String) volResourceId.getTranslatedId());
153 requirement.setRelationship(relationshipTemplateId);
155 .addRelationshipTemplate(translateTo.getServiceTemplate(), relationshipTemplateId,
157 } else if (volResourceId.isGetParam() && volResourceId.getEntityId() instanceof String) {
158 String volumeResourceIdParamName = (String) volResourceId.getEntityId();
159 if (translateTo.getContext().getHeatSharedResourcesByParam()
160 .containsKey(volumeResourceIdParamName) && !isHeatFileNested(translateTo, heatFileName)) {
161 Resource volServerResource =
162 translateTo.getContext().getHeatSharedResourcesByParam().get(volumeResourceIdParamName)
164 if (!StringUtils.equals(HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource(),
165 volServerResource.getType())) {
166 logger.warn("Volume attachment with id '" + translateTo.getResourceId()
167 + "' is pointing to unsupported resource type(" + volServerResource.getType()
168 + ") through the property 'volume_id'."
169 + " The connection to the volume is ignored. "
170 + "Supported types are: "
171 + HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource());
173 mdcDataDebugMessage.debugExitMessage(null, null);
177 translateTo.getContext().getHeatSharedResourcesByParam().get(volumeResourceIdParamName)
179 requirement.setRelationship(relationshipTemplateId);
181 .addRelationshipTemplate(translateTo.getServiceTemplate(), relationshipTemplateId,
184 handleUnsharedVolume(translateTo, relationTemplate, relationshipTemplateId, heatFileName,
185 requirement, volumeResourceIdParamName);
188 Resource novaServerResource =
189 getResource(translateTo.getHeatOrchestrationTemplate(), novaResourceId, heatFileName);
190 if (!StringUtils.equals(HeatResourcesTypes.NOVA_SERVER_RESOURCE_TYPE.getHeatResource(),
191 novaServerResource.getType())) {
192 logger.warn("Volume attachment with id '" + translateTo.getResourceId()
193 + "' is pointing to unsupported resource type(" + novaServerResource.getType()
194 + ") through the property 'instance_uuid'."
195 + " The connection to the nova server is ignored. "
196 + "Supported types are: "
197 + HeatResourcesTypes.NOVA_SERVER_RESOURCE_TYPE.getHeatResource());
199 mdcDataDebugMessage.debugExitMessage(null, null);
202 Optional<String> translatedNovaServerId =
203 ResourceTranslationFactory.getInstance(novaServerResource)
204 .translateResource(heatFileName, translateTo.getServiceTemplate(),
205 translateTo.getHeatOrchestrationTemplate(), novaServerResource, novaResourceId,
206 translateTo.getContext());
208 if (translatedNovaServerId.isPresent() && StringUtils.isNotEmpty(requirement.getNode())) {
209 NodeTemplate novaServerNodeTemplate = DataModelUtil
210 .getNodeTemplate(translateTo.getServiceTemplate(), translatedNovaServerId.get());
211 DataModelUtil.addRequirementAssignment(novaServerNodeTemplate, ToscaConstants
212 .LOCAL_STORAGE_REQUIREMENT_ID, requirement);
213 //Add volume information to consolidation data
214 ConsolidationDataUtil.updateComputeConsolidationDataVolumes(translateTo,
215 novaServerNodeTemplate.getType(), translatedNovaServerId.get(), ToscaConstants
216 .LOCAL_STORAGE_REQUIREMENT_ID, requirement);
219 mdcDataDebugMessage.debugExitMessage(null, null);
222 private void handleUnsharedVolume(TranslateTo translateTo, RelationshipTemplate relationTemplate,
223 String relationshipTemplateId, String heatFileName,
224 RequirementAssignment requirement, String volumeResourceId) {
227 mdcDataDebugMessage.debugEntryMessage(null, null);
229 List<FileData> allFilesData = translateTo.getContext().getManifest().getContent().getData();
230 Optional<FileData> fileData = HeatToToscaUtil.getFileData(heatFileName, allFilesData);
231 if (fileData.isPresent()) {
232 Optional<ResourceFileDataAndIDs> fileDataContainingResource =
233 new VolumeTranslationHelper(logger)
234 .getFileDataContainingVolume(fileData.get().getData(), volumeResourceId, translateTo,
235 FileData.Type.HEAT_VOL);
236 fileDataContainingResource.ifPresent(
237 resourceFileDataAndIDs -> addRelationshipToServiceTemplate(translateTo, relationTemplate,
238 relationshipTemplateId, requirement, resourceFileDataAndIDs));
241 mdcDataDebugMessage.debugExitMessage(null, null);
244 private boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
245 return translateTo.getContext().getNestedHeatsFiles().contains(heatFileName);
248 private void addRelationshipToServiceTemplate(TranslateTo translateTo,
249 RelationshipTemplate relationTemplate,
250 String relationshipTemplateId,
251 RequirementAssignment requirement,
252 ResourceFileDataAndIDs resourceFileDataAndIDs) {
255 mdcDataDebugMessage.debugEntryMessage(null, null);
257 String translatedId = resourceFileDataAndIDs.getTranslatedResourceId();
258 String toscaVolIdPropName =
259 HeatToToscaUtil.getToscaPropertyName(translateTo, HeatConstants.VOL_ID_PROPERTY_NAME);
260 relationTemplate.getProperties().put(toscaVolIdPropName, translatedId);
261 requirement.setNode(translatedId);
262 requirement.setRelationship(relationshipTemplateId);
263 DataModelUtil.addRelationshipTemplate(translateTo.getServiceTemplate(), relationshipTemplateId,
266 mdcDataDebugMessage.debugExitMessage(null, null);