From c977f8f738e14410397d9701abafaacee68e14c1 Mon Sep 17 00:00:00 2001 From: vlad fernoaga Date: Mon, 19 Feb 2024 15:22:17 +0200 Subject: [PATCH 1/2] implement demo code for how-to-mock-aws-s3-integration-tests --- aws-modules/aws-s3/pom.xml | 28 +++++++ .../java/com/baeldung/s3/S3CrudService.java | 65 +++++++++++++++ .../s3/S3CrudServiceIntegrationTest.java | 82 +++++++++++++++++++ 3 files changed, 175 insertions(+) create mode 100644 aws-modules/aws-s3/src/main/java/com/baeldung/s3/S3CrudService.java create mode 100644 aws-modules/aws-s3/src/test/java/com/baeldung/s3/S3CrudServiceIntegrationTest.java diff --git a/aws-modules/aws-s3/pom.xml b/aws-modules/aws-s3/pom.xml index 9ba436b43f..b7bc34f863 100644 --- a/aws-modules/aws-s3/pom.xml +++ b/aws-modules/aws-s3/pom.xml @@ -20,6 +20,12 @@ s3 ${aws.java.sdk.version} + + software.amazon.awssdk + url-connection-client + ${aws.java.sdk.version} + test + commons-io @@ -37,12 +43,34 @@ commons-codec ${commons-codec-version} + + + com.adobe.testing + s3mock + ${com.adobe.testing.version} + test + + + com.adobe.testing + s3mock-testcontainers + ${com.adobe.testing.version} + test + + + + org.testcontainers + junit-jupiter + ${org.testcontainers.version} + test + 2.20.52 1.10.L001 0.9.4.0006L + 3.3.0 + 1.19.4 \ No newline at end of file diff --git a/aws-modules/aws-s3/src/main/java/com/baeldung/s3/S3CrudService.java b/aws-modules/aws-s3/src/main/java/com/baeldung/s3/S3CrudService.java new file mode 100644 index 0000000000..75990516b2 --- /dev/null +++ b/aws-modules/aws-s3/src/main/java/com/baeldung/s3/S3CrudService.java @@ -0,0 +1,65 @@ +package com.baeldung.s3; + +import java.util.Optional; + +import software.amazon.awssdk.core.ResponseBytes; +import software.amazon.awssdk.core.sync.RequestBody; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.model.CreateBucketRequest; +import software.amazon.awssdk.services.s3.model.DeleteObjectRequest; +import software.amazon.awssdk.services.s3.model.GetObjectRequest; +import software.amazon.awssdk.services.s3.model.GetObjectResponse; +import software.amazon.awssdk.services.s3.model.PutObjectRequest; +import software.amazon.awssdk.services.s3.model.S3Exception; + +public class S3CrudService { + + private final S3Client s3Client; + + public S3CrudService(S3Client s3Client) { + this.s3Client = s3Client; + } + + public void createBucket(String bucketName) { + CreateBucketRequest bucketRequest = CreateBucketRequest.builder() + .bucket(bucketName) + .build(); + + s3Client.createBucket(bucketRequest); + } + + public void createObject(String bucketName, File inMemoryObject) { + PutObjectRequest request = PutObjectRequest.builder() + .bucket(bucketName) + .key(inMemoryObject.getName()) + .build(); + s3Client.putObject(request, RequestBody.fromByteBuffer(inMemoryObject.getContent())); + } + + public Optional getObject(String bucketName, String objectKey) { + try { + GetObjectRequest getObjectRequest = GetObjectRequest.builder() + .bucket(bucketName) + .key(objectKey) + .build(); + ResponseBytes responseResponseBytes = s3Client.getObjectAsBytes(getObjectRequest); + return Optional.of(responseResponseBytes.asByteArray()); + } catch (S3Exception e) { + return Optional.empty(); + } + } + + public boolean deleteObject(String bucketName, String objectKey) { + try { + DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder() + .bucket(bucketName) + .key(objectKey) + .build(); + + s3Client.deleteObject(deleteObjectRequest); + return true; + } catch (S3Exception e) { + return false; + } + } +} diff --git a/aws-modules/aws-s3/src/test/java/com/baeldung/s3/S3CrudServiceIntegrationTest.java b/aws-modules/aws-s3/src/test/java/com/baeldung/s3/S3CrudServiceIntegrationTest.java new file mode 100644 index 0000000000..19a5f713d2 --- /dev/null +++ b/aws-modules/aws-s3/src/test/java/com/baeldung/s3/S3CrudServiceIntegrationTest.java @@ -0,0 +1,82 @@ +package com.baeldung.s3; + +import static org.assertj.core.api.Assertions.assertThat; +import static software.amazon.awssdk.http.SdkHttpConfigurationOption.TRUST_ALL_CERTIFICATES; + +import java.net.URI; +import java.util.Arrays; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.testcontainers.junit.jupiter.Container; +import org.testcontainers.junit.jupiter.Testcontainers; + +import com.adobe.testing.s3mock.testcontainers.S3MockContainer; + +import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient; +import software.amazon.awssdk.services.s3.S3Client; +import software.amazon.awssdk.services.s3.S3Configuration; +import software.amazon.awssdk.utils.AttributeMap; + +// This live test needs a running Docker instance so that a S3Mock Container can be started + +@Testcontainers +public class S3CrudServiceIntegrationTest { + + private static final String TEST_BUCKET_NAME = "test-bucket"; + + @Container + private final S3MockContainer s3Mock = new S3MockContainer("latest"); + private S3Client s3Client; + + @BeforeEach + void setUp() { + var endpoint = s3Mock.getHttpsEndpoint(); + var serviceConfig = S3Configuration.builder() + .pathStyleAccessEnabled(true) + .build(); + var httpClient = UrlConnectionHttpClient.builder() + .buildWithDefaults(AttributeMap.builder() + .put(TRUST_ALL_CERTIFICATES, Boolean.TRUE) + .build()); + s3Client = S3Client.builder() + .endpointOverride(URI.create(endpoint)) + .serviceConfiguration(serviceConfig) + .httpClient(httpClient) + .build(); + } + + @Test + void whenVerifyingCreationOfS3Bucket_thenCorrect() { + var s3CrudService = new S3CrudService(s3Client); + s3CrudService.createBucket(TEST_BUCKET_NAME); + + var createdBucketName = s3Client.listBuckets() + .buckets() + .get(0) + .name(); + assertThat(TEST_BUCKET_NAME).isEqualTo(createdBucketName); + } + + @Test + void whenCreatingAnObjectOnS3Bucket_thenSameObjectIsRetrived() { + var s3CrudService = new S3CrudService(s3Client); + s3CrudService.createBucket(TEST_BUCKET_NAME); + + var fileToSave = FileGenerator.generateFiles(1, 100) + .get(0); + s3CrudService.createObject(TEST_BUCKET_NAME, fileToSave); + + var savedFileContent = s3CrudService.getObject(TEST_BUCKET_NAME, fileToSave.getName()); + + assertThat(Arrays.equals(fileToSave.getContent() + .array(), savedFileContent.orElse(new byte[]{}))).isTrue(); + + s3CrudService.deleteObject(TEST_BUCKET_NAME,fileToSave.getName()); + + var deletedFileContent = s3CrudService.getObject(TEST_BUCKET_NAME, fileToSave.getName()); + assertThat(deletedFileContent).isEmpty(); + } +} + + From 162a6e8117014fb666ba0c226d9b9fc30c7fe2cf Mon Sep 17 00:00:00 2001 From: vlad fernoaga Date: Mon, 19 Feb 2024 15:23:05 +0200 Subject: [PATCH 2/2] fix formatting --- .../java/com/baeldung/s3/S3CrudServiceIntegrationTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws-modules/aws-s3/src/test/java/com/baeldung/s3/S3CrudServiceIntegrationTest.java b/aws-modules/aws-s3/src/test/java/com/baeldung/s3/S3CrudServiceIntegrationTest.java index 19a5f713d2..1a8f046f0c 100644 --- a/aws-modules/aws-s3/src/test/java/com/baeldung/s3/S3CrudServiceIntegrationTest.java +++ b/aws-modules/aws-s3/src/test/java/com/baeldung/s3/S3CrudServiceIntegrationTest.java @@ -70,9 +70,9 @@ public class S3CrudServiceIntegrationTest { var savedFileContent = s3CrudService.getObject(TEST_BUCKET_NAME, fileToSave.getName()); assertThat(Arrays.equals(fileToSave.getContent() - .array(), savedFileContent.orElse(new byte[]{}))).isTrue(); + .array(), savedFileContent.orElse(new byte[] {}))).isTrue(); - s3CrudService.deleteObject(TEST_BUCKET_NAME,fileToSave.getName()); + s3CrudService.deleteObject(TEST_BUCKET_NAME, fileToSave.getName()); var deletedFileContent = s3CrudService.getObject(TEST_BUCKET_NAME, fileToSave.getName()); assertThat(deletedFileContent).isEmpty();