diff options
author | andre.schmid <andre.schmid@est.tech> | 2021-12-15 19:44:06 +0000 |
---|---|---|
committer | Michael Morris <michael.morris@est.tech> | 2022-01-21 13:25:16 +0000 |
commit | 049d078d8abbe637b213a2f14c2192379208c168 (patch) | |
tree | 3fb61e7fe7a95684499329cfa120c82de0c533b5 /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 | |
parent | b3761a858f0ec676dd0236101b29f8948d5d6a2e (diff) |
Onboarding upload control
Brings the initial structure to control asynchronously a VSP package
upload during the onboarding.
Instead of blocking the UI, the upload and processing status will be
controlled by the backend, so the frontend can query it and control the
behaviour of the UI.
Updates the upload endpoint to obtain/verify an upload lock, and creates
a second endpoint to check for the upload status.
Change-Id: If1c43fb4f0b11e1d8a5627578bafc75f266393c2
Issue-ID: SDC-3826, SDC-3827
Signed-off-by: andre.schmid <andre.schmid@est.tech>
Diffstat (limited to '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')
1 files changed, 85 insertions, 59 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/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 e8ee6b3c4b..1477ce1414 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 @@ -22,7 +22,6 @@ 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; @@ -59,6 +58,7 @@ import org.openecomp.sdc.be.csar.storage.ArtifactStorageConfig; import org.openecomp.sdc.be.csar.storage.ArtifactStorageManager; import org.openecomp.sdc.be.csar.storage.PackageSizeReducer; import org.openecomp.sdc.be.csar.storage.StorageFactory; +import org.openecomp.sdc.be.csar.storage.exception.ArtifactStorageException; import org.openecomp.sdc.common.util.ValidationUtils; import org.openecomp.sdc.common.utils.SdcCommon; import org.openecomp.sdc.datatypes.error.ErrorLevel; @@ -70,6 +70,7 @@ import org.openecomp.sdc.vendorsoftwareproduct.OrchestrationTemplateCandidateMan import org.openecomp.sdc.vendorsoftwareproduct.VendorSoftwareProductManager; import org.openecomp.sdc.vendorsoftwareproduct.VspManagerFactory; import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspDetails; +import org.openecomp.sdc.vendorsoftwareproduct.dao.type.VspUploadStatus; import org.openecomp.sdc.vendorsoftwareproduct.impl.onboarding.OnboardingPackageProcessor; import org.openecomp.sdc.vendorsoftwareproduct.impl.onboarding.validation.CnfPackageValidator; import org.openecomp.sdc.vendorsoftwareproduct.types.OnboardPackageInfo; @@ -82,10 +83,12 @@ import org.openecomp.sdcrests.vendorsoftwareproducts.types.FileDataStructureDto; import org.openecomp.sdcrests.vendorsoftwareproducts.types.OrchestrationTemplateActionResponseDto; import org.openecomp.sdcrests.vendorsoftwareproducts.types.UploadFileResponseDto; import org.openecomp.sdcrests.vendorsoftwareproducts.types.ValidationResponseDto; +import org.openecomp.sdcrests.vendorsoftwareproducts.types.VspUploadStatusDto; import org.openecomp.sdcrests.vsp.rest.OrchestrationTemplateCandidate; import org.openecomp.sdcrests.vsp.rest.mapping.MapFilesDataStructureToDto; import org.openecomp.sdcrests.vsp.rest.mapping.MapUploadFileResponseToUploadFileResponseDto; import org.openecomp.sdcrests.vsp.rest.mapping.MapValidationResponseToDto; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; @@ -100,8 +103,10 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate private final ActivityLogManager activityLogManager; private final ArtifactStorageManager artifactStorageManager; private final PackageSizeReducer packageSizeReducer; + private final OrchestrationTemplateCandidateUploadManager orchestrationTemplateCandidateUploadManager; - public OrchestrationTemplateCandidateImpl() { + @Autowired + public OrchestrationTemplateCandidateImpl(final OrchestrationTemplateCandidateUploadManager orchestrationTemplateCandidateUploadManager) { this.candidateManager = OrchestrationTemplateCandidateManagerFactory.getInstance().createInterface(); this.vendorSoftwareProductManager = VspManagerFactory.getInstance().createInterface(); this.activityLogManager = ActivityLogManagerFactory.getInstance().createInterface(); @@ -110,6 +115,7 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate this.artifactStorageManager = storageFactory.createArtifactStorageManager(); LOGGER.info("Instantiating packageSizeReducer"); this.packageSizeReducer = storageFactory.createPackageSizeReducer().orElse(null); + this.orchestrationTemplateCandidateUploadManager = orchestrationTemplateCandidateUploadManager; } // Constructor used in test to avoid mock static @@ -117,81 +123,101 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate final VendorSoftwareProductManager vendorSoftwareProductManager, final ActivityLogManager activityLogManager, final ArtifactStorageManager artifactStorageManager, - final PackageSizeReducer packageSizeReducer) { + final PackageSizeReducer packageSizeReducer, + final OrchestrationTemplateCandidateUploadManager orchestrationTemplateCandidateUploadManager) { this.candidateManager = candidateManager; this.vendorSoftwareProductManager = vendorSoftwareProductManager; this.activityLogManager = activityLogManager; this.artifactStorageManager = artifactStorageManager; this.packageSizeReducer = packageSizeReducer; + this.orchestrationTemplateCandidateUploadManager = orchestrationTemplateCandidateUploadManager; } @Override public Response upload(String vspId, String versionId, final Attachment fileToUpload, final String user) { vspId = ValidationUtils.sanitizeInputString(vspId); versionId = ValidationUtils.sanitizeInputString(versionId); - final byte[] fileToUploadBytes; - final DataHandler dataHandler = fileToUpload.getDataHandler(); - final var filename = ValidationUtils.sanitizeInputString(dataHandler.getName()); - ArtifactInfo artifactInfo = null; - if (artifactStorageManager.isEnabled()) { - final Path tempArtifactPath; - try { - final ArtifactStorageConfig storageConfiguration = artifactStorageManager.getStorageConfiguration(); + final Response response; + VspUploadStatusDto vspUploadStatus = null; + try { + vspUploadStatus = orchestrationTemplateCandidateUploadManager.putUploadInProgress(vspId, versionId, user); + final byte[] fileToUploadBytes; + final DataHandler dataHandler = fileToUpload.getDataHandler(); + final var filename = ValidationUtils.sanitizeInputString(dataHandler.getName()); + ArtifactInfo artifactInfo = null; + if (artifactStorageManager.isEnabled()) { + artifactInfo = handleArtifactStorage(vspId, versionId, filename, dataHandler); + fileToUploadBytes = artifactInfo.getBytes(); + } else { + fileToUploadBytes = fileToUpload.getObject(byte[].class); + } - final Path folder = Path.of(storageConfiguration.getTempPath()).resolve(vspId).resolve(versionId); - tempArtifactPath = folder.resolve(UUID.randomUUID().toString()); - Files.createDirectories(folder); - try (final InputStream packageInputStream = dataHandler.getInputStream(); - final var fileOutputStream = new FileOutputStream(tempArtifactPath.toFile())) { - packageInputStream.transferTo(fileOutputStream); - } - } catch (final Exception e) { - return Response.status(INTERNAL_SERVER_ERROR).entity(buildUploadResponseWithError( - new ErrorMessage(ErrorLevel.ERROR, UNEXPECTED_PROBLEM_HAPPENED_WHILE_GETTING.formatMessage(filename)))).build(); + final var onboardingPackageProcessor = + new OnboardingPackageProcessor(filename, fileToUploadBytes, new CnfPackageValidator(), artifactInfo); + final ErrorMessage[] errorMessages = onboardingPackageProcessor.getErrorMessages().toArray(new ErrorMessage[0]); + if (onboardingPackageProcessor.hasErrors()) { + return Response.status(NOT_ACCEPTABLE).entity(buildUploadResponseWithError(errorMessages)).build(); } - try (final InputStream inputStream = Files.newInputStream(tempArtifactPath)) { - artifactInfo = artifactStorageManager.upload(vspId, versionId, inputStream); - } catch (final Exception e) { - LOGGER.error("Package Size Reducer not configured", e); - return Response.status(INTERNAL_SERVER_ERROR).entity(buildUploadResponseWithError( - new ErrorMessage(ErrorLevel.ERROR, ERROR_HAS_OCCURRED_WHILE_PERSISTING_THE_ARTIFACT.formatMessage(filename)))).build(); + final var onboardPackageInfo = onboardingPackageProcessor.getOnboardPackageInfo().orElse(null); + if (onboardPackageInfo == null) { + final UploadFileResponseDto uploadFileResponseDto = buildUploadResponseWithError( + new ErrorMessage(ErrorLevel.ERROR, PACKAGE_PROCESS_ERROR.formatMessage(filename))); + return Response.ok(uploadFileResponseDto).build(); } - try { - fileToUploadBytes = packageSizeReducer.reduce(tempArtifactPath); - Files.delete(tempArtifactPath); - } catch (final Exception e) { - LOGGER.error("Package Size Reducer not configured", e); - return Response.status(INTERNAL_SERVER_ERROR).entity(buildUploadResponseWithError( - new ErrorMessage(ErrorLevel.ERROR, - ERROR_HAS_OCCURRED_WHILE_REDUCING_THE_ARTIFACT_SIZE.formatMessage(tempArtifactPath.toString())))).build(); + final var version = new Version(versionId); + final var vspDetails = vendorSoftwareProductManager.getVsp(vspId, version); + response = processOnboardPackage(onboardPackageInfo, vspDetails, errorMessages); + final UploadFileResponseDto entity = (UploadFileResponseDto) response.getEntity(); + if (artifactStorageManager.isEnabled()) { + if (!entity.getErrors().isEmpty()) { + artifactStorageManager.delete(artifactInfo); + } else { + artifactStorageManager.put(vspId, versionId + ".reduced", new ByteArrayInputStream(fileToUploadBytes)); + } } - } else { - fileToUploadBytes = fileToUpload.getObject(byte[].class); + orchestrationTemplateCandidateUploadManager + .putUploadAsFinished(vspId, versionId, vspUploadStatus.getLockId(), VspUploadStatus.SUCCESS, user); + } catch (final Exception ex) { + if (vspUploadStatus != null) { + orchestrationTemplateCandidateUploadManager + .putUploadAsFinished(vspId, versionId, vspUploadStatus.getLockId(), VspUploadStatus.ERROR, user); + } + throw ex; } + return response; + } + + private ArtifactInfo handleArtifactStorage(final String vspId, final String versionId, final String filename, + final DataHandler artifactDataHandler) { + final Path tempArtifactPath; + try { + final ArtifactStorageConfig storageConfiguration = artifactStorageManager.getStorageConfiguration(); - final var onboardingPackageProcessor = new OnboardingPackageProcessor(filename, fileToUploadBytes, new CnfPackageValidator(), artifactInfo); - final ErrorMessage[] errorMessages = onboardingPackageProcessor.getErrorMessages().toArray(new ErrorMessage[0]); - if (onboardingPackageProcessor.hasErrors()) { - return Response.status(NOT_ACCEPTABLE).entity(buildUploadResponseWithError(errorMessages)).build(); + final Path folder = Path.of(storageConfiguration.getTempPath()).resolve(vspId).resolve(versionId); + tempArtifactPath = folder.resolve(UUID.randomUUID().toString()); + Files.createDirectories(folder); + try (final InputStream packageInputStream = artifactDataHandler.getInputStream(); + final var fileOutputStream = new FileOutputStream(tempArtifactPath.toFile())) { + packageInputStream.transferTo(fileOutputStream); + } + } catch (final Exception e) { + throw new ArtifactStorageException(UNEXPECTED_PROBLEM_HAPPENED_WHILE_GETTING.formatMessage(filename)); } - final var onboardPackageInfo = onboardingPackageProcessor.getOnboardPackageInfo().orElse(null); - if (onboardPackageInfo == null) { - final UploadFileResponseDto uploadFileResponseDto = buildUploadResponseWithError( - new ErrorMessage(ErrorLevel.ERROR, PACKAGE_PROCESS_ERROR.formatMessage(filename))); - return Response.ok(uploadFileResponseDto).build(); + final ArtifactInfo artifactInfo; + try (final InputStream inputStream = Files.newInputStream(tempArtifactPath)) { + artifactInfo = artifactStorageManager.upload(vspId, versionId, inputStream); + } catch (final Exception e) { + LOGGER.error("Package Size Reducer not configured", e); + throw new ArtifactStorageException(ERROR_HAS_OCCURRED_WHILE_PERSISTING_THE_ARTIFACT.formatMessage(filename)); } - final var version = new Version(versionId); - final var vspDetails = vendorSoftwareProductManager.getVsp(vspId, version); - final Response response = processOnboardPackage(onboardPackageInfo, vspDetails, errorMessages); - final UploadFileResponseDto entity = (UploadFileResponseDto) response.getEntity(); - if (artifactStorageManager.isEnabled()) { - if (!entity.getErrors().isEmpty()) { - artifactStorageManager.delete(artifactInfo); - } else { - artifactStorageManager.put(vspId, versionId + ".reduced", new ByteArrayInputStream(fileToUploadBytes)); - } + try { + artifactInfo.setBytes(packageSizeReducer.reduce(tempArtifactPath)); + Files.delete(tempArtifactPath); + } catch (final Exception e) { + LOGGER.error("Package Size Reducer not configured", e); + throw new ArtifactStorageException(ERROR_HAS_OCCURRED_WHILE_REDUCING_THE_ARTIFACT_SIZE.formatMessage(filename)); } - return response; + return artifactInfo; } private Response processOnboardPackage(final OnboardPackageInfo onboardPackageInfo, final VspDetails vspDetails, @@ -227,7 +253,7 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate fileName = "Candidate." + zipFile.get().getLeft(); } else { zipFile = vendorSoftwareProductManager.get(vspId, new Version((versionId))); - if (!zipFile.isPresent()) { + if (zipFile.isEmpty()) { ErrorMessage errorMessage = new ErrorMessage(ErrorLevel.ERROR, getErrorWithParameters(NO_FILE_WAS_UPLOADED_OR_FILE_NOT_EXIST.getErrorMessage(), "")); LOGGER.error(errorMessage.getMessage()); @@ -270,7 +296,7 @@ public class OrchestrationTemplateCandidateImpl implements OrchestrationTemplate @Override public Response getFilesDataStructure(String vspId, String versionId, String user) { Optional<FilesDataStructure> filesDataStructure = candidateManager.getFilesDataStructure(vspId, new Version(versionId)); - if (!filesDataStructure.isPresent()) { + if (filesDataStructure.isEmpty()) { filesDataStructure = vendorSoftwareProductManager.getOrchestrationTemplateStructure(vspId, new Version(versionId)); } FileDataStructureDto fileDataStructureDto = filesDataStructure |