[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 / NovaToVolResourceConnection.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.collections4.CollectionUtils;
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.HeatOrchestrationTemplate;
28 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
29 import org.openecomp.sdc.heat.datatypes.model.Resource;
30 import org.openecomp.sdc.logging.context.impl.MdcDataErrorMessage;
31 import org.openecomp.sdc.logging.types.LoggerConstants;
32 import org.openecomp.sdc.logging.types.LoggerErrorCode;
33 import org.openecomp.sdc.logging.types.LoggerErrorDescription;
34 import org.openecomp.sdc.logging.types.LoggerTragetServiceName;
35 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
36 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
37 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
38 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
39 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
40 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
41 import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition;
42 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
43 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
44 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
45 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
46 import org.openecomp.sdc.translator.datatypes.heattotosca.to.ResourceFileDataAndIDs;
47 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
48 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslatedHeatResource;
49 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
50 import org.openecomp.sdc.translator.services.heattotosca.errors.MissingMandatoryPropertyErrorBuilder;
51 import org.openecomp.sdc.translator.services.heattotosca.helper.VolumeTranslationHelper;
52
53 import java.util.ArrayList;
54 import java.util.Collections;
55 import java.util.List;
56 import java.util.Map;
57 import java.util.Objects;
58 import java.util.Optional;
59 import java.util.function.Predicate;
60 import java.util.stream.Collectors;
61
62 class NovaToVolResourceConnection extends ResourceConnectionUsingRequirementHelper {
63
64   public NovaToVolResourceConnection(ResourceTranslationBase resourceTranslationBase,
65                                      TranslateTo translateTo, FileData nestedFileData,
66                                      NodeTemplate substitutionNodeTemplate, NodeType nodeType) {
67     super(resourceTranslationBase, translateTo, nestedFileData, substitutionNodeTemplate, nodeType);
68   }
69
70   @Override
71   boolean isDesiredNodeTemplateType(NodeTemplate nodeTemplate) {
72     ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
73     ToscaServiceModel toscaServiceModel =
74         HeatToToscaUtil.getToscaServiceModel(translateTo.getContext());
75     return toscaAnalyzerService.isTypeOf(nodeTemplate, ToscaNodeType.NOVA_SERVER,
76         translateTo.getContext().getTranslatedServiceTemplates()
77             .get(translateTo.getResource().getType()), toscaServiceModel);
78   }
79
80   @Override
81   List<Predicate<RequirementDefinition>> getPredicatesListForConnectionPoints() {
82     ArrayList<Predicate<RequirementDefinition>> predicates = new ArrayList<>();
83     predicates
84         .add(req -> req.getCapability().equals(ToscaCapabilityType.NATIVE_ATTACHMENT)
85             && req.getNode().equals(ToscaNodeType.NATIVE_BLOCK_STORAGE)
86             && req.getRelationship()
87             .equals(ToscaRelationshipType.NATIVE_ATTACHES_TO));
88     return predicates;
89   }
90
91   @Override
92   Optional<List<String>> getConnectorPropertyParamName(String heatResourceId, Resource heatResource,
93                                                        HeatOrchestrationTemplate
94                                                            nestedHeatOrchestrationTemplate,
95                                                        String nestedHeatFileName) {
96
97
98     mdcDataDebugMessage.debugEntryMessage(null, null);
99
100     Optional<AttachedResourceId> volumeId = HeatToToscaUtil
101         .extractAttachedResourceId(nestedFileData.getFile(), nestedHeatOrchestrationTemplate,
102             translateTo.getContext(), heatResource.getProperties().get("volume_id"));
103     if (volumeId.isPresent() && volumeId.get().isGetParam()
104         && volumeId.get().getEntityId() instanceof String) {
105       mdcDataDebugMessage.debugExitMessage(null, null);
106       return Optional.of(Collections.singletonList((String) volumeId.get().getEntityId()));
107     } else {
108       mdcDataDebugMessage.debugExitMessage(null, null);
109       return Optional.empty();
110     }
111   }
112
113   @Override
114   String getDesiredResourceType() {
115     return HeatResourcesTypes.CINDER_VOLUME_ATTACHMENT_RESOURCE_TYPE.getHeatResource();
116   }
117
118   @Override
119   void addRequirementToConnectResources(
120       Map.Entry<String, RequirementDefinition> requirementDefinitionEntry,
121       List<String> paramNames) {
122
123
124     mdcDataDebugMessage.debugEntryMessage(null, null);
125
126     if (paramNames == null || paramNames.isEmpty()) {
127       return;
128     }
129
130     List<String> supportedVolumeTypes =
131         Collections.singletonList(HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource());
132
133     for (String paramName : paramNames) {
134       Object paramValue = translateTo.getResource().getProperties().get(paramName);
135       addRequirementToConnectResource(requirementDefinitionEntry, paramName, paramValue,
136           supportedVolumeTypes);
137     }
138
139     mdcDataDebugMessage.debugExitMessage(null, null);
140   }
141
142   @Override
143   boolean validateResourceTypeSupportedForReqCreation(String nestedResourceId,
144                                                       String nestedPropertyName,
145                                                       String connectionPointId,
146                                                       Resource connectedResource,
147                                                       List<String> supportedTypes) {
148
149
150     mdcDataDebugMessage.debugEntryMessage(null, null);
151
152     if (!resourceTranslationBase.isResourceTypeSupported(connectedResource, supportedTypes)) {
153       logger.warn("Nested resource '" + nestedResourceId + "' property '" + nestedPropertyName
154           + "' is pointing to a resource with type '" + connectedResource.getType()
155           + "' which is not supported for requirement '" + connectionPointId
156           + "' that connect VolumeAttachment to Volume. Supported types are: '"
157           + supportedTypes.toString()
158           + "', therefore, this TOSCA requirement will not be connected.");
159
160       mdcDataDebugMessage.debugExitMessage(null, null);
161       return false;
162     }
163
164     mdcDataDebugMessage.debugExitMessage(null, null);
165     return true;
166   }
167
168   @Override
169   protected Optional<List<Map.Entry<String, Resource>>> getResourceByTranslatedResourceId(
170       String translatedResourceId, HeatOrchestrationTemplate nestedHeatOrchestrationTemplate) {
171
172
173     mdcDataDebugMessage.debugEntryMessage(null, null);
174
175     List<Predicate<Map.Entry<String, Resource>>> predicates =
176         buildPredicates(nestedFileData.getFile(), nestedHeatOrchestrationTemplate,
177             translatedResourceId);
178     List<Map.Entry<String, Resource>> list =
179         nestedHeatOrchestrationTemplate.getResources().entrySet()
180             .stream()
181             .filter(entry -> predicates
182                 .stream()
183                     .allMatch(p -> p.test(entry)))
184             .collect(Collectors.toList());
185     if (CollectionUtils.isEmpty(list)) {
186       mdcDataDebugMessage.debugExitMessage(null, null);
187       return Optional.empty();
188     } else {
189       mdcDataDebugMessage.debugExitMessage(null, null);
190       return Optional.of(list);
191     }
192   }
193
194   @Override
195   Optional<String> getConnectionTranslatedNodeUsingGetParamFunc(
196       Map.Entry<String, RequirementDefinition> requirementDefinitionEntry, String paramName,
197       List<String> supportedTargetNodeTypes) {
198
199
200     mdcDataDebugMessage.debugEntryMessage(null, null);
201
202     Optional<String> targetTranslatedNodeId = super
203         .getConnectionTranslatedNodeUsingGetParamFunc(requirementDefinitionEntry, paramName,
204             supportedTargetNodeTypes);
205     if (targetTranslatedNodeId.isPresent()) {
206       return targetTranslatedNodeId;
207     } else {
208       Optional<AttachedResourceId> attachedResourceId =
209           HeatToToscaUtil.extractAttachedResourceId(translateTo, paramName);
210       if (!attachedResourceId.isPresent()) {
211         return Optional.empty();
212       }
213       AttachedResourceId resourceId = attachedResourceId.get();
214       if (resourceId.isGetParam() && resourceId.getEntityId() instanceof String) {
215         TranslatedHeatResource shareResource =
216             translateTo.getContext().getHeatSharedResourcesByParam().get(resourceId.getEntityId());
217         if (Objects.isNull(shareResource)) {
218           List<FileData> allFilesData =
219               translateTo.getContext().getManifest().getContent().getData();
220           Optional<FileData> fileData =
221               HeatToToscaUtil.getFileData(translateTo.getHeatFileName(), allFilesData);
222           if (fileData.isPresent()) {
223             Optional<ResourceFileDataAndIDs> fileDataContainingResource =
224                 new VolumeTranslationHelper(logger)
225                     .getFileDataContainingVolume(fileData.get().getData(),
226                         (String) resourceId.getEntityId(), translateTo, FileData.Type.HEAT_VOL);
227             if (fileDataContainingResource.isPresent()) {
228               mdcDataDebugMessage.debugExitMessage(null, null);
229               return Optional.of(fileDataContainingResource.get().getTranslatedResourceId());
230             }
231           }
232         }
233       }
234
235       mdcDataDebugMessage.debugExitMessage(null, null);
236       return Optional.empty();
237     }
238   }
239
240   private List<Predicate<Map.Entry<String, Resource>>> buildPredicates(
241       String fileName,
242       HeatOrchestrationTemplate heatOrchestrationTemplate,
243       String novaTranslatedResourceId) {
244     List<Predicate<Map.Entry<String, Resource>>> list = new ArrayList<>();
245     list.add(entry -> entry.getValue().getType().equals(getDesiredResourceType()));
246     list.add(entry -> {
247       Object instanceUuidProp = entry.getValue().getProperties().get("instance_uuid");
248       TranslationContext context = translateTo.getContext();
249       Optional<AttachedResourceId> instanceUuid = HeatToToscaUtil
250           .extractAttachedResourceId(fileName, heatOrchestrationTemplate, context,
251               instanceUuidProp);
252       if (instanceUuid.isPresent()) {
253         Optional<String> resourceTranslatedId =
254             ResourceTranslationBase.getResourceTranslatedId(fileName, heatOrchestrationTemplate,
255                 (String) instanceUuid.get().getTranslatedId(), context);
256         return resourceTranslatedId.isPresent()
257             && resourceTranslatedId.get().equals(novaTranslatedResourceId);
258
259       } else {
260         MdcDataErrorMessage.createErrorMessageAndUpdateMdc(LoggerConstants.TARGET_ENTITY_DB,
261             LoggerTragetServiceName.GET_RESOURCE, ErrorLevel.ERROR.name(),
262             LoggerErrorCode.DATA_ERROR.getErrorCode(),
263             LoggerErrorDescription.MISSING_MANDATORY_PROPERTY);
264         throw new CoreException(new MissingMandatoryPropertyErrorBuilder("instance_uuid").build());
265       }
266     });
267     return list;
268   }
269 }