MinioStorageService.java
package api.services.storage;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import api.exceptions.StorageException;
import io.minio.BucketExistsArgs;
import io.minio.GetObjectArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
import io.minio.errors.ErrorResponseException;
import io.minio.errors.InsufficientDataException;
import io.minio.errors.InternalException;
import io.minio.errors.InvalidResponseException;
import io.minio.errors.ServerException;
import io.minio.errors.XmlParserException;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
/**
* {@link MinioStorageService}.
*/
@Slf4j
@Service
@Profile("prod")
public class MinioStorageService implements SimpleStorageService {
@Autowired
private MinioClient minioClient;
@Value("${s3.bucket.name:main}")
private String defaultBucket;
/**
* Initialize the Minio storage system.
*/
@PostConstruct
public void init() {
createBucket(defaultBucket);
}
@Override
public void uploadObject(String key, InputStream stream, long size) {
uploadObject(defaultBucket, key, stream, size);
}
private void uploadObject(String bucket, String key, InputStream stream, long size) {
validateKey(key);
if (size < 0) {
throw new IllegalArgumentException("Size must not be negative.");
}
try {
minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucket)
.object(key)
.stream(stream, size, -1)
.build()
);
} catch (InvalidKeyException | ErrorResponseException | InsufficientDataException | InternalException
| InvalidResponseException | NoSuchAlgorithmException | ServerException | XmlParserException
| IllegalArgumentException | IOException e) {
throw new StorageException(e);
}
log.info("S3 object uploaded: " + bucket + "/" + key);
}
@Override
public InputStream downloadObject(String key) {
return downloadObject(defaultBucket, key);
}
private InputStream downloadObject(String bucket, String key) {
validateKey(key);
try {
return minioClient.getObject(GetObjectArgs.builder()
.bucket(bucket)
.object(key)
.build()
);
} catch (InvalidKeyException | ErrorResponseException | InsufficientDataException | InternalException
| InvalidResponseException | NoSuchAlgorithmException | ServerException | XmlParserException
| IllegalArgumentException | IOException e) {
throw new StorageException(e);
}
}
@Override
public void deleteObject(String key) {
deleteObject(defaultBucket, key);
}
private void deleteObject(String bucket, String key) {
validateKey(key);
try {
minioClient.removeObject(RemoveObjectArgs.builder()
.bucket(bucket)
.object(key)
.build()
);
} catch (InvalidKeyException | ErrorResponseException | InsufficientDataException | InternalException
| InvalidResponseException | NoSuchAlgorithmException | ServerException | XmlParserException
| IllegalArgumentException | IOException e) {
throw new StorageException(e);
}
log.info("S3 object deleted: " + bucket + "/" + key);
}
/**
* Create a new Minio bucket.
*
* @param bucket bucket name
*/
public void createBucket(String bucket) {
try {
boolean exists = minioClient.bucketExists(
BucketExistsArgs.builder().bucket(bucket).build()
);
if (!exists) {
minioClient.makeBucket(
MakeBucketArgs.builder().bucket(bucket).build()
);
log.info("S3 bucket created: " + bucket);
}
} catch (InvalidKeyException | ErrorResponseException | InsufficientDataException | InternalException
| InvalidResponseException | NoSuchAlgorithmException | ServerException | XmlParserException
| IllegalArgumentException | IOException e) {
throw new StorageException(e);
}
}
}