38.2 Working with S3 (tutorial) - using aws-java-sdk (#38)

This commit is contained in:
Art
2021-09-29 11:12:42 +03:00
parent ebcb900cdf
commit 70aebf53bb
5 changed files with 156 additions and 1 deletions

View File

@ -0,0 +1,30 @@
package net.shyshkin.study.fullstack.supportportal.backend.config;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
@Profile("image-s3")
public class AmazonConfig {
@Bean
public AmazonS3 s3(@Value("${app.amazon-s3.access-key}") String accessKey,
@Value("${app.amazon-s3.secret-key}") String secretKey,
@Value("${app.amazon-s3.region}") String region) {
AWSCredentials awsCredentials =
new BasicAWSCredentials(accessKey, secretKey);
return AmazonS3ClientBuilder
.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.build();
}
}

View File

@ -0,0 +1,83 @@
package net.shyshkin.study.fullstack.supportportal.backend.service;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.SdkClientException;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.ObjectListing;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.S3Object;
import com.amazonaws.services.s3.model.S3ObjectInputStream;
import com.amazonaws.util.IOUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.shyshkin.study.fullstack.supportportal.backend.exception.domain.ImageStorageException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.UUID;
@Slf4j
@Service
@Profile("image-s3")
@RequiredArgsConstructor
public class S3ProfileImageService implements ProfileImageService {
private final AmazonS3 amazonS3;
@Value("${app.amazon-s3.bucket-name}")
private String bucketName;
@Override
public byte[] retrieveProfileImage(UUID userId, String filename) {
String fileKey = createFileKey(userId, filename);
try {
S3Object object = amazonS3.getObject(bucketName, fileKey);
S3ObjectInputStream objectContent = object.getObjectContent();
return IOUtils.toByteArray(objectContent);
} catch (AmazonServiceException | IOException exception) {
throw new ImageStorageException("Failed to download the file from Amazon S3", exception);
}
}
@Override
public String persistProfileImage(UUID userId, MultipartFile profileImage, String filename) {
// String fileName = String.format("%s", profileImage.getOriginalFilename());
String fileKey = createFileKey(userId, filename);
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.addUserMetadata("Content-Type", profileImage.getContentType());
objectMetadata.addUserMetadata("Content-Length", String.valueOf(profileImage.getSize()));
try {
amazonS3.putObject(bucketName, fileKey, profileImage.getInputStream(), objectMetadata);
} catch (IOException | SdkClientException exception) {
throw new ImageStorageException("Failed to persist to Amazon S3", exception);
}
return null;
}
@Override
public void clearUserStorage(UUID userId) {
try {
String prefix = userId + "/";
ObjectListing objectListing = amazonS3.listObjects(bucketName, prefix);
objectListing.getObjectSummaries()
.forEach(file -> amazonS3.deleteObject(bucketName, file.getKey()));
} catch (SdkClientException exception) {
throw new ImageStorageException("Failed to delete objects from Amazon S3", exception);
}
}
private String createFileKey(UUID userId, String filename) {
return String.format("%s/%s", userId, filename);
}
}

View File

@ -128,4 +128,17 @@ server.ssl:
key-store-password: secret # Keystore password
key-store-type: PKCS12 # Keystore format
---
spring:
config:
activate:
on-profile: image-s3
app:
amazon-s3:
access-key: ${AMAZON_S3_ACCESS_KEY}
secret-key: ${AMAZON_S3_SECRET_KEY}
region: eu-north-1
bucket-name: portal-user-profile-images