e5c59968fa2d58b66b0f3714665ddbe8a595b58d
[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  * ============LICENSE_END=========================================================
16  * Modifications copyright (c) 2021 Nordix Foundation
17  * ================================================================================
18  */
19 package org.openecomp.sdc.vendorsoftwareproduct.dao.impl.zusammen;
20
21 import static org.openecomp.core.zusammen.api.ZusammenUtil.buildStructuralElement;
22 import static org.openecomp.core.zusammen.api.ZusammenUtil.createSessionContext;
23
24 import com.amdocs.zusammen.adaptor.inbound.api.types.item.Element;
25 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo;
26 import com.amdocs.zusammen.adaptor.inbound.api.types.item.ZusammenElement;
27 import com.amdocs.zusammen.datatypes.SessionContext;
28 import com.amdocs.zusammen.datatypes.item.Action;
29 import com.amdocs.zusammen.datatypes.item.ElementContext;
30 import com.amdocs.zusammen.utils.fileutils.FileUtils;
31 import java.io.ByteArrayInputStream;
32 import java.nio.ByteBuffer;
33 import java.nio.charset.StandardCharsets;
34 import java.nio.file.Path;
35 import java.util.Optional;
36 import lombok.AllArgsConstructor;
37 import lombok.Getter;
38 import org.openecomp.core.utilities.json.JsonUtil;
39 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
40 import org.openecomp.core.zusammen.api.ZusammenAdaptor;
41 import org.openecomp.sdc.be.csar.storage.ArtifactInfo;
42 import org.openecomp.sdc.be.csar.storage.ArtifactStorageConfig;
43 import org.openecomp.sdc.be.csar.storage.ArtifactStorageManager;
44 import org.openecomp.sdc.be.csar.storage.PersistentVolumeArtifactStorageConfig;
45 import org.openecomp.sdc.be.csar.storage.PersistentVolumeArtifactStorageManager;
46 import org.openecomp.sdc.common.CommonConfigurationManager;
47 import org.openecomp.sdc.common.errors.Messages;
48 import org.openecomp.sdc.datatypes.model.ElementType;
49 import org.openecomp.sdc.heat.datatypes.structure.ValidationStructureList;
50 import org.openecomp.sdc.logging.api.Logger;
51 import org.openecomp.sdc.logging.api.LoggerFactory;
52 import org.openecomp.sdc.vendorsoftwareproduct.dao.OrchestrationTemplateCandidateDao;
53 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.OrchestrationTemplateCandidateData;
54 import org.openecomp.sdc.vendorsoftwareproduct.types.candidateheat.FilesDataStructure;
55 import org.openecomp.sdc.versioning.dao.types.Version;
56
57 public class OrchestrationTemplateCandidateDaoZusammenImpl implements OrchestrationTemplateCandidateDao {
58
59     private static final Logger logger = LoggerFactory.getLogger(OrchestrationTemplateCandidateDaoZusammenImpl.class);
60     private static final String EMPTY_DATA = "{}";
61     private static final String EXTERNAL_CSAR_STORE = "externalCsarStore";
62     private final ZusammenAdaptor zusammenAdaptor;
63     private final ArtifactStorageManager artifactStorageManager;
64
65     public OrchestrationTemplateCandidateDaoZusammenImpl(final ZusammenAdaptor zusammenAdaptor) {
66         this.zusammenAdaptor = zusammenAdaptor;
67         this.artifactStorageManager = new PersistentVolumeArtifactStorageManager(readArtifactStorageConfiguration());
68     }
69
70     @Override
71     public void registerVersioning(String versionableEntityType) {
72         // registerVersioning not implemented for OrchestrationTemplateCandidateDaoZusammenImpl
73     }
74
75     @Override
76     public Optional<OrchestrationTemplateCandidateData> get(String vspId, Version version) {
77         logger.info("Getting orchestration template for vsp id {}", vspId);
78         SessionContext context = createSessionContext();
79         ElementContext elementContext = new ElementContext(vspId, version.getId());
80         Optional<Element> candidateElement = zusammenAdaptor
81             .getElementByName(context, elementContext, null, ElementType.OrchestrationTemplateCandidate.name());
82         if (!candidateElement.isPresent() || VspZusammenUtil.hasEmptyData(candidateElement.get().getData()) || candidateElement.get().getSubElements()
83             .isEmpty()) {
84             logger.info("Orchestration template for vsp id {} does not exist / has empty data", vspId);
85             return Optional.empty();
86         }
87         OrchestrationTemplateCandidateData candidate = new OrchestrationTemplateCandidateData();
88         candidate.setFilesDataStructure(new String(FileUtils.toByteArray(candidateElement.get().getData())));
89         candidateElement.get().getSubElements().stream()
90             .map(element -> zusammenAdaptor.getElement(context, elementContext, element.getElementId().toString()))
91             .forEach(element -> element.ifPresent(candidateInfoElement -> populateCandidate(candidate, candidateInfoElement, true)));
92         logger.info("Finished getting orchestration template for vsp id {}", vspId);
93         return candidate.getFileSuffix() == null ? Optional.empty() : Optional.of(candidate);
94     }
95
96     @Override
97     public Optional<OrchestrationTemplateCandidateData> getInfo(String vspId, Version version) {
98         logger.info("Getting orchestration template info for vsp id {}", vspId);
99         SessionContext context = createSessionContext();
100         ElementContext elementContext = new ElementContext(vspId, version.getId());
101         Optional<ElementInfo> candidateElement = zusammenAdaptor
102             .getElementInfoByName(context, elementContext, null, ElementType.OrchestrationTemplateCandidate.name());
103         if (!candidateElement.isPresent() || candidateElement.get().getSubElements().isEmpty()) {
104             logger.info("Orchestration template info for vsp id {} does not exist", vspId);
105             return Optional.empty();
106         }
107         OrchestrationTemplateCandidateData candidate = new OrchestrationTemplateCandidateData();
108         candidateElement.get().getSubElements().stream()
109             .map(elementInfo -> zusammenAdaptor.getElement(context, elementContext, elementInfo.getId().toString()))
110             .forEach(element -> element.ifPresent(candidateInfoElement -> populateCandidate(candidate, candidateInfoElement, false)));
111         logger.info("Finished getting orchestration template info for vsp id {}", vspId);
112         return candidate.getFileSuffix() == null ? Optional.empty() : Optional.of(candidate);
113     }
114
115     private void populateCandidate(final OrchestrationTemplateCandidateData candidate, final Element candidateInfoElement, final boolean fullData) {
116         final String elementName = candidateInfoElement.getInfo().getName();
117         if (ElementType.OrchestrationTemplateCandidateContent.name().equals(elementName)) {
118             if (fullData) {
119                 candidate.setContentData(ByteBuffer.wrap(FileUtils.toByteArray(candidateInfoElement.getData())));
120             }
121             candidate.setFileSuffix(candidateInfoElement.getInfo().getProperty(InfoPropertyName.FILE_SUFFIX.getVal()));
122             candidate.setFileName(candidateInfoElement.getInfo().getProperty(InfoPropertyName.FILE_NAME.getVal()));
123         } else if (ElementType.OrchestrationTemplateCandidateValidationData.name().equals(elementName)) {
124             candidate.setValidationData(new String(FileUtils.toByteArray(candidateInfoElement.getData())));
125         } else if (ElementType.ORIGINAL_ONBOARDED_PACKAGE.name().equals(elementName)) {
126             candidate.setOriginalFileName(candidateInfoElement.getInfo().getProperty(InfoPropertyName.ORIGINAL_FILE_NAME.getVal()));
127             candidate.setOriginalFileSuffix(candidateInfoElement.getInfo().getProperty(InfoPropertyName.ORIGINAL_FILE_SUFFIX.getVal()));
128             if (fullData) {
129                 candidate.setOriginalFileContentData(ByteBuffer.wrap(FileUtils.toByteArray(candidateInfoElement.getData())));
130             }
131         }
132     }
133
134     @Override
135     public void delete(String vspId, Version version) {
136         ByteArrayInputStream emptyData = new ByteArrayInputStream(EMPTY_DATA.getBytes());
137         ZusammenElement candidateContentElement = buildStructuralElement(ElementType.OrchestrationTemplateCandidateContent, Action.UPDATE);
138         candidateContentElement.setData(emptyData);
139         ZusammenElement validationData = buildStructuralElement(ElementType.OrchestrationTemplateCandidateValidationData, Action.UPDATE);
140         validationData.setData(emptyData);
141         ZusammenElement candidateElement = buildStructuralElement(ElementType.OrchestrationTemplateCandidate, Action.UPDATE);
142         candidateElement.setData(emptyData);
143         candidateElement.addSubElement(candidateContentElement);
144         candidateElement.addSubElement(validationData);
145         SessionContext context = createSessionContext();
146         ElementContext elementContext = new ElementContext(vspId, version.getId());
147         zusammenAdaptor.saveElement(context, elementContext, candidateElement, "Delete Orchestration Template Candidate Elements's content");
148     }
149
150     @Override
151     public void update(final String vspId, final Version version, final OrchestrationTemplateCandidateData candidateData) {
152         logger.info("Uploading candidate data entity for vsp id {}", vspId);
153         final ZusammenElement candidateElement = buildStructuralElement(ElementType.OrchestrationTemplateCandidate, Action.UPDATE);
154         candidateElement.setData(new ByteArrayInputStream(candidateData.getFilesDataStructure().getBytes()));
155         final ZusammenElement candidateContentElement = buildStructuralElement(ElementType.OrchestrationTemplateCandidateContent, Action.UPDATE);
156         candidateContentElement.setData(new ByteArrayInputStream(candidateData.getContentData().array()));
157         candidateContentElement.getInfo().addProperty(InfoPropertyName.FILE_SUFFIX.getVal(), candidateData.getFileSuffix());
158         candidateContentElement.getInfo().addProperty(InfoPropertyName.FILE_NAME.getVal(), candidateData.getFileName());
159         final String versionId = version.getId();
160         if (OnboardingTypesEnum.CSAR.toString().equalsIgnoreCase(candidateData.getFileSuffix())) {
161             final ZusammenElement originalPackageElement = buildStructuralElement(ElementType.ORIGINAL_ONBOARDED_PACKAGE, Action.UPDATE);
162             final String originalFileName = candidateData.getOriginalFileName();
163             final String originalFileSuffix = candidateData.getOriginalFileSuffix();
164             originalPackageElement.getInfo().addProperty(InfoPropertyName.ORIGINAL_FILE_NAME.getVal(), originalFileName);
165             originalPackageElement.getInfo().addProperty(InfoPropertyName.ORIGINAL_FILE_SUFFIX.getVal(), originalFileSuffix);
166             originalPackageElement.getInfo().addProperty("storeCsarsExternally", artifactStorageManager.isEnabled());
167             if (artifactStorageManager.isEnabled()) {
168                 final ArtifactInfo candidateArtifactInfo = candidateData.getArtifactInfo();
169                 if (candidateArtifactInfo == null) {
170                     throw new OrchestrationTemplateCandidateDaoZusammenException("No artifact info provided");
171                 }
172                 final ArtifactInfo artifactInfo = artifactStorageManager.persist(vspId, versionId, candidateArtifactInfo);
173                 originalPackageElement.setData(new ByteArrayInputStream(artifactInfo.getPath().toString().getBytes(StandardCharsets.UTF_8)));
174             } else {
175                 originalPackageElement.setData(new ByteArrayInputStream(candidateData.getOriginalFileContentData().array()));
176             }
177             candidateElement.addSubElement(originalPackageElement);
178         }
179         final ZusammenElement validationData = buildStructuralElement(ElementType.OrchestrationTemplateCandidateValidationData, Action.UPDATE);
180         if (candidateData.getValidationData() != null) {
181             validationData.setData(new ByteArrayInputStream(candidateData.getValidationData().getBytes()));
182         }
183         candidateElement.addSubElement(validationData);
184         candidateElement.addSubElement(candidateContentElement);
185         final var context = createSessionContext();
186         final var elementContext = new ElementContext(vspId, versionId);
187         zusammenAdaptor.saveElement(context, elementContext, candidateElement, "Update Orchestration Template Candidate");
188         logger.info("Finished uploading candidate data entity for vsp id {}", vspId);
189     }
190
191     @Override
192     public void updateValidationData(String vspId, Version version, ValidationStructureList validationData) {
193         logger.info("Updating validation data of orchestration template candidate for VSP id {} ", vspId);
194         ZusammenElement validationDataElement = buildStructuralElement(ElementType.OrchestrationTemplateCandidateValidationData, Action.UPDATE);
195         validationDataElement.setData(validationData == null ? new ByteArrayInputStream(EMPTY_DATA.getBytes())
196             : new ByteArrayInputStream(JsonUtil.object2Json(validationData).getBytes()));
197         ZusammenElement candidateElement = buildStructuralElement(ElementType.OrchestrationTemplateCandidate, Action.IGNORE);
198         candidateElement.addSubElement(validationDataElement);
199         SessionContext context = createSessionContext();
200         ElementContext elementContext = new ElementContext(vspId, version.getId());
201         zusammenAdaptor.saveElement(context, elementContext, candidateElement, "Update Orchestration Template Candidate validation data");
202         logger.info("Finished updating validation data of orchestration template candidate for VSP id {}", vspId);
203     }
204
205     @Override
206     public void updateStructure(String vspId, Version version, FilesDataStructure fileDataStructure) {
207         logger.info("Updating orchestration template for VSP id {}", vspId);
208         ZusammenElement candidateElement = buildStructuralElement(ElementType.OrchestrationTemplateCandidate, Action.UPDATE);
209         candidateElement.setData(new ByteArrayInputStream(JsonUtil.object2Json(fileDataStructure).getBytes()));
210         SessionContext context = createSessionContext();
211         ElementContext elementContext = new ElementContext(vspId, version.getId());
212         zusammenAdaptor.saveElement(context, elementContext, candidateElement, "Update Orchestration Template Candidate structure");
213         logger.info("Finished uploading candidate data entity for vsp id {}", vspId);
214     }
215
216     @Override
217     public Optional<String> getStructure(String vspId, Version version) {
218         logger.info("Getting orchestration template candidate structure for vsp id {}", vspId);
219         SessionContext context = createSessionContext();
220         ElementContext elementContext = new ElementContext(vspId, version.getId());
221         Optional<Element> element = zusammenAdaptor
222             .getElementByName(context, elementContext, null, ElementType.OrchestrationTemplateCandidate.name());
223         if (element.isPresent() && !VspZusammenUtil.hasEmptyData(element.get().getData())) {
224             return Optional.of(new String(FileUtils.toByteArray(element.get().getData())));
225         }
226         logger.info("Finished getting orchestration template candidate structure for vsp id {}", vspId);
227         return Optional.empty();
228     }
229
230     private ArtifactStorageConfig readArtifactStorageConfiguration() {
231         final var commonConfigurationManager = CommonConfigurationManager.getInstance();
232         final boolean isEnabled = commonConfigurationManager.getConfigValue(EXTERNAL_CSAR_STORE, "storeCsarsExternally", false);
233         logger.info("ArtifactConfig.isEnabled: '{}'", isEnabled);
234         final String storagePathString = commonConfigurationManager.getConfigValue(EXTERNAL_CSAR_STORE, "fullPath", null);
235         logger.info("ArtifactConfig.storagePath: '{}'", storagePathString);
236         if (isEnabled && storagePathString == null) {
237             throw new OrchestrationTemplateCandidateDaoZusammenException(
238                 Messages.EXTERNAL_CSAR_STORE_CONFIGURATION_FAILURE_MISSING_FULL_PATH.getErrorMessage());
239         }
240         final var storagePath = storagePathString == null ? null : Path.of(storagePathString);
241         return new PersistentVolumeArtifactStorageConfig(isEnabled, storagePath);
242     }
243
244     @Getter
245     @AllArgsConstructor
246     private enum InfoPropertyName {
247         FILE_SUFFIX("fileSuffix"), FILE_NAME("fileName"), ORIGINAL_FILE_NAME("originalFilename"), ORIGINAL_FILE_SUFFIX("originalFileSuffix");
248         private final String val;
249     }
250 }