cd8e3764e209dc9396884eb9e482fda53ea4344e
[sdc.git] /
1 /*
2  * Copyright © 2016-2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.openecomp.sdc.translator.services.heattotosca.impl.resourcetranslation;
18
19 import static org.openecomp.sdc.translator.services.heattotosca.HeatToToscaLogConstants.LOG_UNSUPPORTED_VOL_ATTACHMENT_VOLUME_REQUIREMENT_CONNECTION;
20
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Objects;
26 import java.util.Optional;
27 import java.util.function.Predicate;
28 import java.util.stream.Collectors;
29
30 import org.apache.commons.collections4.CollectionUtils;
31 import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
32 import org.onap.sdc.tosca.datatypes.model.NodeType;
33 import org.onap.sdc.tosca.datatypes.model.RequirementDefinition;
34 import org.openecomp.sdc.common.errors.CoreException;
35 import org.openecomp.sdc.heat.datatypes.manifest.FileData;
36 import org.openecomp.sdc.heat.datatypes.model.HeatOrchestrationTemplate;
37 import org.openecomp.sdc.heat.datatypes.model.HeatResourcesTypes;
38 import org.openecomp.sdc.heat.datatypes.model.Resource;
39 import org.openecomp.sdc.tosca.datatypes.ToscaCapabilityType;
40 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
41 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
42 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
43 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
44 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
45 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
46 import org.openecomp.sdc.translator.datatypes.heattotosca.TranslationContext;
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.datatypes.heattotosca.to.TranslatedHeatResource;
50 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
51 import org.openecomp.sdc.translator.services.heattotosca.errors.MissingMandatoryPropertyErrorBuilder;
52 import org.openecomp.sdc.translator.services.heattotosca.helper.VolumeTranslationHelper;
53
54 class NovaToVolResourceConnection extends ResourceConnectionUsingRequirementHelper {
55
56     NovaToVolResourceConnection(ResourceTranslationBase resourceTranslationBase,
57                                 TranslateTo translateTo, FileData nestedFileData,
58                                 NodeTemplate substitutionNodeTemplate, NodeType nodeType) {
59         super(resourceTranslationBase, translateTo, nestedFileData, substitutionNodeTemplate, nodeType);
60     }
61
62     @Override
63     boolean isDesiredNodeTemplateType(NodeTemplate nodeTemplate) {
64         ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
65         ToscaServiceModel toscaServiceModel =
66                 HeatToToscaUtil.getToscaServiceModel(translateTo.getContext());
67         return toscaAnalyzerService.isTypeOf(nodeTemplate, ToscaNodeType.NOVA_SERVER,
68                 translateTo.getContext().getTranslatedServiceTemplates()
69                         .get(translateTo.getResource().getType()), toscaServiceModel);
70     }
71
72     @Override
73     List<Predicate<RequirementDefinition>> getPredicatesListForConnectionPoints() {
74         ArrayList<Predicate<RequirementDefinition>> predicates = new ArrayList<>();
75         predicates
76                 .add(req -> req.getCapability().equals(ToscaCapabilityType.NATIVE_ATTACHMENT)
77                         && req.getNode().equals(ToscaNodeType.NATIVE_BLOCK_STORAGE)
78                         && req.getRelationship()
79                         .equals(ToscaRelationshipType.NATIVE_ATTACHES_TO));
80         return predicates;
81     }
82
83     @Override
84     Optional<List<String>> getConnectorPropertyParamName(String heatResourceId, Resource heatResource,
85                                                          HeatOrchestrationTemplate
86                                                                  nestedHeatOrchestrationTemplate,
87                                                          String nestedHeatFileName) {
88
89
90         Optional<AttachedResourceId> volumeId = HeatToToscaUtil
91                 .extractAttachedResourceId(nestedFileData.getFile(), nestedHeatOrchestrationTemplate,
92                         translateTo.getContext(), heatResource.getProperties().get("volume_id"));
93         if (volumeId.isPresent() && volumeId.get().isGetParam()
94                 && volumeId.get().getEntityId() instanceof String) {
95             return Optional.of(Collections.singletonList((String) volumeId.get().getEntityId()));
96         } else {
97             return Optional.empty();
98         }
99     }
100
101     @Override
102     String getDesiredResourceType() {
103         return HeatResourcesTypes.CINDER_VOLUME_ATTACHMENT_RESOURCE_TYPE.getHeatResource();
104     }
105
106     @Override
107     void addRequirementToConnectResources(
108             Map.Entry<String, RequirementDefinition> requirementDefinitionEntry,
109             List<String> paramNames) {
110
111
112         if (paramNames == null || paramNames.isEmpty()) {
113             return;
114         }
115
116         List<String> supportedVolumeTypes =
117                 Collections.singletonList(HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource());
118
119         for (String paramName : paramNames) {
120             Object paramValue = translateTo.getResource().getProperties().get(paramName);
121             addRequirementToConnectResource(requirementDefinitionEntry, paramName, paramValue,
122                     supportedVolumeTypes);
123         }
124
125     }
126
127     @Override
128     boolean validateResourceTypeSupportedForReqCreation(String nestedResourceId,
129                                                         String nestedPropertyName,
130                                                         String connectionPointId,
131                                                         Resource connectedResource,
132                                                         List<String> supportedTypes) {
133
134
135         if (resourceTranslationBase.isUnsupportedResourceType(connectedResource, supportedTypes)) {
136             logger.warn(LOG_UNSUPPORTED_VOL_ATTACHMENT_VOLUME_REQUIREMENT_CONNECTION, nestedResourceId,
137                     nestedPropertyName, connectedResource.getType(), connectionPointId, supportedTypes.toString());
138             return false;
139         }
140
141         return true;
142     }
143
144     @Override
145     protected Optional<List<Map.Entry<String, Resource>>> getResourceByTranslatedResourceId(
146             String translatedResourceId, HeatOrchestrationTemplate nestedHeatOrchestrationTemplate) {
147
148
149         List<Predicate<Map.Entry<String, Resource>>> predicates =
150                 buildPredicates(nestedFileData.getFile(), nestedHeatOrchestrationTemplate,
151                         translatedResourceId);
152         List<Map.Entry<String, Resource>> list =
153                 nestedHeatOrchestrationTemplate.getResources().entrySet()
154                         .stream()
155                         .filter(entry -> predicates
156                                 .stream()
157                                 .allMatch(p -> p.test(entry)))
158                         .collect(Collectors.toList());
159         if (CollectionUtils.isEmpty(list)) {
160             return Optional.empty();
161         } else {
162             return Optional.of(list);
163         }
164     }
165
166     @Override
167     Optional<String> getConnectionTranslatedNodeUsingGetParamFunc(
168             Map.Entry<String, RequirementDefinition> requirementDefinitionEntry, String paramName,
169             List<String> supportedTargetNodeTypes) {
170
171
172         Optional<String> targetTranslatedNodeId = super
173                 .getConnectionTranslatedNodeUsingGetParamFunc(requirementDefinitionEntry, paramName,
174                         supportedTargetNodeTypes);
175         if (targetTranslatedNodeId.isPresent()) {
176             return targetTranslatedNodeId;
177         }
178         Optional<AttachedResourceId> attachedResourceId =
179                 HeatToToscaUtil.extractAttachedResourceId(translateTo, paramName);
180         if (!attachedResourceId.isPresent()) {
181             return Optional.empty();
182         }
183         AttachedResourceId resourceId = attachedResourceId.get();
184         if (resourceId.isGetParam() && resourceId.getEntityId() instanceof String) {
185             TranslatedHeatResource shareResource =
186                     translateTo.getContext().getHeatSharedResourcesByParam().get(resourceId.getEntityId());
187             if (Objects.nonNull(shareResource)) {
188                 return Optional.empty();
189             }
190             List<FileData> allFilesData = translateTo.getContext().getManifest().getContent().getData();
191             Optional<FileData> fileData = HeatToToscaUtil.getFileData(translateTo.getHeatFileName(), allFilesData);
192             if (fileData.isPresent()) {
193                 Optional<ResourceFileDataAndIDs> fileDataContainingResource = new VolumeTranslationHelper(logger)
194                                 .getFileDataContainingVolume(fileData.get().getData(),
195                                         (String) resourceId.getEntityId(), translateTo, FileData.Type.HEAT_VOL);
196                 if (fileDataContainingResource.isPresent()) {
197                     return Optional.of(fileDataContainingResource.get().getTranslatedResourceId());
198                 }
199             }
200         }
201
202         return Optional.empty();
203     }
204
205     private List<Predicate<Map.Entry<String, Resource>>> buildPredicates(
206             String fileName,
207             HeatOrchestrationTemplate heatOrchestrationTemplate,
208             String novaTranslatedResourceId) {
209         List<Predicate<Map.Entry<String, Resource>>> list = new ArrayList<>();
210         list.add(entry -> entry.getValue().getType().equals(getDesiredResourceType()));
211         list.add(entry -> {
212             Object instanceUuidProp = entry.getValue().getProperties().get("instance_uuid");
213             TranslationContext context = translateTo.getContext();
214             Optional<AttachedResourceId> instanceUuid = HeatToToscaUtil
215                     .extractAttachedResourceId(fileName, heatOrchestrationTemplate, context,
216                             instanceUuidProp);
217             if (instanceUuid.isPresent()) {
218                 Optional<String> resourceTranslatedId =
219                         ResourceTranslationBase.getResourceTranslatedId(fileName, heatOrchestrationTemplate,
220                                 (String) instanceUuid.get().getTranslatedId(), context);
221                 return resourceTranslatedId.isPresent()
222                         && resourceTranslatedId.get().equals(novaTranslatedResourceId);
223
224             } else {
225                 throw new CoreException(new MissingMandatoryPropertyErrorBuilder("instance_uuid").build());
226             }
227         });
228         return list;
229     }
230 }