Add a CSAR validator for model ETSI SOL001 2.5.1
[sdc.git] / openecomp-be / backend / openecomp-sdc-vendor-software-product-manager / src / main / java / org / openecomp / sdc / vendorsoftwareproduct / impl / orchestration / OrchestrationTemplateCSARHandler.java
1 /*
2  * Copyright (c) 2018 AT&T Intellectual Property.
3
4  * Modifications Copyright (c) 2018 Verizon Property.
5  * Modifications Copyright (c) 2019 Nordix Foundation.
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  *     http://www.apache.org/licenses/LICENSE-2.0
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
15  * See the License for the specific language governing permissions and
16
17  * limitations under the License.
18
19  */
20 package org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration;
21
22 import static org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder.getErrorWithParameters;
23
24 import java.io.IOException;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Optional;
30 import org.apache.commons.collections4.CollectionUtils;
31 import org.openecomp.core.utilities.file.FileContentHandler;
32 import org.openecomp.core.utilities.orchestration.OnboardingTypesEnum;
33 import org.openecomp.sdc.be.csar.storage.ArtifactInfo;
34 import org.openecomp.sdc.common.errors.CoreException;
35 import org.openecomp.sdc.common.errors.Messages;
36 import org.openecomp.sdc.common.utils.SdcCommon;
37 import org.openecomp.sdc.datatypes.error.ErrorLevel;
38 import org.openecomp.sdc.datatypes.error.ErrorMessage;
39 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.OrchestrationTemplateCandidateData;
40 import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails;
41 import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.CsarSecurityValidator;
42 import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.Validator;
43 import org.openecomp.sdc.vendorsoftwareproduct.impl.orchestration.csar.validation.ValidatorFactory;
44 import org.openecomp.sdc.vendorsoftwareproduct.security.SecurityManagerException;
45 import org.openecomp.sdc.vendorsoftwareproduct.services.filedatastructuremodule.CandidateService;
46 import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardPackage;
47 import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardPackageInfo;
48 import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardSignedPackage;
49 import org.openecomp.sdc.vendorsoftwareproduct.types.UploadFileResponse;
50
51 public class OrchestrationTemplateCSARHandler extends BaseOrchestrationTemplateHandler {
52
53     private final ValidatorFactory validatorFactory;
54
55     public OrchestrationTemplateCSARHandler() {
56         this.validatorFactory = new ValidatorFactory();
57     }
58
59     @Override
60     public UploadFileResponse validate(final VspDetails vspDetails, final OnboardPackageInfo onboardPackageInfo) {
61         final UploadFileResponse uploadFileResponse = new UploadFileResponse();
62         if (onboardPackageInfo.getPackageType() == OnboardingTypesEnum.SIGNED_CSAR) {
63             final OnboardSignedPackage originalOnboardPackage = (OnboardSignedPackage) onboardPackageInfo.getOriginalOnboardPackage();
64             final ArtifactInfo artifactInfo = onboardPackageInfo.getArtifactInfo();
65             validatePackageSecurity(originalOnboardPackage, artifactInfo).ifPresent(packageSignatureResponse -> {
66                 if (packageSignatureResponse.hasErrors()) {
67                     uploadFileResponse.addStructureErrors(packageSignatureResponse.getErrors());
68                 }
69             });
70             if (uploadFileResponse.hasErrors()) {
71                 return uploadFileResponse;
72             }
73         }
74         final OnboardPackage onboardPackage = onboardPackageInfo.getOnboardPackage();
75         final FileContentHandler fileContentHandler = onboardPackage.getFileContentHandler();
76         try {
77             final List<String> modelIdList = vspDetails.getModelIdList();
78             if (CollectionUtils.isEmpty(modelIdList)) {
79                 final Map<String, List<ErrorMessage>> errorResponseMap = validateSdcModel(fileContentHandler);
80                 if (!errorResponseMap.isEmpty()) {
81                     uploadFileResponse.addStructureErrors(errorResponseMap);
82                 }
83             } else {
84                 final Map<String, List<ErrorMessage>> errorResponseMap = validateModels(modelIdList, fileContentHandler);
85                 if (!errorResponseMap.isEmpty()) {
86                     uploadFileResponse.addStructureErrors(errorResponseMap);
87                 }
88             }
89         } catch (final IOException exception) {
90             logger.error(exception.getMessage(), exception);
91             uploadFileResponse
92                 .addStructureError(SdcCommon.UPLOAD_FILE, new ErrorMessage(ErrorLevel.ERROR, Messages.INVALID_CSAR_FILE.getErrorMessage()));
93         } catch (final CoreException coreException) {
94             logger.error(coreException.getMessage(), coreException);
95             uploadFileResponse.addStructureError(SdcCommon.UPLOAD_FILE, new ErrorMessage(ErrorLevel.ERROR, coreException.getMessage()));
96         } catch (final Exception ex) {
97             logger.error(ex.getMessage(), ex);
98         }
99         return uploadFileResponse;
100     }
101
102     private Map<String, List<ErrorMessage>> validateModels(final List<String> modelIdList, final FileContentHandler fileContentHandler) {
103         final Map<String, List<ErrorMessage>> errorResponseMap = new HashMap<>();
104         modelIdList.forEach(model -> {
105             final List<Validator> validators = validatorFactory.getValidators(model);
106             validators.forEach(validator -> {
107                 final var validationResult = validator.validate(fileContentHandler);
108                 if (CollectionUtils.isNotEmpty(validationResult.getErrors())) {
109                     if (errorResponseMap.containsKey(SdcCommon.UPLOAD_FILE)) {
110                         errorResponseMap.get(SdcCommon.UPLOAD_FILE).addAll(validationResult.getErrors());
111                     } else {
112                         errorResponseMap.put(SdcCommon.UPLOAD_FILE, validationResult.getErrors());
113                     }
114                 }
115             });
116         });
117         return errorResponseMap;
118     }
119
120     private Map<String, List<ErrorMessage>> validateSdcModel(final FileContentHandler fileContentHandler) throws IOException {
121         final var validator = validatorFactory.getValidator(fileContentHandler);
122         final var validationResult = validator.validate(fileContentHandler);
123         if (CollectionUtils.isNotEmpty(validationResult.getErrors())) {
124             return Map.of(SdcCommon.UPLOAD_FILE, validationResult.getErrors());
125         }
126
127         return Collections.emptyMap();
128     }
129
130     private Optional<UploadFileResponse> validatePackageSecurity(final OnboardSignedPackage signedPackage, final ArtifactInfo artifactInfo) {
131         final UploadFileResponse uploadFileResponseDto = new UploadFileResponse();
132         try {
133             final CsarSecurityValidator csarSecurityValidator = new CsarSecurityValidator();
134             if (!csarSecurityValidator.verifyPackageSignature(signedPackage, artifactInfo)) {
135                 final ErrorMessage errorMessage = new ErrorMessage(ErrorLevel.ERROR, Messages.FAILED_TO_VERIFY_SIGNATURE.getErrorMessage());
136                 logger.error(errorMessage.getMessage());
137                 uploadFileResponseDto.addStructureError(SdcCommon.UPLOAD_FILE, errorMessage);
138                 return Optional.of(uploadFileResponseDto);
139             }
140         } catch (final SecurityManagerException e) {
141             final ErrorMessage errorMessage = new ErrorMessage(ErrorLevel.ERROR, e.getMessage());
142             logger.error("Could not validate package signature {}", signedPackage.getFilename(), e);
143             uploadFileResponseDto.addStructureError(SdcCommon.UPLOAD_FILE, errorMessage);
144             return Optional.of(uploadFileResponseDto);
145         }
146         return Optional.empty();
147     }
148
149     @Override
150     protected UploadFileResponse updateCandidateData(final VspDetails vspDetails, final OnboardPackageInfo onboardPackageInfo,
151                                                      final CandidateService candidateService) {
152         final UploadFileResponse uploadFileResponse = new UploadFileResponse();
153         final OnboardPackage csarPackage = onboardPackageInfo.getOnboardPackage();
154         final OnboardPackage originalOnboardPackage = onboardPackageInfo.getOriginalOnboardPackage();
155         try {
156             final var candidateData = new OrchestrationTemplateCandidateData(csarPackage.getFileContent(), csarPackage.getFileExtension(),
157                 csarPackage.getFilename(), originalOnboardPackage.getFilename(), originalOnboardPackage.getFileExtension(),
158                 originalOnboardPackage.getFileContent(), onboardPackageInfo.getArtifactInfo());
159             candidateService.updateCandidateUploadData(vspDetails.getId(), vspDetails.getVersion(), candidateData);
160         } catch (final Exception exception) {
161             logger.error(getErrorWithParameters(Messages.FILE_LOAD_CONTENT_ERROR.getErrorMessage(), getHandlerType().toString()), exception);
162             uploadFileResponse.addStructureError(SdcCommon.UPLOAD_FILE, new ErrorMessage(ErrorLevel.ERROR, exception.getMessage()));
163         }
164         return uploadFileResponse;
165     }
166
167     @Override
168     protected OnboardingTypesEnum getHandlerType() {
169         return OnboardingTypesEnum.CSAR;
170     }
171 }