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