diff --git a/src/main/java/org/radarbase/appserver/exception/FileStorageException.java b/src/main/java/org/radarbase/appserver/exception/FileStorageException.java new file mode 100644 index 00000000..b7c98145 --- /dev/null +++ b/src/main/java/org/radarbase/appserver/exception/FileStorageException.java @@ -0,0 +1,13 @@ +package org.radarbase.appserver.exception; + +public class FileStorageException extends RuntimeException { + private static final long serialVersionUID = -793674245766939L; + + public FileStorageException(String message) { + super(message); + } + + public FileStorageException(String message, Object object) { + super(message + " " + object.toString()); + } +} diff --git a/src/main/java/org/radarbase/appserver/exception/InvalidFileDetailsException.java b/src/main/java/org/radarbase/appserver/exception/InvalidFileDetailsException.java new file mode 100644 index 00000000..f969facc --- /dev/null +++ b/src/main/java/org/radarbase/appserver/exception/InvalidFileDetailsException.java @@ -0,0 +1,13 @@ +package org.radarbase.appserver.exception; + +public class InvalidFileDetailsException extends IllegalArgumentException { + private static final long serialVersionUID = -793674245766939L; + + public InvalidFileDetailsException(String message) { + super(message); + } + + public InvalidFileDetailsException(String message, Object object) { + super(message + " " + object.toString()); + } +} diff --git a/src/main/java/org/radarbase/appserver/exception/InvalidPathDetailsException.java b/src/main/java/org/radarbase/appserver/exception/InvalidPathDetailsException.java new file mode 100644 index 00000000..49be4c0d --- /dev/null +++ b/src/main/java/org/radarbase/appserver/exception/InvalidPathDetailsException.java @@ -0,0 +1,13 @@ +package org.radarbase.appserver.exception; + +public class InvalidPathDetailsException extends IllegalArgumentException { + private static final long serialVersionUID = -793674245766939L; + + public InvalidPathDetailsException(String message) { + super(message); + } + + public InvalidPathDetailsException(String message, Object object) { + super(message + " " + object.toString()); + } +} diff --git a/src/main/java/org/radarbase/appserver/exception/handler/ResponseEntityExceptionHandler.java b/src/main/java/org/radarbase/appserver/exception/handler/ResponseEntityExceptionHandler.java index d111119b..5a7ef43d 100644 --- a/src/main/java/org/radarbase/appserver/exception/handler/ResponseEntityExceptionHandler.java +++ b/src/main/java/org/radarbase/appserver/exception/handler/ResponseEntityExceptionHandler.java @@ -64,6 +64,21 @@ public final ResponseEntity handleInvalidUserDetailsException(Exce return handleEntityWithCause(ex, request); } + @ExceptionHandler(InvalidFileDetailsException.class) + public final ResponseEntity handleInvalidFileDetailsException(Exception ex, WebRequest request) { + return handleEntityWithCause(ex, request); + } + + @ExceptionHandler(InvalidPathDetailsException.class) + public final ResponseEntity handleInvalidPathDetailsException(Exception ex, WebRequest request) { + return handleEntityWithCause(ex, request); + } + + @ExceptionHandler(FileStorageException.class) + public final ResponseEntity handleFileStorageException(Exception ex, WebRequest request) { + return handleEntityWithCause(ex, request); + } + public ResponseEntity handleEntityWithCause(Exception ex, WebRequest request) { String cause = ex.getCause() != null ? ex.getCause().getMessage() : null; HttpStatus status = ex.getClass().getAnnotation(ResponseStatus.class).value(); diff --git a/src/main/java/org/radarbase/appserver/service/storage/S3StorageService.java b/src/main/java/org/radarbase/appserver/service/storage/S3StorageService.java index c9aaec0c..24db2b24 100644 --- a/src/main/java/org/radarbase/appserver/service/storage/S3StorageService.java +++ b/src/main/java/org/radarbase/appserver/service/storage/S3StorageService.java @@ -21,6 +21,9 @@ import io.minio.PutObjectArgs; import lombok.extern.slf4j.Slf4j; import org.radarbase.appserver.config.S3StorageProperties; +import org.radarbase.appserver.exception.FileStorageException; +import org.radarbase.appserver.exception.InvalidFileDetailsException; +import org.radarbase.appserver.exception.InvalidPathDetailsException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Service; @@ -40,31 +43,37 @@ public class S3StorageService implements StorageService { private transient MinioClientInitializer bucketClient; public String store(MultipartFile file, String projectId, String subjectId, String topicId) { - Assert.notNull(file, "File must not be null"); - Assert.notEmpty(new String[]{projectId, subjectId, topicId}, "Project, subject and topic IDs must not be empty"); + if ( + file == null || projectId == null || subjectId == null || topicId == null + || file.isEmpty()|| projectId.isEmpty() || subjectId.isEmpty() || topicId.isEmpty()) { + throw new InvalidFileDetailsException("File, project, subject and topic IDs must not be empty"); + } - StoragePath filePath = StoragePath.builder() - .prefix(s3StorageProperties.getPath().getPrefix()) - .projectId(projectId) - .subjectId(subjectId) - .topicId(topicId) - .collectPerDay(s3StorageProperties.getPath().isCollectPerDay()) - .filename(file.getOriginalFilename()) - .build(); + try { + StoragePath filePath = StoragePath.builder() + .prefix(s3StorageProperties.getPath().getPrefix()) + .projectId(projectId) + .subjectId(subjectId) + .topicId(topicId) + .collectPerDay(s3StorageProperties.getPath().isCollectPerDay()) + .filename(file.getOriginalFilename()) + .build(); - log.debug("Attempt storing file at path: {}", filePath.getFullPath()); + log.debug("Attempt storing file at path: {}", filePath.getFullPath()); - try { bucketClient.getClient().putObject(PutObjectArgs .builder() .bucket(bucketClient.getBucketName()) .object(filePath.getFullPath()) .stream(file.getInputStream(), file.getSize(), -1) .build()); + + return filePath.getFullPath(); + } catch (IllegalArgumentException e) { + throw new InvalidPathDetailsException("There is a problem resolving the path on the object storage", e); } catch (Exception e) { - throw new RuntimeException("Could not store file", e); + throw new FileStorageException("There is a problem storing the file on the object storage", e); } - return filePath.getFullPath(); } }