2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2019 Nordix Foundation
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.vendorsoftwareproduct.impl.onboarding;
22 import static org.openecomp.sdc.common.errors.Messages.PACKAGE_EMPTY_ERROR;
23 import static org.openecomp.sdc.common.errors.Messages.PACKAGE_INVALID_ERROR;
24 import static org.openecomp.sdc.common.errors.Messages.PACKAGE_INVALID_EXTENSION;
25 import static org.openecomp.sdc.common.errors.Messages.PACKAGE_MISSING_INTERNAL_PACKAGE;
26 import static org.openecomp.sdc.common.errors.Messages.PACKAGE_PROCESS_ERROR;
27 import static org.openecomp.sdc.common.errors.Messages.PACKAGE_PROCESS_INTERNAL_PACKAGE_ERROR;
28 import static org.openecomp.sdc.vendorsoftwareproduct.security.SecurityManager.ALLOWED_CERTIFICATE_EXTENSIONS;
29 import static org.openecomp.sdc.vendorsoftwareproduct.security.SecurityManager.ALLOWED_SIGNATURE_EXTENSIONS;
31 import java.nio.ByteBuffer;
32 import java.util.HashSet;
34 import java.util.Optional;
36 import org.apache.commons.collections4.CollectionUtils;
37 import org.apache.commons.collections4.MapUtils;
38 import org.apache.commons.io.FilenameUtils;
39 import org.openecomp.core.utilities.file.FileContentHandler;
40 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
41 import org.openecomp.sdc.common.zip.exception.ZipException;
42 import org.openecomp.sdc.common.utils.CommonUtil;
43 import org.openecomp.sdc.datatypes.error.ErrorLevel;
44 import org.openecomp.sdc.datatypes.error.ErrorMessage;
45 import org.openecomp.sdc.logging.api.Logger;
46 import org.openecomp.sdc.logging.api.LoggerFactory;
47 import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardPackage;
48 import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardPackageInfo;
49 import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardSignedPackage;
51 public class OnboardingPackageProcessor {
52 private static final Logger LOGGER = LoggerFactory.getLogger(OnboardingPackageProcessor.class);
53 private static final String CSAR_EXTENSION = "csar";
54 private static final String ZIP_EXTENSION = "zip";
56 private final String packageFileName;
57 private final byte[] packageFileContent;
58 private FileContentHandler onboardPackageContentHandler;
59 private Set<ErrorMessage> errorMessageSet = new HashSet<>();
60 private OnboardPackageInfo onboardPackageInfo;
62 public OnboardingPackageProcessor(final String packageFileName, final byte[] packageFileContent) {
63 this.packageFileName = packageFileName;
64 this.packageFileContent = packageFileContent;
65 onboardPackageInfo = processPackage();
68 private OnboardPackageInfo processPackage() {
69 if (!hasValidExtension()) {
70 final String message = PACKAGE_INVALID_EXTENSION.formatMessage(packageFileName, String.join(", ", CSAR_EXTENSION, ZIP_EXTENSION));
71 reportError(ErrorLevel.ERROR, message);
75 onboardPackageContentHandler = CommonUtil.getZipContent(packageFileContent);
76 } catch (final ZipException e) {
77 final String message = PACKAGE_PROCESS_ERROR.formatMessage(packageFileName);
78 LOGGER.error(message, e);
79 reportError(ErrorLevel.ERROR, message);
82 if (isPackageEmpty()) {
83 final String message = PACKAGE_EMPTY_ERROR.formatMessage(packageFileName);
84 reportError(ErrorLevel.ERROR, message);
88 final String packageName = FilenameUtils.getBaseName(packageFileName);
89 final String packageExtension = FilenameUtils.getExtension(packageFileName);
91 if (hasSignedPackageStructure()) {
92 return processSignedPackage(packageName, packageExtension);
94 if (packageExtension.equalsIgnoreCase(CSAR_EXTENSION)) {
95 final OnboardPackage onboardPackage = new OnboardPackage(packageName, packageExtension,
96 ByteBuffer.wrap(packageFileContent), new OnboardingPackageContentHandler(onboardPackageContentHandler));
97 return new OnboardPackageInfo(onboardPackage, OnboardingTypesEnum.CSAR);
98 } else if (packageExtension.equalsIgnoreCase(ZIP_EXTENSION)) {
99 final OnboardPackage onboardPackage = new OnboardPackage(packageName, packageExtension,
100 ByteBuffer.wrap(packageFileContent), onboardPackageContentHandler);
101 return new OnboardPackageInfo(onboardPackage, OnboardingTypesEnum.ZIP);
105 reportError(ErrorLevel.ERROR, PACKAGE_INVALID_ERROR.formatMessage(packageFileName));
109 private boolean hasValidExtension() {
110 final String packageExtension = FilenameUtils.getExtension(packageFileName);
111 return packageExtension.equalsIgnoreCase(CSAR_EXTENSION) || packageExtension.equalsIgnoreCase(ZIP_EXTENSION);
114 private OnboardPackageInfo processSignedPackage(final String packageName, final String packageExtension) {
115 final String internalPackagePath = findInternalPackagePath().orElse(null);
116 if (internalPackagePath == null) {
117 reportError(ErrorLevel.ERROR, PACKAGE_MISSING_INTERNAL_PACKAGE.getErrorMessage());
120 final String signatureFilePath = findSignatureFilePath().orElse(null);
121 final String certificateFilePath = findCertificateFilePath().orElse(null);
122 final OnboardSignedPackage onboardSignedPackage =
123 new OnboardSignedPackage(packageName, packageExtension, ByteBuffer.wrap(packageFileContent),
124 onboardPackageContentHandler, signatureFilePath, internalPackagePath, certificateFilePath);
126 final String internalPackageName = FilenameUtils.getName(internalPackagePath);
127 final String internalPackageBaseName = FilenameUtils.getBaseName(internalPackagePath);
128 final String internalPackageExtension = FilenameUtils.getExtension(internalPackagePath);
129 final byte[] internalPackageContent = onboardPackageContentHandler.getFileContent(internalPackagePath);
130 final OnboardPackage onboardPackage;
132 final OnboardingPackageContentHandler fileContentHandler =
133 new OnboardingPackageContentHandler(CommonUtil.getZipContent(internalPackageContent));
134 onboardPackage = new OnboardPackage(internalPackageBaseName, internalPackageExtension,
135 internalPackageContent, fileContentHandler);
136 } catch (final ZipException e) {
137 final String message = PACKAGE_PROCESS_INTERNAL_PACKAGE_ERROR.formatMessage(internalPackageName);
138 LOGGER.error(message, e);
139 reportError(ErrorLevel.ERROR, message);
143 return new OnboardPackageInfo(onboardSignedPackage, onboardPackage, OnboardingTypesEnum.SIGNED_CSAR);
146 private void reportError(final ErrorLevel errorLevel, final String message) {
147 errorMessageSet.add(new ErrorMessage(errorLevel, message));
150 public boolean hasErrors() {
151 return !errorMessageSet.isEmpty();
154 public Set<ErrorMessage> getErrorMessageSet() {
155 return errorMessageSet;
158 private Optional<String> findInternalPackagePath() {
159 return onboardPackageContentHandler.getFileList().stream()
160 .filter(filePath -> {
161 final String extension = FilenameUtils.getExtension(filePath);
162 return CSAR_EXTENSION.equalsIgnoreCase(extension) || ZIP_EXTENSION.equalsIgnoreCase(extension);
168 private boolean isPackageEmpty() {
169 return MapUtils.isEmpty(onboardPackageContentHandler.getFiles());
172 private boolean hasSignedPackageStructure() {
173 if (MapUtils.isEmpty(onboardPackageContentHandler.getFiles()) || !CollectionUtils.isEmpty(
174 onboardPackageContentHandler.getFolderList())) {
177 final int numberOfFiles = onboardPackageContentHandler.getFileList().size();
178 if (numberOfFiles == 2) {
179 return hasOneInternalPackageFile(onboardPackageContentHandler) &&
180 hasOneSignatureFile(onboardPackageContentHandler);
183 if (numberOfFiles == 3) {
184 return hasOneInternalPackageFile(onboardPackageContentHandler) &&
185 hasOneSignatureFile(onboardPackageContentHandler) &&
186 hasOneCertificateFile(onboardPackageContentHandler);
192 private boolean hasOneInternalPackageFile(final FileContentHandler fileContentHandler) {
193 return fileContentHandler.getFileList().parallelStream()
194 .map(FilenameUtils::getExtension)
195 .map(String::toLowerCase)
196 .filter(file -> file.endsWith(CSAR_EXTENSION)).count() == 1;
199 private boolean hasOneSignatureFile(final FileContentHandler fileContentHandler) {
200 return fileContentHandler.getFileList().parallelStream()
201 .map(FilenameUtils::getExtension)
202 .map(String::toLowerCase)
203 .filter(ALLOWED_SIGNATURE_EXTENSIONS::contains).count() == 1;
206 private boolean hasOneCertificateFile(final FileContentHandler fileContentHandler) {
207 return fileContentHandler.getFileList().parallelStream()
208 .map(FilenameUtils::getExtension)
209 .map(String::toLowerCase)
210 .filter(ALLOWED_CERTIFICATE_EXTENSIONS::contains).count() == 1;
213 private Optional<String> findSignatureFilePath() {
214 final Map<String, byte[]> files = onboardPackageContentHandler.getFiles();
215 return files.keySet().stream()
216 .filter(fileName -> ALLOWED_SIGNATURE_EXTENSIONS.contains(FilenameUtils.getExtension(fileName).toLowerCase()))
220 private Optional<String> findCertificateFilePath() {
221 final Map<String, byte[]> files = onboardPackageContentHandler.getFiles();
222 return files.keySet().stream()
223 .filter(fileName -> ALLOWED_CERTIFICATE_EXTENSIONS.contains(FilenameUtils.getExtension(fileName).toLowerCase()))
227 public Optional<OnboardPackageInfo> getOnboardPackageInfo() {
228 return Optional.ofNullable(onboardPackageInfo);