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