diff options
Diffstat (limited to 'openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java')
2 files changed, 98 insertions, 27 deletions
diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateException.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateException.java index 1e20d1ced7..abe227c745 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateException.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateException.java @@ -19,9 +19,9 @@ */ package org.openecomp.sdcrests.vsp.rest.services; -public class OrchestrationTemplateCandidateException extends Exception { +public class OrchestrationTemplateCandidateException extends RuntimeException { - public OrchestrationTemplateCandidateException(String message, Throwable t) { - super(message, t); + public OrchestrationTemplateCandidateException(final String message) { + super(message); } } diff --git a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImpl.java b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImpl.java index cd18cf973b..10f6012a76 100644 --- a/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImpl.java +++ b/openecomp-be/api/openecomp-sdc-rest-webapp/vendor-software-products-rest/vendor-software-products-rest-services/src/main/java/org/openecomp/sdcrests/vsp/rest/services/OrchestrationTemplateCandidateImpl.java @@ -16,30 +16,52 @@ * limitations under the License. * ============LICENSE_END========================================================= * Modifications copyright (c) 2019 Nokia + * Modifications copyright (c) 2021 Nordix Foundation * ================================================================================ */ package org.openecomp.sdcrests.vsp.rest.services; +import static javax.ws.rs.core.Response.Status.EXPECTATION_FAILED; +import static javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; +import static javax.ws.rs.core.Response.Status.NOT_ACCEPTABLE; +import static javax.ws.rs.core.Response.Status.NOT_FOUND; import static org.openecomp.core.validation.errors.ErrorMessagesFormatBuilder.getErrorWithParameters; +import static org.openecomp.sdc.common.errors.Messages.ERROR_HAS_OCCURRED_WHILE_PERSISTING_THE_ARTIFACT; +import static org.openecomp.sdc.common.errors.Messages.ERROR_HAS_OCCURRED_WHILE_REDUCING_THE_ARTIFACT_SIZE; +import static org.openecomp.sdc.common.errors.Messages.EXTERNAL_CSAR_STORE_CONFIGURATION_FAILURE_MISSING_FULL_PATH; +import static org.openecomp.sdc.common.errors.Messages.NO_FILE_WAS_UPLOADED_OR_FILE_NOT_EXIST; +import static org.openecomp.sdc.common.errors.Messages.PACKAGE_PROCESS_ERROR; +import static org.openecomp.sdc.common.errors.Messages.UNEXPECTED_PROBLEM_HAPPENED_WHILE_GETTING; import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; -import javax.activation.DataHandler; +import java.util.Set; +import java.util.stream.Collectors; import javax.inject.Named; import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; import org.apache.commons.lang3.tuple.Pair; import org.apache.cxf.jaxrs.ext.multipart.Attachment; import org.openecomp.sdc.activitylog.ActivityLogManager; import org.openecomp.sdc.activitylog.ActivityLogManagerFactory; import org.openecomp.sdc.activitylog.dao.type.ActivityLogEntity; import org.openecomp.sdc.activitylog.dao.type.ActivityType; -import org.openecomp.sdc.common.errors.Messages; +import org.openecomp.sdc.be.csar.storage.ArtifactInfo; +import org.openecomp.sdc.be.csar.storage.ArtifactStorageConfig; +import org.openecomp.sdc.be.csar.storage.ArtifactStorageManager; +import org.openecomp.sdc.be.csar.storage.CsarPackageReducerConfiguration; +import org.openecomp.sdc.be.csar.storage.CsarSizeReducer; +import org.openecomp.sdc.be.csar.storage.PackageSizeReducer; +import org.openecomp.sdc.be.csar.storage.PersistentVolumeArtifactStorageConfig; +import org.openecomp.sdc.be.csar.storage.PersistentVolumeArtifactStorageManager; +import org.openecomp.sdc.be.exception.BusinessException; +import org.openecomp.sdc.common.CommonConfigurationManager; import org.openecomp.sdc.common.util.ValidationUtils; import org.openecomp.sdc.common.utils.SdcCommon; import org.openecomp.sdc.datatypes.error.ErrorLevel; @@ -76,49 +98,100 @@ import org.springframework.stereotype.Service; public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplateCandidate { private static final Logger LOGGER = LoggerFactory.getLogger(OrchestrationTemplateCandidateImpl.class); + private static final String EXTERNAL_CSAR_STORE = "externalCsarStore"; private final OrchestrationTemplateCandidateManager candidateManager; private final VendorSoftwareProductManager vendorSoftwareProductManager; private final ActivityLogManager activityLogManager; + private final ArtifactStorageManager artifactStorageManager; + private final PackageSizeReducer packageSizeReducer; public OrchestrationTemplateCandidateImpl() { this.candidateManager = OrchestrationTemplateCandidateManagerFactory.getInstance().createInterface(); this.vendorSoftwareProductManager = VspManagerFactory.getInstance().createInterface(); this.activityLogManager = ActivityLogManagerFactory.getInstance().createInterface(); + LOGGER.info("Instantiating artifactStorageManager"); + this.artifactStorageManager = new PersistentVolumeArtifactStorageManager(readArtifactStorageConfiguration()); + LOGGER.info("Instantiating packageSizeReducer"); + this.packageSizeReducer = new CsarSizeReducer(readPackageReducerConfiguration()); } // Constructor used in test to avoid mock static - public OrchestrationTemplateCandidateImpl(OrchestrationTemplateCandidateManager candidateManager, - VendorSoftwareProductManager vendorSoftwareProductManager, ActivityLogManager activityLogManager) { + public OrchestrationTemplateCandidateImpl(final OrchestrationTemplateCandidateManager candidateManager, + final VendorSoftwareProductManager vendorSoftwareProductManager, + final ActivityLogManager activityLogManager, + final ArtifactStorageManager artifactStorageManager, + final PackageSizeReducer packageSizeReducer) { this.candidateManager = candidateManager; this.vendorSoftwareProductManager = vendorSoftwareProductManager; this.activityLogManager = activityLogManager; + this.artifactStorageManager = artifactStorageManager; + this.packageSizeReducer = packageSizeReducer; + } + + private CsarPackageReducerConfiguration readPackageReducerConfiguration() { + final var commonConfigurationManager = CommonConfigurationManager.getInstance(); + final List<String> foldersToStrip = commonConfigurationManager.getConfigValue(EXTERNAL_CSAR_STORE, "foldersToStrip", new ArrayList<>()); + final int sizeLimit = commonConfigurationManager.getConfigValue(EXTERNAL_CSAR_STORE, "sizeLimit", 1000000); + LOGGER.info("Folders to strip: '{}'", String.join(", ", foldersToStrip)); + final Set<Path> foldersToStripPathSet = foldersToStrip.stream().map(Path::of).collect(Collectors.toSet()); + return new CsarPackageReducerConfiguration(foldersToStripPathSet, sizeLimit); + } + + private ArtifactStorageConfig readArtifactStorageConfiguration() { + final var commonConfigurationManager = CommonConfigurationManager.getInstance(); + final boolean isEnabled = commonConfigurationManager.getConfigValue(EXTERNAL_CSAR_STORE, "storeCsarsExternally", false); + LOGGER.info("ArtifactConfig.isEnabled: '{}'", isEnabled); + final String storagePathString = commonConfigurationManager.getConfigValue(EXTERNAL_CSAR_STORE, "fullPath", null); + LOGGER.info("ArtifactConfig.storagePath: '{}'", storagePathString); + if (isEnabled && storagePathString == null) { + throw new OrchestrationTemplateCandidateException(EXTERNAL_CSAR_STORE_CONFIGURATION_FAILURE_MISSING_FULL_PATH.getErrorMessage()); + } + final var storagePath = storagePathString == null ? null : Path.of(storagePathString); + return new PersistentVolumeArtifactStorageConfig(isEnabled, storagePath); } @Override public Response upload(final String vspId, final String versionId, final Attachment fileToUpload, final String user) { - final byte[] fileToUploadBytes = fileToUpload.getObject(byte[].class); - final DataHandler dataHandler = fileToUpload.getDataHandler(); - final String filename = ValidationUtils.sanitizeInputString(dataHandler.getName()); - final OnboardingPackageProcessor onboardingPackageProcessor = - new OnboardingPackageProcessor(filename, fileToUploadBytes, new CnfPackageValidator()); + final byte[] fileToUploadBytes; + final var filename = ValidationUtils.sanitizeInputString(fileToUpload.getDataHandler().getName()); + ArtifactInfo artifactInfo = null; + if (artifactStorageManager.isEnabled()) { + final InputStream packageInputStream; + try { + packageInputStream = fileToUpload.getDataHandler().getInputStream(); + } catch (final IOException e) { + return Response.status(INTERNAL_SERVER_ERROR).entity(buildUploadResponseWithError(new ErrorMessage(ErrorLevel.ERROR, UNEXPECTED_PROBLEM_HAPPENED_WHILE_GETTING.formatMessage(filename)))).build(); + } + try { + artifactInfo = artifactStorageManager.upload(vspId, versionId, packageInputStream); + } catch (final BusinessException e) { + return Response.status(INTERNAL_SERVER_ERROR).entity(buildUploadResponseWithError(new ErrorMessage(ErrorLevel.ERROR, ERROR_HAS_OCCURRED_WHILE_PERSISTING_THE_ARTIFACT.formatMessage(filename)))).build(); + } + try { + fileToUploadBytes = packageSizeReducer.reduce(artifactInfo.getPath()); + } catch (final BusinessException e) { + return Response.status(INTERNAL_SERVER_ERROR).entity(buildUploadResponseWithError(new ErrorMessage(ErrorLevel.ERROR, ERROR_HAS_OCCURRED_WHILE_REDUCING_THE_ARTIFACT_SIZE.formatMessage(artifactInfo.getPath())))).build(); + } + } else { + fileToUploadBytes = fileToUpload.getObject(byte[].class); + } + + final var onboardingPackageProcessor = new OnboardingPackageProcessor(filename, fileToUploadBytes, new CnfPackageValidator(), artifactInfo); final ErrorMessage[] errorMessages = onboardingPackageProcessor.getErrorMessages().toArray(new ErrorMessage[0]); if (onboardingPackageProcessor.hasErrors()) { - final UploadFileResponseDto uploadFileResponseDto = buildUploadResponseWithError( - errorMessages); - return Response.status(Status.NOT_ACCEPTABLE).entity(uploadFileResponseDto).build(); + return Response.status(NOT_ACCEPTABLE).entity(buildUploadResponseWithError(errorMessages)).build(); } - final OnboardPackageInfo onboardPackageInfo = onboardingPackageProcessor.getOnboardPackageInfo().orElse(null); + final var onboardPackageInfo = onboardingPackageProcessor.getOnboardPackageInfo().orElse(null); if (onboardPackageInfo == null) { - final UploadFileResponseDto uploadFileResponseDto = buildUploadResponseWithError( - new ErrorMessage(ErrorLevel.ERROR, Messages.PACKAGE_PROCESS_ERROR.formatMessage(filename))); - return Response.ok(uploadFileResponseDto).build(); + return Response.ok(buildUploadResponseWithError(new ErrorMessage(ErrorLevel.ERROR, PACKAGE_PROCESS_ERROR.formatMessage(filename)))).build(); } - final VspDetails vspDetails = new VspDetails(ValidationUtils.sanitizeInputString(vspId), + final var vspDetails = new VspDetails(ValidationUtils.sanitizeInputString(vspId), new Version(ValidationUtils.sanitizeInputString(versionId))); return processOnboardPackage(onboardPackageInfo, vspDetails, errorMessages); } - private Response processOnboardPackage(final OnboardPackageInfo onboardPackageInfo, final VspDetails vspDetails, final ErrorMessage... errorMessages) { + private Response processOnboardPackage(final OnboardPackageInfo onboardPackageInfo, final VspDetails vspDetails, + final ErrorMessage... errorMessages) { final UploadFileResponse uploadFileResponse = candidateManager.upload(vspDetails, onboardPackageInfo); final UploadFileResponseDto uploadFileResponseDto = new MapUploadFileResponseToUploadFileResponseDto() .applyMapping(uploadFileResponse, UploadFileResponseDto.class); @@ -151,10 +224,9 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate } else { zipFile = vendorSoftwareProductManager.get(vspId, new Version((versionId))); if (!zipFile.isPresent()) { - ErrorMessage errorMessage = new ErrorMessage(ErrorLevel.ERROR, - getErrorWithParameters(Messages.NO_FILE_WAS_UPLOADED_OR_FILE_NOT_EXIST.getErrorMessage(), "")); + ErrorMessage errorMessage = new ErrorMessage(ErrorLevel.ERROR, getErrorWithParameters(NO_FILE_WAS_UPLOADED_OR_FILE_NOT_EXIST.getErrorMessage(), "")); LOGGER.error(errorMessage.getMessage()); - return Response.status(Response.Status.NOT_FOUND).build(); + return Response.status(NOT_FOUND).build(); } fileName = "Processed." + zipFile.get().getLeft(); } @@ -183,8 +255,7 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate FilesDataStructure fileDataStructure = copyFilesDataStructureDtoToFilesDataStructure(fileDataStructureDto); ValidationResponse response = candidateManager.updateFilesDataStructure(vspId, new Version(versionId), fileDataStructure); if (!response.isValid()) { - return Response.status(Response.Status.EXPECTATION_FAILED) - .entity(new MapValidationResponseToDto().applyMapping(response, ValidationResponseDto.class)).build(); + return Response.status(EXPECTATION_FAILED).entity(new MapValidationResponseToDto().applyMapping(response, ValidationResponseDto.class)).build(); } return Response.ok(fileDataStructureDto).build(); } |