Remove enter/exit debug #6
[sdc.git] / openecomp-be / lib / openecomp-sdc-translator-lib / openecomp-sdc-translator-core / src / main / java / org / openecomp / sdc / translator / services / heattotosca / impl / resourcetranslation / ResourceTranslationCinderVolumeAttachmentImpl.java
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.lang3.StringUtils;
24 import org.openecomp.sdc.common.errors.CoreException;
25 import org.openecomp.sdc.datatypes.error.ErrorLevel;
26 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
27 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
28 import org.openecomp.sdc.heat.datatypes.model.Resource;
29 import org.openecomp.sdc.heat.services.HeatConstants;
30 import org.openecomp.sdc.logging.api.Logger;
31 import org.openecomp.sdc.logging.api.LoggerFactory;
32 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
33 import org.openecomp.sdc.logging.types.LoggerConstants;
34 import org.openecomp.sdc.logging.types.LoggerErrorCode;
35 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
36 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
37 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
38 import org.openecomp.sdc.tosca.datatypes.ToscaTopologyTemplateElements;
39 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
40 import org.openecomp.sdc.tosca.datatypes.model.RelationshipTemplate;
41 import org.openecomp.sdc.tosca.datatypes.model.RequirementAssignment;
42 import org.openecomp.sdc.tosca.services.DataModelUtil;
43 import org.openecomp.sdc.tosca.services.ToscaConstants;
44 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
45 import org.openecomp.sdc.translator.datatypes.heattotosca.to.ResourceFileDataAndIDs;
46 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
47 import org.openecomp.sdc.translator.services.heattotosca.ConsolidationDataUtil;
48 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
49 import org.openecomp.sdc.translator.services.heattotosca.ResourceTranslationFactory;
50 import org.openecomp.sdc.translator.services.heattotosca.errors.MissingMandatoryPropertyErrorBuilder;
51 import org.openecomp.sdc.translator.services.heattotosca.helper.VolumeTranslationHelper;
52 import org.openecomp.sdc.translator.services.heattotosca.mapping.TranslatorHeatToToscaPropertyConverter;
53
54 import java.util.List;
55 import java.util.Optional;
56
57 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil.getResource;
58
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";
64
65   @Override
66   protected void translate(TranslateTo translateTo) {
67     RelationshipTemplate relationTemplate = new RelationshipTemplate();
68     relationTemplate.setType(ToscaRelationshipType.CINDER_VOLUME_ATTACHES_TO);
69     String relationshipTemplateId = translateTo.getTranslatedId();
70     String heatFileName = translateTo.getHeatFileName();
71     relationTemplate.setProperties(TranslatorHeatToToscaPropertyConverter
72         .getToscaPropertiesSimpleConversion(translateTo.getServiceTemplate(),translateTo
73             .getResourceId(),translateTo.getResource().getProperties(),
74             relationTemplate.getProperties(), heatFileName,
75             translateTo.getHeatOrchestrationTemplate(), translateTo.getResource().getType(),
76             relationTemplate, translateTo.getContext()));
77
78     AttachedResourceId attachedVolumeId = getAttachedResourceId(translateTo, volumeIdPropertyName);
79     String instanceUuid = HeatConstants.INSTANCE_UUID_PROPERTY_NAME;
80     AttachedResourceId attachedNovaServerId = getAttachedResourceId(translateTo, instanceUuid);
81
82     if (attachedNovaServerId.isGetResource()) {
83       handleNovaGetResource(translateTo, relationTemplate, relationshipTemplateId, heatFileName,
84           attachedVolumeId, (String) attachedNovaServerId.getEntityId());
85     } else {
86       logger.warn("Heat resource: '" + translateTo.getResourceId() + "' with type: '"
87           + translateTo.getResource().getType()
88           + "' include 'instance_uuid' property without 'get_resource' function, therefore this "
89           + "resource will be ignored in TOSCA translation.");
90     }
91   }
92
93   @Override
94   protected Optional<ToscaTopologyTemplateElements> getTranslatedToscaTopologyElement(
95       TranslateTo translateTo) {
96     if (isEssentialRequirementsValid(translateTo)) {
97       return Optional.of(ToscaTopologyTemplateElements.RELATIONSHIP_TEMPLATE);
98     } else {
99       return Optional.empty();
100     }
101   }
102
103   private AttachedResourceId getAttachedResourceId(TranslateTo translateTo, String propertyName) {
104     Optional<AttachedResourceId> attachedResourceId =
105         HeatToToscaUtil.extractAttachedResourceId(translateTo, propertyName);
106     if (!attachedResourceId.isPresent()) {
107       MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
108           LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
109           LoggerErrorCode.DATA_ERROR.getErrorCode(),
110           LoggerErrorDescription.MISSING_MANDATORY_PROPERTY);
111       throw new CoreException(new MissingMandatoryPropertyErrorBuilder(propertyName).build());
112     }
113     return attachedResourceId.get();
114   }
115
116   private void handleNovaGetResource(TranslateTo translateTo, RelationshipTemplate relationTemplate,
117                                      String relationshipTemplateId, String heatFileName,
118                                      AttachedResourceId volResourceId, String novaResourceId) {
119     RequirementAssignment requirement = new RequirementAssignment();
120     requirement.setCapability(toscaCapabilityAttachment);
121     if (volResourceId.isGetResource()) {
122       Resource volServerResource = getResource(translateTo.getHeatOrchestrationTemplate(),
123           (String) volResourceId.getTranslatedId(), heatFileName);
124       if (!StringUtils.equals(HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource(),
125           volServerResource.getType())) {
126         logger.warn("Volume attachment with id '" + translateTo.getResourceId()
127             + "' is pointing to unsupported resource type(" + volServerResource.getType()
128             + ") through the property 'volume_id'."
129             + " The connection to the volume is ignored. "
130             + "Supported types are: "
131             + HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource());
132         return;
133       }
134       requirement.setNode((String) volResourceId.getTranslatedId());
135       requirement.setRelationship(relationshipTemplateId);
136       DataModelUtil
137           .addRelationshipTemplate(translateTo.getServiceTemplate(), relationshipTemplateId,
138               relationTemplate);
139     } else if (volResourceId.isGetParam() && volResourceId.getEntityId() instanceof String) {
140       String volumeResourceIdParamName = (String) volResourceId.getEntityId();
141       if (translateTo.getContext().getHeatSharedResourcesByParam()
142           .containsKey(volumeResourceIdParamName) && !isHeatFileNested(translateTo, heatFileName)) {
143         Resource volServerResource =
144             translateTo.getContext().getHeatSharedResourcesByParam().get(volumeResourceIdParamName)
145                 .getHeatResource();
146         if (!StringUtils.equals(HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource(),
147             volServerResource.getType())) {
148           logger.warn("Volume attachment with id '" + translateTo.getResourceId()
149               + "' is pointing to unsupported resource type(" + volServerResource.getType()
150               + ") through the property 'volume_id'."
151               + " The connection to the volume is ignored. "
152               + "Supported types are: "
153               + HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource());
154           return;
155         }
156         requirement.setNode(
157             translateTo.getContext().getHeatSharedResourcesByParam().get(volumeResourceIdParamName)
158                 .getTranslatedId());
159         requirement.setRelationship(relationshipTemplateId);
160         DataModelUtil
161             .addRelationshipTemplate(translateTo.getServiceTemplate(), relationshipTemplateId,
162                 relationTemplate);
163       } else {
164         handleUnsharedVolume(translateTo, relationTemplate, relationshipTemplateId, heatFileName,
165             requirement, volumeResourceIdParamName);
166       }
167     }
168     Resource novaServerResource =
169         getResource(translateTo.getHeatOrchestrationTemplate(), novaResourceId, heatFileName);
170     if (!StringUtils.equals(HeatResourcesTypes.NOVA_SERVER_RESOURCE_TYPE.getHeatResource(),
171         novaServerResource.getType())) {
172       logger.warn("Volume attachment with id '" + translateTo.getResourceId()
173           + "' is pointing to unsupported resource type(" + novaServerResource.getType()
174           + ") through the property 'instance_uuid'."
175           + " The connection to the nova server is ignored. "
176           + "Supported types are: "
177           + HeatResourcesTypes.NOVA_SERVER_RESOURCE_TYPE.getHeatResource());
178       return;
179     }
180     Optional<String> translatedNovaServerId =
181         ResourceTranslationFactory.getInstance(novaServerResource)
182             .translateResource(heatFileName, translateTo.getServiceTemplate(),
183                 translateTo.getHeatOrchestrationTemplate(), novaServerResource, novaResourceId,
184                 translateTo.getContext());
185
186     if (translatedNovaServerId.isPresent() && StringUtils.isNotEmpty(requirement.getNode())) {
187       NodeTemplate novaServerNodeTemplate = DataModelUtil
188           .getNodeTemplate(translateTo.getServiceTemplate(), translatedNovaServerId.get());
189       DataModelUtil.addRequirementAssignment(novaServerNodeTemplate, ToscaConstants
190           .LOCAL_STORAGE_REQUIREMENT_ID, requirement);
191       //Add volume information to consolidation data
192       ConsolidationDataUtil.updateComputeConsolidationDataVolumes(translateTo,
193           novaServerNodeTemplate.getType(), translatedNovaServerId.get(), ToscaConstants
194           .LOCAL_STORAGE_REQUIREMENT_ID, requirement);
195     }
196   }
197
198   private void handleUnsharedVolume(TranslateTo translateTo, RelationshipTemplate relationTemplate,
199                                     String relationshipTemplateId, String heatFileName,
200                                     RequirementAssignment requirement, String volumeResourceId) {
201     List<FileData> allFilesData = translateTo.getContext().getManifest().getContent().getData();
202     Optional<FileData> fileData = HeatToToscaUtil.getFileData(heatFileName, allFilesData);
203     if (fileData.isPresent()) {
204       Optional<ResourceFileDataAndIDs> fileDataContainingResource =
205           new VolumeTranslationHelper(logger)
206               .getFileDataContainingVolume(fileData.get().getData(), volumeResourceId, translateTo,
207                   FileData.Type.HEAT_VOL);
208       fileDataContainingResource.ifPresent(
209           resourceFileDataAndIDs -> addRelationshipToServiceTemplate(translateTo, relationTemplate,
210               relationshipTemplateId, requirement, resourceFileDataAndIDs));
211     }
212   }
213
214   private boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
215     return translateTo.getContext().getNestedHeatsFiles().contains(heatFileName);
216   }
217
218   private void addRelationshipToServiceTemplate(TranslateTo translateTo,
219                                                 RelationshipTemplate relationTemplate,
220                                                 String relationshipTemplateId,
221                                                 RequirementAssignment requirement,
222                                                 ResourceFileDataAndIDs resourceFileDataAndIDs) {
223     String translatedId = resourceFileDataAndIDs.getTranslatedResourceId();
224     String toscaVolIdPropName =
225         HeatToToscaUtil.getToscaPropertyName(translateTo, HeatConstants.VOL_ID_PROPERTY_NAME);
226     relationTemplate.getProperties().put(toscaVolIdPropName, translatedId);
227     requirement.setNode(translatedId);
228     requirement.setRelationship(relationshipTemplateId);
229     DataModelUtil.addRelationshipTemplate(translateTo.getServiceTemplate(), relationshipTemplateId,
230         relationTemplate);
231   }
232 }