# AmazonS3ServiceApitest.java

    package cloud.wconnect.frontoffice.apitest;

    import java.io.IOException;
    import java.io.InputStream;
    import java.net.URI;
    import java.util.Map;

    import org.springframework.beans.factory.annotation.Value;

    import cloud.wconnect.commonlib.apitest.LocalStackConfigHolder;
    import cloud.wconnect.frontoffice.service.AmazonS3Service;
    import jakarta.validation.constraints.NotBlank;
    import org.springframework.web.multipart.MultipartFile;
    import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
    import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
    import software.amazon.awssdk.core.sync.RequestBody;
    import software.amazon.awssdk.http.urlconnection.UrlConnectionHttpClient;
    import software.amazon.awssdk.regions.Region;
    import software.amazon.awssdk.services.s3.S3Client;
    import software.amazon.awssdk.services.s3.S3Configuration;
    import software.amazon.awssdk.services.s3.model.*;

    public class AmazonS3ServiceApitest extends AmazonS3Service {
        @Value("${aws-s3.region}")
        private String awsRegion;

        @Value("${aws-s3.third-party.bucket}")
        private String bucket;

        @Value("#{${aws-s3.function-bucket}}")
        private Map<String, Map<String, Object>> bucketMap;

        private S3Client initS3ForImport(Map<String, Object> config) {
            return  S3Client.builder()
                    .endpointOverride(URI.create(LocalStackConfigHolder.getEndpoint()))
                    .serviceConfiguration(S3Configuration.builder().pathStyleAccessEnabled(true).build())
                    .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(config.get("accessKey").toString(),
                            config.get("secretKey").toString())))
                    .region(Region.of(awsRegion))
                    .forcePathStyle(true)
                    .httpClient(UrlConnectionHttpClient.builder().build())
                    .build();
        }

        private S3Client initS3() {
            return S3Client.builder()
                    .endpointOverride(URI.create(LocalStackConfigHolder.getEndpoint()))
                    .serviceConfiguration(S3Configuration.builder().pathStyleAccessEnabled(true).build())
                    .credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create("", "")))
                    .region(Region.of(awsRegion))
                    .forcePathStyle(true)
                    .httpClient(UrlConnectionHttpClient.builder().build())
                    .build();
        }

        public InputStream getFile(@NotBlank String key) {
            GetObjectRequest getObjectRequest = GetObjectRequest.builder()
                    .bucket(bucket)
                    .key(key)
                    .build();

            try (S3Client s3 = initS3()) {
                return s3.getObjectAsBytes(getObjectRequest).asInputStream();
            }
        }

        public InputStream getFile(String function, @NotBlank String key) {
            Map<String, Object> config = bucketMap.get(function);
            GetObjectRequest getObjectRequest = GetObjectRequest.builder()
                    .bucket(config.get("bucket").toString())
                    .key(key)
                    .build();

            try (S3Client s3 = initS3ForImport(config)) {
                return s3.getObjectAsBytes(getObjectRequest).asInputStream();
            }
        }

        public String uploadFile(MultipartFile file, @NotBlank String key) throws IOException {
            PutObjectRequest objectRequest = PutObjectRequest.builder()
                    .bucket(bucket)
                    .key(key)
                    .build();

            try (S3Client s3 = initS3()) {
                PutObjectResponse putObjectResponse = s3.putObject(objectRequest, RequestBody.fromBytes(file.getBytes()));
                return putObjectResponse.eTag();
            }
        }

        public String uploadFile(String function, MultipartFile file, String key) throws IOException {
            Map<String, Object> config = bucketMap.get(function);
            PutObjectRequest objectRequest = PutObjectRequest.builder()
                    .bucket(config.get("bucket").toString())
                    .key(key)
                    .build();

            try (S3Client s3 = initS3ForImport(config)) {
                PutObjectResponse putObjectResponse = s3.putObject(objectRequest, RequestBody.fromBytes(file.getBytes()));
                return putObjectResponse.eTag();
            }
        }

        public String uploadFile(String function, InputStream inputStream, String key) throws IOException {
            Map<String, Object> config = bucketMap.get(function);
            PutObjectRequest objectRequest = PutObjectRequest.builder()
                    .bucket(config.get("bucket").toString())
                    .key(key)
                    .build();

            try (S3Client s3 = initS3ForImport(config)) {
                PutObjectResponse putObjectResponse = s3.putObject(objectRequest, RequestBody.fromBytes(inputStream.readAllBytes()));
                return putObjectResponse.eTag();
            }
        }
    }