[SDC-29] Amdocs OnBoard 1707 initial commit.
[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 static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil.getResource;
24
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;
55
56 import java.util.List;
57 import java.util.Optional;
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
68
69     mdcDataDebugMessage.debugEntryMessage(null, null);
70
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()));
81
82     AttachedResourceId attachedVolumeId = getAttachedResourceId(translateTo, volumeIdPropertyName);
83     String instanceUuid = HeatConstants.INSTANCE_UUID_PROPERTY_NAME;
84     AttachedResourceId attachedNovaServerId = getAttachedResourceId(translateTo, instanceUuid);
85
86     if (attachedNovaServerId.isGetResource()) {
87       handleNovaGetResource(translateTo, relationTemplate, relationshipTemplateId, heatFileName,
88           attachedVolumeId, (String) attachedNovaServerId.getEntityId());
89     } else {
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.");
94     }
95
96     mdcDataDebugMessage.debugExitMessage(null, null);
97   }
98
99   @Override
100   protected Optional<ToscaTopologyTemplateElements> getTranslatedToscaTopologyElement(
101       TranslateTo translateTo) {
102     if (isEssentialRequirementsValid(translateTo)) {
103       return Optional.of(ToscaTopologyTemplateElements.RELATIONSHIP_TEMPLATE);
104     } else {
105       return Optional.empty();
106     }
107   }
108
109   private AttachedResourceId getAttachedResourceId(TranslateTo translateTo, String propertyName) {
110
111
112     mdcDataDebugMessage.debugEntryMessage(null, null);
113
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());
122     }
123
124     mdcDataDebugMessage.debugExitMessage(null, null);
125     return attachedResourceId.get();
126   }
127
128   private void handleNovaGetResource(TranslateTo translateTo, RelationshipTemplate relationTemplate,
129                                      String relationshipTemplateId, String heatFileName,
130                                      AttachedResourceId volResourceId, String novaResourceId) {
131
132
133     mdcDataDebugMessage.debugEntryMessage(null, null);
134
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());
148
149         mdcDataDebugMessage.debugExitMessage(null, null);
150         return;
151       }
152       requirement.setNode((String) volResourceId.getTranslatedId());
153       requirement.setRelationship(relationshipTemplateId);
154       DataModelUtil
155           .addRelationshipTemplate(translateTo.getServiceTemplate(), relationshipTemplateId,
156               relationTemplate);
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)
163                 .getHeatResource();
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());
172
173           mdcDataDebugMessage.debugExitMessage(null, null);
174           return;
175         }
176         requirement.setNode(
177             translateTo.getContext().getHeatSharedResourcesByParam().get(volumeResourceIdParamName)
178                 .getTranslatedId());
179         requirement.setRelationship(relationshipTemplateId);
180         DataModelUtil
181             .addRelationshipTemplate(translateTo.getServiceTemplate(), relationshipTemplateId,
182                 relationTemplate);
183       } else {
184         handleUnsharedVolume(translateTo, relationTemplate, relationshipTemplateId, heatFileName,
185             requirement, volumeResourceIdParamName);
186       }
187     }
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());
198
199       mdcDataDebugMessage.debugExitMessage(null, null);
200       return;
201     }
202     Optional<String> translatedNovaServerId =
203         ResourceTranslationFactory.getInstance(novaServerResource)
204             .translateResource(heatFileName, translateTo.getServiceTemplate(),
205                 translateTo.getHeatOrchestrationTemplate(), novaServerResource, novaResourceId,
206                 translateTo.getContext());
207
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);
217     }
218
219     mdcDataDebugMessage.debugExitMessage(null, null);
220   }
221
222   private void handleUnsharedVolume(TranslateTo translateTo, RelationshipTemplate relationTemplate,
223                                     String relationshipTemplateId, String heatFileName,
224                                     RequirementAssignment requirement, String volumeResourceId) {
225
226
227     mdcDataDebugMessage.debugEntryMessage(null, null);
228
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));
239     }
240
241     mdcDataDebugMessage.debugExitMessage(null, null);
242   }
243
244   private boolean isHeatFileNested(TranslateTo translateTo, String heatFileName) {
245     return translateTo.getContext().getNestedHeatsFiles().contains(heatFileName);
246   }
247
248   private void addRelationshipToServiceTemplate(TranslateTo translateTo,
249                                                 RelationshipTemplate relationTemplate,
250                                                 String relationshipTemplateId,
251                                                 RequirementAssignment requirement,
252                                                 ResourceFileDataAndIDs resourceFileDataAndIDs) {
253
254
255     mdcDataDebugMessage.debugEntryMessage(null, null);
256
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,
264         relationTemplate);
265
266     mdcDataDebugMessage.debugExitMessage(null, null);
267   }
268 }