2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.sdc.translator.services.heattotosca.impl;
23 import org.apache.commons.collections4.CollectionUtils;
24 import org.apache.commons.lang3.StringUtils;
25 import org.openecomp.sdc.common.errors.CoreException;
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.tosca.datatypes.ToscaCapabilityType;
31 import org.openecomp.sdc.tosca.datatypes.ToscaNodeType;
32 import org.openecomp.sdc.tosca.datatypes.ToscaRelationshipType;
33 import org.openecomp.sdc.tosca.datatypes.ToscaServiceModel;
34 import org.openecomp.sdc.tosca.datatypes.model.NodeTemplate;
35 import org.openecomp.sdc.tosca.datatypes.model.NodeType;
36 import org.openecomp.sdc.tosca.datatypes.model.RequirementDefinition;
37 import org.openecomp.sdc.tosca.datatypes.model.ServiceTemplate;
38 import org.openecomp.sdc.tosca.services.ToscaAnalyzerService;
39 import org.openecomp.sdc.tosca.services.impl.ToscaAnalyzerServiceImpl;
40 import org.openecomp.sdc.translator.datatypes.heattotosca.AttachedResourceId;
41 import org.openecomp.sdc.translator.datatypes.heattotosca.to.ResourceFileDataAndIDs;
42 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslateTo;
43 import org.openecomp.sdc.translator.datatypes.heattotosca.to.TranslatedHeatResource;
44 import org.openecomp.sdc.translator.services.heattotosca.HeatToToscaUtil;
45 import org.openecomp.sdc.translator.services.heattotosca.TranslationContext;
46 import org.openecomp.sdc.translator.services.heattotosca.errors.MissingMandatoryPropertyErrorBuilder;
47 import org.openecomp.sdc.translator.services.heattotosca.helper.VolumeTranslationHelper;
49 import java.util.ArrayList;
50 import java.util.Collections;
51 import java.util.List;
53 import java.util.Objects;
54 import java.util.Optional;
55 import java.util.function.Predicate;
56 import java.util.stream.Collectors;
58 class NovaToVolResourceConnection extends NovaAndPortResourceConnectionHelper {
60 public NovaToVolResourceConnection(ResourceTranslationBase resourceTranslationBase,
61 TranslateTo translateTo, FileData nestedFileData,
62 NodeTemplate substitutionNodeTemplate, NodeType nodeType) {
63 super(resourceTranslationBase, translateTo, nestedFileData, substitutionNodeTemplate, nodeType);
67 boolean isDesiredNodeTemplateType(NodeTemplate nodeTemplate) {
68 ToscaAnalyzerService toscaAnalyzerService = new ToscaAnalyzerServiceImpl();
69 ToscaServiceModel toscaServiceModel = HeatToToscaUtil.getToscaServiceModel(translateTo);
70 return toscaAnalyzerService.isTypeOf(nodeTemplate, ToscaNodeType.NOVA_SERVER.getDisplayName(),
71 translateTo.getContext().getTranslatedServiceTemplates()
72 .get(translateTo.getResource().getType()), toscaServiceModel);
76 List<Predicate<RequirementDefinition>> getPredicatesListForConnectionPoints() {
77 ArrayList<Predicate<RequirementDefinition>> predicates = new ArrayList<>();
79 .add(req -> req.getCapability().equals(ToscaCapabilityType.ATTACHMENT.getDisplayName())
80 && req.getNode().equals(ToscaNodeType.BLOCK_STORAGE.getDisplayName())
81 && req.getRelationship()
82 .equals(ToscaRelationshipType.NATIVE_ATTACHES_TO.getDisplayName()));
87 Optional<List<String>> getConnectorParamName(
88 String heatResourceId, Resource heatResource,
89 HeatOrchestrationTemplate nestedHeatOrchestrationTemplate) {
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 return Optional.of(Collections.singletonList((String) volumeId.get().getEntityId()));
96 return Optional.empty();
101 String getDesiredResourceType() {
102 return HeatResourcesTypes.CINDER_VOLUME_ATTACHMENT_RESOURCE_TYPE.getHeatResource();
106 protected Optional<List<Map.Entry<String, Resource>>> getResourceByTranslatedResourceId(
107 String translatedResourceId, HeatOrchestrationTemplate nestedHeatOrchestrationTemplate) {
109 List<Predicate<Map.Entry<String, Resource>>> predicates =
110 buildPredicates(nestedFileData.getFile(), nestedHeatOrchestrationTemplate,
111 translatedResourceId);
112 List<Map.Entry<String, Resource>> list =
113 nestedHeatOrchestrationTemplate.getResources().entrySet()
115 .filter(entry -> predicates
117 .allMatch(p -> p.test(entry)))
118 .collect(Collectors.toList());
119 if (CollectionUtils.isEmpty(list)) {
120 return Optional.empty();
122 return Optional.of(list);
126 private List<Predicate<Map.Entry<String, Resource>>> buildPredicates(String fileName,
127 HeatOrchestrationTemplate
128 heatOrchestrationTemplate,
130 novaTranslatedResourceId) {
131 List<Predicate<Map.Entry<String, Resource>>> list = new ArrayList<>();
132 list.add(entry -> entry.getValue().getType().equals(getDesiredResourceType()));
134 Object instanceUuidProp = entry.getValue().getProperties().get("instance_uuid");
135 TranslationContext context = translateTo.getContext();
136 Optional<AttachedResourceId> instanceUuid = HeatToToscaUtil
137 .extractAttachedResourceId(fileName, heatOrchestrationTemplate, context,
139 if (instanceUuid.isPresent()) {
140 Optional<String> resourceTranslatedId = ResourceTranslationBase
141 .getResourceTranslatedId(fileName, heatOrchestrationTemplate,
142 (String) instanceUuid.get().getTranslatedId(), context);
143 return resourceTranslatedId.isPresent()
144 && resourceTranslatedId.get().equals(novaTranslatedResourceId);
147 throw new CoreException(new MissingMandatoryPropertyErrorBuilder("instance_uuid").build());
154 String getTranslatedResourceIdFromSubstitutionMapping(ServiceTemplate nestedServiceTemplate,
156 RequirementDefinition> entry) {
157 List<String> substitutionMapping =
158 nestedServiceTemplate.getTopology_template().getSubstitution_mappings().getRequirements()
159 .get(entry.getKey());
160 return substitutionMapping.get(0);
164 void addRequirementToConnectResources(Map.Entry<String, RequirementDefinition> entry,
165 List<String> paramNames) {
166 String paramName = paramNames.get(0);
167 Optional<AttachedResourceId> attachedResourceId =
168 HeatToToscaUtil.extractAttachedResourceId(translateTo, paramName);
170 if (!attachedResourceId.isPresent()) {
173 AttachedResourceId attachedResource = attachedResourceId.get();
174 if (attachedResource.isGetResource()) {
175 String volTranslatedId = (String) attachedResource.getTranslatedId();
176 Resource volServerResource = HeatToToscaUtil
177 .getResource(translateTo.getHeatOrchestrationTemplate(), volTranslatedId,
178 translateTo.getHeatFileName());
179 if (!StringUtils.equals(HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource(),
180 volServerResource.getType())) {
181 logger.warn("Volume attachment used from nested resource " + translateTo.getResourceId()
182 + " is pointing to incorrect resource type(" + volServerResource.getType()
183 + ") for relation through the parameter '" + paramName + "."
184 + " The connection to the volume is ignored. "
185 + "Supported types are: "
186 + HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource());
189 node = volTranslatedId;
190 createRequirementAssignment(entry, node, substitutionNodeTemplate);
191 } else if (attachedResource.isGetParam()) {
192 TranslatedHeatResource shareResource =
193 translateTo.getContext().getHeatSharedResourcesByParam()
194 .get(attachedResource.getEntityId());
195 if (Objects.nonNull(shareResource)
196 && !HeatToToscaUtil.isHeatFileNested(translateTo, translateTo.getHeatFileName())) {
197 if (!StringUtils.equals(HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource(),
198 shareResource.getHeatResource().getType())) {
199 logger.warn("Volume attachment used from nested resource " + translateTo.getResourceId()
200 + " is pointing to incorrect resource type("
201 + shareResource.getHeatResource().getType() + ") for relation through the parameter '"
203 + " The connection to the volume is ignored. "
204 + "Supported types are: "
205 + HeatResourcesTypes.CINDER_VOLUME_RESOURCE_TYPE.getHeatResource());
208 node = shareResource.getTranslatedId();
209 createRequirementAssignment(entry, node, substitutionNodeTemplate);
210 } else if (Objects.isNull(shareResource)) {
211 List<FileData> allFilesData = translateTo.getContext().getManifest().getContent().getData();
212 Optional<FileData> fileData =
213 HeatToToscaUtil.getFileData(translateTo.getHeatFileName(), allFilesData);
214 if (fileData.isPresent()) {
215 Optional<ResourceFileDataAndIDs> fileDataContainingResource =
216 new VolumeTranslationHelper(logger)
217 .getFileDataContainingVolume(fileData.get().getData(),
218 (String) attachedResource.getEntityId(), translateTo, FileData.Type.HEAT_VOL);
219 if (fileDataContainingResource.isPresent()) {
220 createRequirementAssignment(entry,
221 fileDataContainingResource.get().getTranslatedResourceId(),
222 substitutionNodeTemplate);