diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java index a99ae03f19..eae6b94765 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/Messages.java @@ -711,6 +711,7 @@ public class Messages { public static final String ERROR_WAITING_FOR_OPERATION_TO_FINISH = "Error waiting for operation to finish"; public static final String OPERATION_OF_SERVICE_BINDING_OR_KEY_IS_IN_PROGRESS = "Operation of service binding or key is in progress"; public static final String ARCHIVE_WAS_NOT_SPLIT_TOTAL_SIZE_IN_BYTES_0 = "Archive was not split! Total size in bytes: {0}"; + public static final String SIZE_OF_MTAR_IS_AND_SIZE_OF_EXTENSION_DESCRIPTOR_ID = "Size of mtars is {0} and size of extension descriptors is {1}"; public static final String ARCHIVE_IS_SPLIT_TO_0_PARTS_TOTAL_SIZE_IN_BYTES_1_UPLOADING = "Archive was split to: {0} parts. Total size in bytes: {1}. Uploading started..."; public static final String SIZE_OF_APP_0_IS_1_BYTES = "Size of app {0} is {1} bytes"; public static final String SHOULD_UPDATE_SERVICE_KEY = "Service keys should be updated"; diff --git a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/ValidateDeployParametersStep.java b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/ValidateDeployParametersStep.java index ab6c9944ab..d295b0a71e 100644 --- a/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/ValidateDeployParametersStep.java +++ b/multiapps-controller-process/src/main/java/org/cloudfoundry/multiapps/controller/process/steps/ValidateDeployParametersStep.java @@ -1,7 +1,13 @@ package org.cloudfoundry.multiapps.controller.process.steps; -import jakarta.inject.Inject; -import jakarta.inject.Named; +import java.math.BigInteger; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; + import org.apache.commons.io.IOUtils; import org.cloudfoundry.multiapps.common.ContentException; import org.cloudfoundry.multiapps.common.SLException; @@ -19,12 +25,8 @@ import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; -import java.math.BigInteger; -import java.text.MessageFormat; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; +import jakarta.inject.Inject; +import jakarta.inject.Named; @Named("validateDeployParametersStep") @Scope(BeanDefinition.SCOPE_PROTOTYPE) @@ -57,22 +59,34 @@ protected String getStepErrorMessage(ProcessContext context) { } private void validateParameters(ProcessContext context) { - validateExtensionDescriptorFileIds(context); - validateFilesSizeLimit(context); - validateArchive(context); + List extensionDescriptors = validateExtensionDescriptorFileIds(context); + List archivePartEntries = getArchivePartEntries(context); + validateFilesSizeLimit(context, archivePartEntries, extensionDescriptors); + + if (archivePartEntries.size() == 1) { + getStepLogger().infoWithoutProgressMessage(Messages.ARCHIVE_WAS_NOT_SPLIT_TOTAL_SIZE_IN_BYTES_0, archivePartEntries.get(0) + .getSize()); + } else { + mergeArchive(context, archivePartEntries); + } } - private void validateExtensionDescriptorFileIds(ProcessContext context) { + private List validateExtensionDescriptorFileIds(ProcessContext context) { + List extensionDescriptors = new ArrayList<>(); String extensionDescriptorFileId = context.getVariable(Variables.EXT_DESCRIPTOR_FILE_ID); + if (extensionDescriptorFileId == null) { - return; + return List.of(); } String[] extensionDescriptorFileIds = extensionDescriptorFileId.split(","); for (String fileId : extensionDescriptorFileIds) { FileEntry file = findFile(context, fileId); validateDescriptorSize(file); + extensionDescriptors.add(file); } + + return extensionDescriptors; } private FileEntry findFile(ProcessContext context, String fileId) { @@ -94,27 +108,37 @@ private void validateDescriptorSize(FileEntry file) { .compareTo(BigInteger.valueOf(maxSizeLimit)) > 0) { throw new SLException(org.cloudfoundry.multiapps.mta.Messages.ERROR_SIZE_OF_FILE_EXCEEDS_CONFIGURED_MAX_SIZE_LIMIT, file.getSize() - .toString(), file.getName(), String.valueOf(maxSizeLimit.longValue())); + .toString(), + file.getName(), + String.valueOf(maxSizeLimit.longValue())); } } - private void validateFilesSizeLimit(ProcessContext context) { + private void validateFilesSizeLimit(ProcessContext context, List archivePartEntries, List extensionDescriptors) { try { - checkFileSizeOfAllFiles(context); + checkFileSizeOfAllFiles(context, archivePartEntries, extensionDescriptors); } catch (FileStorageException e) { throw new SLException(e, MessageFormat.format(Messages.ERROR_OCURRED_DURING_VALIDATION_OF_FILES_0, e.getMessage())); } } - private void checkFileSizeOfAllFiles(ProcessContext context) throws FileStorageException { + private void checkFileSizeOfAllFiles(ProcessContext context, List archivePartEntries, List extensionDescriptors) + throws FileStorageException { long maxFileSizeLimit = configuration.getMaxUploadSize(); - List fileEntries = fileService.listFilesBySpaceAndOperationId(context.getVariable(Variables.SPACE_GUID), - context.getVariable(Variables.CORRELATION_ID)); - long sizeOfAllFiles = getSizeOfAllFiles(fileEntries); - if (sizeOfAllFiles >= maxFileSizeLimit) { - deleteFiles(context, fileEntries); - throw new ContentException(Messages.SIZE_OF_ALL_OPERATIONS_FILES_0_EXCEEDS_MAX_UPLOAD_SIZE_1, sizeOfAllFiles, maxFileSizeLimit); + long sizeOfAllArchivePartEntries = getSizeOfAllFiles(archivePartEntries); + long sizeOfExtensionDescriptorsEntries = getSizeOfAllFiles(extensionDescriptors); + long sizeOfAllFileEntries = sizeOfAllArchivePartEntries + sizeOfExtensionDescriptorsEntries; + + getStepLogger().infoWithoutProgressMessage(Messages.SIZE_OF_MTAR_IS_AND_SIZE_OF_EXTENSION_DESCRIPTOR_ID, + sizeOfAllArchivePartEntries, sizeOfExtensionDescriptorsEntries); + + if (sizeOfAllFileEntries > maxFileSizeLimit) { + deleteFiles(context, archivePartEntries); + deleteFiles(context, extensionDescriptors); + throw new ContentException(Messages.SIZE_OF_ALL_OPERATIONS_FILES_0_EXCEEDS_MAX_UPLOAD_SIZE_1, + sizeOfAllFileEntries, + maxFileSizeLimit); } } @@ -126,21 +150,26 @@ private long getSizeOfAllFiles(List fileEntries) { } private void deleteFiles(ProcessContext context, List fileEntries) throws FileStorageException { - FileSweeper fileSweeper = new FileSweeper(context.getVariable(Variables.SPACE_GUID), fileService, + FileSweeper fileSweeper = new FileSweeper(context.getVariable(Variables.SPACE_GUID), + fileService, context.getVariable(Variables.CORRELATION_ID)); fileSweeper.sweep(fileEntries); } - private void validateArchive(ProcessContext context) { + private List getArchivePartEntries(ProcessContext context) { String[] archivePartIds = getArchivePartIds(context); if (archivePartIds.length == 1) { // TODO The merging of chunks should be done prior to this step FileEntry archiveFileEntry = findFile(context, archivePartIds[0]); - getStepLogger().infoWithoutProgressMessage(Messages.ARCHIVE_WAS_NOT_SPLIT_TOTAL_SIZE_IN_BYTES_0, archiveFileEntry.getSize()); - return; + return List.of(archiveFileEntry); } List archivePartEntries = getArchivePartEntries(context, archivePartIds); context.setVariable(Variables.FILE_ENTRIES, archivePartEntries); + + return archivePartEntries; + } + + private void mergeArchive(ProcessContext context, List archivePartEntries) { BigInteger archiveSize = calculateArchiveSize(archivePartEntries); resilientOperationExecutor.execute(() -> mergeArchive(context, archivePartEntries, archiveSize)); } @@ -152,9 +181,9 @@ private void mergeArchive(ProcessContext context, List archivePartEnt archivePartEntries.size(), archiveSize); FileEntry uploadedArchive = persistArchive(archiveStreamWithName, context, archiveSize); context.setVariable(Variables.APP_ARCHIVE_ID, uploadedArchive.getId()); - getStepLogger().infoWithoutProgressMessage( - MessageFormat.format(Messages.ARCHIVE_WITH_ID_0_AND_NAME_1_WAS_STORED, uploadedArchive.getId(), - archiveStreamWithName.getArchiveName())); + getStepLogger().infoWithoutProgressMessage(MessageFormat.format(Messages.ARCHIVE_WITH_ID_0_AND_NAME_1_WAS_STORED, + uploadedArchive.getId(), + archiveStreamWithName.getArchiveName())); } finally { IOUtils.closeQuietly(archiveStreamWithName.getArchiveStream()); } @@ -183,8 +212,8 @@ private MergedArchiveStreamCreator getMergedArchiveStreamCreator(List private FileEntry persistArchive(ArchiveStreamWithName archiveStreamWithName, ProcessContext context, BigInteger size) { try { - return fileStorageThreadPool.submit( - new PriorityCallable<>(PriorityFuture.Priority.HIGHEST, () -> doPersistArchive(archiveStreamWithName, context, size))) + return fileStorageThreadPool.submit(new PriorityCallable<>(PriorityFuture.Priority.HIGHEST, + () -> doPersistArchive(archiveStreamWithName, context, size))) .get(); } catch (ExecutionException | InterruptedException e) { throw new SLException(e.getMessage(), e); @@ -200,7 +229,8 @@ private FileEntry doPersistArchive(ArchiveStreamWithName archiveStreamWithName, .operationId(context.getExecution() .getProcessInstanceId()) .size(size) - .build(), archiveStreamWithName.getArchiveStream()); + .build(), + archiveStreamWithName.getArchiveStream()); } } diff --git a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/ValidateDeployParametersStepTest.java b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/ValidateDeployParametersStepTest.java index dd18a13fff..51cf648610 100644 --- a/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/ValidateDeployParametersStepTest.java +++ b/multiapps-controller-process/src/test/java/org/cloudfoundry/multiapps/controller/process/steps/ValidateDeployParametersStepTest.java @@ -135,6 +135,21 @@ private void prepareFileService(String appArchiveId) throws FileStorageException when(fileService.getFile("space-id", MERGED_ARCHIVE_NAME + ".part.2")) .thenReturn(createFileEntry(MERGED_ARCHIVE_NAME + ".part.2", MERGED_ARCHIVE_NAME + ".part.2", 1024 * 1024L)); + when(fileService.getFile("space-id", EXCEEDING_FILE_SIZE_ID + ".part.0")) + .thenReturn(createFileEntry(MERGED_ARCHIVE_NAME + ".part.0", MERGED_ARCHIVE_NAME + ".part.0", 1024 * 1024 * 1024)); + + when(fileService.getFile("space-id", EXCEEDING_FILE_SIZE_ID + ".part.1")) + .thenReturn(createFileEntry(MERGED_ARCHIVE_NAME + ".part.1", MERGED_ARCHIVE_NAME + ".part.1", 1024 * 1024 * 1024)); + + when(fileService.getFile("space-id", EXCEEDING_FILE_SIZE_ID + ".part.2")) + .thenReturn(createFileEntry(MERGED_ARCHIVE_NAME + ".part.2", MERGED_ARCHIVE_NAME + ".part.2", 1024 * 1024 * 1024)); + + when(fileService.getFile("space-id", EXCEEDING_FILE_SIZE_ID + ".part.3")) + .thenReturn(createFileEntry(MERGED_ARCHIVE_NAME + ".part.3", MERGED_ARCHIVE_NAME + ".part.3", 1024 * 1024 * 1024)); + + when(fileService.getFile("space-id", EXCEEDING_FILE_SIZE_ID + ".part.4")) + .thenReturn(createFileEntry(MERGED_ARCHIVE_NAME + ".part.4", MERGED_ARCHIVE_NAME + ".part.4", 1024 * 1024 * 1024)); + when(fileService.getFile("space-id", EXISTING_BIGGER_FILE_ID)) .thenReturn(createFileEntry(EXISTING_BIGGER_FILE_ID, "extDescriptorFile", 1024 * 1024L + 1)); when(fileService.getFile("space-id", NOT_EXISTING_FILE_ID))