Implement 'Update Service by importing Tosca Template'-story
[sdc.git] / catalog-be / src / main / java / org / openecomp / sdc / be / components / impl / CsarValidationUtils.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 package org.openecomp.sdc.be.components.impl;
21
22 import fj.data.Either;
23 import java.io.ByteArrayInputStream;
24 import java.io.IOException;
25 import java.io.StringReader;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Optional;
31 import java.util.Properties;
32 import java.util.regex.Matcher;
33 import java.util.regex.Pattern;
34 import java.util.stream.Collectors;
35 import org.apache.commons.lang3.tuple.ImmutablePair;
36 import org.openecomp.sdc.be.config.BeEcompErrorManager;
37 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
38 import org.openecomp.sdc.be.dao.api.ActionStatus;
39 import org.openecomp.sdc.be.impl.ComponentsUtils;
40 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
41 import org.openecomp.sdc.be.tosca.CsarUtils;
42 import org.openecomp.sdc.common.log.wrappers.Logger;
43 import org.openecomp.sdc.common.util.GeneralUtility;
44 import org.openecomp.sdc.exception.ResponseFormat;
45
46 public class CsarValidationUtils {
47
48     private static final Logger log = Logger.getLogger(CsarValidationUtils.class.getName());
49     private static final String TOSCA_META_FILE_VERSION = "TOSCA-Meta-File-Version";
50     private static final String CSAR_VERSION = "CSAR-Version";
51     private static final String CREATED_BY = "Created-By";
52     private static final String NEW_LINE_DELM = "\n";
53     private static final String TOSCA_METADATA = "TOSCA-Metadata";
54     private static final String TOSCA_FILE = "TOSCA.meta";
55     private static final String DEL_PATTERN = "([/\\\\]+)";
56     private static final String TOSCA_METADATA_PATH_PATTERN = TOSCA_METADATA +
57         // Artifact Group (i.e Deployment/Informational)
58         DEL_PATTERN + TOSCA_FILE;
59     private static final String TOSCA_META_ENTRY_DEFINITIONS = "Entry-Definitions";
60     private static final String[] TOSCA_METADATA_FIELDS = {TOSCA_META_FILE_VERSION, CSAR_VERSION, CREATED_BY, TOSCA_META_ENTRY_DEFINITIONS};
61     private static final String ARTIFACTS_METADATA_FILE = "HEAT.meta";
62     private static final String TOSCA_CSAR_EXTENSION = ".csar";
63     private static final String TOSCA_METADATA_TOSCA_META_FILE_IS_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_CSAR_ID = "TOSCA-Metadata/TOSCA.meta file is not in expected key-value form in csar, csar ID {}";
64     private static final String TOSCA_METADATA_TOSCA_META_FILE_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_WITH_ID = "TOSCA-Metadata/TOSCA.meta file not in expected key-value form in CSAR with id ";
65     private static final String CSAR_INTERNALS_ARE_INVALID = "CSAR internals are invalid";
66     private static final String ENTRY_DEFINITIONS_ENTRY_NOT_FOUND_IN_TOSCA_METADATA_TOSCA_META_FILE_CSAR_ID = "Entry-Definitions entry not found in TOSCA-Metadata/TOSCA.meta file, csar ID {}";
67     private static final String FILE_NOT_FOUND_IN_CSAR_WITH_ID = " file not found in CSAR with id ";
68     private static final String CSAR_STRUCTURE_IS_INVALID = "CSAR structure is invalid";
69     private static final String ENTRY_DEFINITIONS = "Entry-Definitions ";
70     private static final Pattern floatPattern = Pattern.compile("^\\d{1}[.]\\d{1}$");
71
72     /**
73      * Utility classes, which are collections of static members, are not meant to be instantiated
74      */
75     private CsarValidationUtils() {
76     }
77
78     /**
79      * Validates Csar
80      *
81      * @param csar
82      * @param csarUUID
83      * @param componentsUtils
84      * @return
85      */
86     public static Either<Boolean, ResponseFormat> validateCsar(Map<String, byte[]> csar, String csarUUID, ComponentsUtils componentsUtils) {
87         Either<Boolean, ResponseFormat> validateStatus = validateIsTOSCAMetadataExist(csar, csarUUID, componentsUtils);
88         if (validateStatus.isRight()) {
89             return Either.right(validateStatus.right().value());
90         }
91         removeNonUniqueArtifactsFromCsar(csar);
92         log.trace("TOSCA-Metadata/TOSCA.meta file found, CSAR id {}", csarUUID);
93         validateStatus = validateTOSCAMetadataFile(csar, csarUUID, componentsUtils);
94         if (validateStatus.isRight()) {
95             return Either.right(validateStatus.right().value());
96         }
97         return Either.left(true);
98     }
99
100     private static void removeNonUniqueArtifactsFromCsar(Map<String, byte[]> csar) {
101         List<String> nonUniqueArtifactsToRemove = new ArrayList<>();
102         String[] paths = csar.keySet().toArray(new String[csar.keySet().size()]);
103         int numberOfArtifacts = paths.length;
104         for (int i = 0; i < numberOfArtifacts; ++i) {
105             collectNonUniqueArtifact(paths, i, numberOfArtifacts, nonUniqueArtifactsToRemove);
106         }
107         nonUniqueArtifactsToRemove.stream().forEach(csar::remove);
108     }
109
110     private static void collectNonUniqueArtifact(String[] paths, int currInd, int numberOfArtifacts, List<String> nonUniqueArtifactsToRemove) {
111         String[] parsedPath = paths[currInd].split("/");
112         String[] otherParsedPath;
113         int artifactNameInd = parsedPath.length - 1;
114         for (int j = currInd + 1; j < numberOfArtifacts; ++j) {
115             otherParsedPath = paths[j].split("/");
116             if (parsedPath.length == otherParsedPath.length && parsedPath.length > 3 && isEqualArtifactNames(parsedPath, otherParsedPath)) {
117                 log.error(
118                     "Can't upload two artifact with the same name {}. The artifact with path {} will be handled, and the artifact with path {} will be ignored. ",
119                     parsedPath[artifactNameInd], paths[currInd], paths[j]);
120                 nonUniqueArtifactsToRemove.add(paths[j]);
121             }
122         }
123     }
124
125     private static boolean isEqualArtifactNames(String[] parsedPath, String[] otherParsedPath) {
126         boolean isEqualArtifactNames = false;
127         int artifactNameInd = parsedPath.length - 1;
128         int artifactGroupTypeInd = parsedPath.length - 3;
129         String groupType = parsedPath[artifactGroupTypeInd];
130         String artifactName = parsedPath[artifactNameInd];
131         String otherGroupType = otherParsedPath[artifactGroupTypeInd];
132         String otherArtifactName = otherParsedPath[artifactNameInd];
133         String vfcToscaName = parsedPath.length == 5 ? parsedPath[1] : null;
134         if (artifactName.equalsIgnoreCase(otherArtifactName) && groupType.equalsIgnoreCase(otherGroupType)) {
135             isEqualArtifactNames = vfcToscaName == null || vfcToscaName.equalsIgnoreCase(otherParsedPath[1]);
136         }
137         return isEqualArtifactNames;
138     }
139
140     public static Either<ImmutablePair<String, String>, ResponseFormat> getToscaYaml(Map<String, byte[]> csar, String csarUUID,
141                                                                                      ComponentsUtils componentsUtils, AuditingActionEnum auditingAction) {
142         if (!AuditingActionEnum.UPDATE_SERVICE_TOSCA_TEMPLATE.equals(auditingAction)) {
143             Either<Boolean, ResponseFormat> validateStatus = validateIsTOSCAMetadataExist(csar, csarUUID, componentsUtils);
144             if (validateStatus.isRight()) {
145                 return Either.right(validateStatus.right().value());
146             }
147         }
148         Pattern pattern = Pattern.compile(TOSCA_METADATA_PATH_PATTERN);
149         Optional<String> keyOp = csar.keySet().stream().filter(k -> pattern.matcher(k).matches()).findAny();
150         if (!keyOp.isPresent()) {
151             log.debug(TOSCA_METADATA_TOSCA_META_FILE_IS_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_CSAR_ID, csarUUID);
152             BeEcompErrorManager.getInstance()
153                     .logInternalDataError(TOSCA_METADATA_TOSCA_META_FILE_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_WITH_ID + csarUUID,
154                             CSAR_INTERNALS_ARE_INVALID, ErrorSeverity.ERROR);
155             return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, csarUUID));
156         }
157         byte[] toscaMetaBytes = csar.get(keyOp.get());
158         Properties props = new Properties();
159         try {
160             String propStr = new String(toscaMetaBytes);
161             props.load(new StringReader(propStr.replace("\\", "\\\\")));
162         } catch (IOException e) {
163             log.debug(TOSCA_METADATA_TOSCA_META_FILE_IS_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_CSAR_ID, csarUUID, e);
164             BeEcompErrorManager.getInstance()
165                     .logInternalDataError(TOSCA_METADATA_TOSCA_META_FILE_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_WITH_ID + csarUUID,
166                             CSAR_INTERNALS_ARE_INVALID, ErrorSeverity.ERROR);
167             return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, csarUUID));
168         }
169         String yamlFileName = props.getProperty(TOSCA_META_ENTRY_DEFINITIONS);
170         String[] ops = yamlFileName.split(DEL_PATTERN);
171         List<String> list = Arrays.asList(ops);
172         String result = list.stream().map(x -> x).collect(Collectors.joining(DEL_PATTERN));
173         keyOp = csar.keySet().stream().filter(k -> Pattern.compile(result).matcher(k).matches()).findAny();
174         if (!keyOp.isPresent()) {
175             log.debug(ENTRY_DEFINITIONS_ENTRY_NOT_FOUND_IN_TOSCA_METADATA_TOSCA_META_FILE_CSAR_ID, csarUUID);
176             BeEcompErrorManager.getInstance()
177                     .logInternalDataError(ENTRY_DEFINITIONS_ENTRY_NOT_FOUND_IN_TOSCA_METADATA_TOSCA_META_FILE_CSAR_ID + csarUUID,
178                             CSAR_INTERNALS_ARE_INVALID, ErrorSeverity.ERROR);
179             return Either.right(componentsUtils.getResponseFormat(ActionStatus.YAML_NOT_FOUND_IN_CSAR, csarUUID, yamlFileName));
180         }
181         log.trace("Found Entry-Definitions property in TOSCA-Metadata/TOSCA.meta, Entry-Definitions: {}, CSAR id: {}", yamlFileName, csarUUID);
182         byte[] yamlFileBytes = csar.get(yamlFileName);
183         if (yamlFileBytes == null) {
184             log.debug("Entry-Definitions {} file not found in csar, csar ID {}", yamlFileName, csarUUID);
185             BeEcompErrorManager.getInstance()
186                     .logInternalDataError(ENTRY_DEFINITIONS + yamlFileName + FILE_NOT_FOUND_IN_CSAR_WITH_ID + csarUUID, CSAR_STRUCTURE_IS_INVALID,
187                             ErrorSeverity.ERROR);
188             return Either.right(componentsUtils.getResponseFormat(ActionStatus.YAML_NOT_FOUND_IN_CSAR, csarUUID, yamlFileName));
189         }
190         String yamlFileContents = new String(yamlFileBytes);
191         return Either.left(new ImmutablePair<>(yamlFileName, yamlFileContents));
192     }
193
194     public static Either<ImmutablePair<String, String>, ResponseFormat> getArtifactsMeta(Map<String, byte[]> csar, String csarUUID,
195                                                                                          ComponentsUtils componentsUtils) {
196         if (!csar.containsKey(CsarUtils.ARTIFACTS_PATH + ARTIFACTS_METADATA_FILE)) {
197             log.debug(ENTRY_DEFINITIONS_ENTRY_NOT_FOUND_IN_TOSCA_METADATA_TOSCA_META_FILE_CSAR_ID, csarUUID);
198             BeEcompErrorManager.getInstance()
199                 .logInternalDataError(ENTRY_DEFINITIONS_ENTRY_NOT_FOUND_IN_TOSCA_METADATA_TOSCA_META_FILE_CSAR_ID + csarUUID,
200                     CSAR_INTERNALS_ARE_INVALID, ErrorSeverity.ERROR);
201             return Either.right(componentsUtils.getResponseFormat(ActionStatus.YAML_NOT_FOUND_IN_CSAR, csarUUID, ARTIFACTS_METADATA_FILE));
202         }
203         log.trace("Found Entry-Definitions property in TOSCA-Metadata/TOSCA.meta, Entry-Definitions: {}, CSAR id: {}", ARTIFACTS_METADATA_FILE,
204             csarUUID);
205         byte[] artifactsMetaBytes = csar.get(CsarUtils.ARTIFACTS_PATH + ARTIFACTS_METADATA_FILE);
206         if (artifactsMetaBytes == null) {
207             log.debug("Entry-Definitions {}{} file not found in csar, csar ID {}", CsarUtils.ARTIFACTS_PATH, ARTIFACTS_METADATA_FILE, csarUUID);
208             BeEcompErrorManager.getInstance().logInternalDataError(
209                 ENTRY_DEFINITIONS + CsarUtils.ARTIFACTS_PATH + ARTIFACTS_METADATA_FILE + FILE_NOT_FOUND_IN_CSAR_WITH_ID + csarUUID,
210                 CSAR_STRUCTURE_IS_INVALID, ErrorSeverity.ERROR);
211             return Either.right(
212                 componentsUtils.getResponseFormat(ActionStatus.YAML_NOT_FOUND_IN_CSAR, csarUUID, CsarUtils.ARTIFACTS_PATH + ARTIFACTS_METADATA_FILE));
213         }
214         String artifactsFileContents = new String(artifactsMetaBytes);
215         return Either.left(new ImmutablePair<>(CsarUtils.ARTIFACTS_PATH + ARTIFACTS_METADATA_FILE, artifactsFileContents));
216     }
217
218     public static Either<ImmutablePair<String, byte[]>, ResponseFormat> getArtifactContent(String csarUUID, Map<String, byte[]> csar,
219                                                                                            String artifactPath, String artifactName,
220                                                                                            ComponentsUtils componentsUtils) {
221         if (!csar.containsKey(artifactPath)) {
222             log.debug("Entry-Definitions entry not found in Artifacts/HEAT.meta file, csar ID {}", csarUUID);
223             BeEcompErrorManager.getInstance()
224                 .logInternalDataError(ENTRY_DEFINITIONS_ENTRY_NOT_FOUND_IN_TOSCA_METADATA_TOSCA_META_FILE_CSAR_ID + csarUUID,
225                     CSAR_INTERNALS_ARE_INVALID, ErrorSeverity.ERROR);
226             return Either
227                 .right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND_IN_CSAR, CsarUtils.ARTIFACTS_PATH + artifactName, csarUUID));
228         }
229         log.trace("Found Entry-Definitions property in Artifacts/HEAT.meta, Entry-Definitions: {}, CSAR id: {}", artifactPath, csarUUID);
230         byte[] artifactFileBytes = csar.get(artifactPath);
231         if (artifactFileBytes == null) {
232             log.debug("Entry-Definitions {}{} file not found in csar, csar ID {}", CsarUtils.ARTIFACTS_PATH, artifactName, csarUUID);
233             BeEcompErrorManager.getInstance()
234                 .logInternalDataError(ENTRY_DEFINITIONS + artifactPath + FILE_NOT_FOUND_IN_CSAR_WITH_ID + csarUUID, CSAR_STRUCTURE_IS_INVALID,
235                     ErrorSeverity.ERROR);
236             return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND_IN_CSAR, artifactPath, csarUUID));
237         }
238         return Either.left(new ImmutablePair<>(artifactName, artifactFileBytes));
239     }
240
241     private static Either<Boolean, ResponseFormat> validateTOSCAMetadataFile(Map<String, byte[]> csar, String csarUUID,
242                                                                              ComponentsUtils componentsUtils) {
243         Pattern pattern = Pattern.compile(TOSCA_METADATA_PATH_PATTERN);
244         Optional<String> keyOp = csar.keySet().stream().filter(k -> pattern.matcher(k).matches()).findAny();
245         if (!keyOp.isPresent()) {
246             log.debug(TOSCA_METADATA_TOSCA_META_FILE_IS_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_CSAR_ID, csarUUID);
247             BeEcompErrorManager.getInstance()
248                 .logInternalDataError(TOSCA_METADATA_TOSCA_META_FILE_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_WITH_ID + csarUUID,
249                     CSAR_INTERNALS_ARE_INVALID, ErrorSeverity.ERROR);
250             return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, csarUUID));
251         }
252         byte[] toscaMetaBytes = csar.get(keyOp.get());
253         String toscaMetadata = new String(toscaMetaBytes);
254         String[] splited = toscaMetadata.split(NEW_LINE_DELM);
255         if (splited == null || splited.length < TOSCA_METADATA_FIELDS.length) {
256             log.debug(TOSCA_METADATA_TOSCA_META_FILE_IS_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_CSAR_ID, csarUUID);
257             BeEcompErrorManager.getInstance()
258                 .logInternalDataError(TOSCA_METADATA_TOSCA_META_FILE_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_WITH_ID + csarUUID,
259                     CSAR_INTERNALS_ARE_INVALID, ErrorSeverity.ERROR);
260             return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, csarUUID));
261         }
262         Either<Boolean, ResponseFormat> blockStatus = validateBlock(csarUUID, splited, componentsUtils);
263         if (blockStatus.isRight()) {
264             return Either.right(blockStatus.right().value());
265         }
266         return Either.left(true);
267     }
268
269     private static Either<Boolean, ResponseFormat> validateBlock(String csarUUID, String[] splited, ComponentsUtils componentsUtils) {
270         int index = 0;
271         for (String toscaField : TOSCA_METADATA_FIELDS) {
272             Properties props = new Properties();
273             try {
274                 props.load(new ByteArrayInputStream(splited[index].getBytes()));
275             } catch (IOException e) {
276                 log.debug(TOSCA_METADATA_TOSCA_META_FILE_IS_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_CSAR_ID, csarUUID, e);
277                 BeEcompErrorManager.getInstance()
278                     .logInternalDataError(TOSCA_METADATA_TOSCA_META_FILE_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_WITH_ID + csarUUID,
279                         CSAR_INTERNALS_ARE_INVALID, ErrorSeverity.ERROR);
280                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, csarUUID));
281             }
282             if (!props.containsKey(toscaField)) {
283                 log.debug("TOSCA.meta file format is invalid: No new line after block_0 as expected in csar, csar ID {}", csarUUID);
284                 BeEcompErrorManager.getInstance()
285                     .logInternalDataError(TOSCA_METADATA_TOSCA_META_FILE_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_WITH_ID + csarUUID,
286                         CSAR_INTERNALS_ARE_INVALID, ErrorSeverity.ERROR);
287                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, csarUUID));
288             }
289             String value = props.getProperty(toscaField);
290             if (value == null || value.isEmpty()) {
291                 log.debug(TOSCA_METADATA_TOSCA_META_FILE_IS_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_CSAR_ID, csarUUID);
292                 BeEcompErrorManager.getInstance()
293                     .logInternalDataError(TOSCA_METADATA_TOSCA_META_FILE_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_WITH_ID + csarUUID,
294                         CSAR_INTERNALS_ARE_INVALID, ErrorSeverity.ERROR);
295                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, csarUUID));
296             }
297             // TOSCA-Meta-File-Version & CSAR-Version : digit.digit - format
298
299             // validation
300             if ((toscaField.equals(TOSCA_META_FILE_VERSION) || toscaField.equals(CSAR_VERSION)) && !validateTOSCAMetaProperty(value)) {
301                 log.debug("TOSCA-Metadata/TOSCA.meta file contains {} in wrong format (digit.digit), csar ID {}", toscaField, csarUUID);
302                 BeEcompErrorManager.getInstance()
303                     .logInternalDataError(TOSCA_METADATA_TOSCA_META_FILE_NOT_IN_EXPECTED_KEY_VALUE_FORM_IN_CSAR_WITH_ID + csarUUID,
304                         CSAR_INTERNALS_ARE_INVALID, ErrorSeverity.ERROR);
305                 return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, csarUUID));
306             }
307             index++;
308         }
309         return Either.left(true);
310     }
311
312     private static boolean validateTOSCAMetaProperty(String toscaProperty) {
313         Matcher floatMatcher = floatPattern.matcher(toscaProperty);
314         return floatMatcher.matches();
315     }
316
317     private static Either<Boolean, ResponseFormat> validateIsTOSCAMetadataExist(Map<String, byte[]> csar, String csarUUID,
318                                                                                 ComponentsUtils componentsUtils) {
319         if (csar == null || csar.isEmpty()) {
320             log.debug("Error when fetching csar with ID {}", csarUUID);
321             BeEcompErrorManager.getInstance().logBeDaoSystemError("Creating resource from CSAR: fetching CSAR with id " + csarUUID + " failed");
322             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID, csarUUID);
323             return Either.right(responseFormat);
324         }
325         Pattern pattern = Pattern.compile(TOSCA_METADATA_PATH_PATTERN);
326         Optional<String> keyOp = csar.keySet().stream().filter(k -> pattern.matcher(k).matches()).findAny();
327         if (!keyOp.isPresent()) {
328             log.debug("TOSCA-Metadata/TOSCA.meta file not found in csar, csar ID {}", csarUUID);
329             BeEcompErrorManager.getInstance()
330                 .logInternalDataError("TOSCA-Metadata/TOSCA.meta file not found in CSAR with id " + csarUUID, CSAR_STRUCTURE_IS_INVALID,
331                     ErrorSeverity.ERROR);
332             return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID, csarUUID));
333         }
334         byte[] toscaMetaBytes = csar.get(keyOp.get());
335         if (toscaMetaBytes == null || toscaMetaBytes.length == 0) {
336             log.debug("TOSCA-Metadata/TOSCA.meta file not found in csar, csar ID {}", csarUUID);
337             BeEcompErrorManager.getInstance()
338                 .logInternalDataError("TOSCA-Metadata/TOSCA.meta file not found in CSAR with id " + csarUUID, CSAR_STRUCTURE_IS_INVALID,
339                     ErrorSeverity.ERROR);
340             return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID, csarUUID));
341         }
342         return Either.left(Boolean.TRUE);
343     }
344
345     public static Either<String, ResponseFormat> getToscaYamlChecksum(Map<String, byte[]> csar, String csarUUID, ComponentsUtils componentsUtils) {
346         Either<ImmutablePair<String, String>, ResponseFormat> toscaYamlRes = getToscaYaml(csar, csarUUID, componentsUtils, AuditingActionEnum.GET_TOSCA_MODEL);
347         if (toscaYamlRes.isRight() || toscaYamlRes.left().value() == null || toscaYamlRes.left().value().getRight() == null) {
348             log.debug("Faild to create toscaYamlChecksum for csar, csar ID {}", csarUUID);
349             return Either.right(toscaYamlRes.right().value());
350         }
351         String newCheckSum = GeneralUtility.calculateMD5Base64EncodedByByteArray(toscaYamlRes.left().value().getRight().getBytes());
352         return Either.left(newCheckSum);
353     }
354
355     public static boolean isCsarPayloadName(String payloadName) {
356         return payloadName != null && payloadName.toLowerCase().endsWith(TOSCA_CSAR_EXTENSION);
357     }
358 }