S3 - woowa-turkey/miniprojects-2019 GitHub Wiki

Spring Boot์™€ S3 ์—ฐ๋™ํ•˜์—ฌ ํŒŒ์ผ ์ €์žฅํ•˜๊ธฐ


S3 - Simple Storage Service

  • https ํ˜•ํƒœ์˜ API๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ฑฐ๋‚˜ ์ถ”์ถœํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ์›น์„œ๋น„์Šค

  • ์›น ์ƒ์˜ ์˜์—ญ(bucket)์— ์šฐ๋ฆฌ์˜ ๋ฐ์ดํ„ฐ(๊ฐ์ฒด)๋ฅผ ์ €์žฅ

Setting

  • build.gradle

    repositories {
        mavenCentral()
        maven { url 'https://repo.spring.io/snapshot' }
    }
    
    ext {
        set('springCloudVersion', "Greenwich.BUILD-SNAPSHOT")
    }
    
    dependencies {
        implementation 'org.springframework.cloud:spring-cloud-starter-aws'
    }
    
    dependencyManagement {
        imports {
            mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
        }
    }
    
  • application.yml

    cloud:
      aws:
        stack:
          auto: false
        s3:
          bucket: woowa-turkey
        region:
          static: ap-northeast-2
        credentials:
          accessKey: [๋ฐœ๊ธ‰๋ฐ›์€ accessKey]
          secretKey: [๋ฐœ๊ธ‰๋ฐ›์€ secretKey]
    

    ํ”„๋กœ์ ํŠธ ๋ฐฐํฌ์‹œ ๊ธฐ๋ณธ์œผ๋กœ CloudFormation ๊ตฌ์„ฑ์„ ์‹œ์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์„ค์ •ํ•œ CloudFormation์ด ์—†์œผ๋ฉด ํ”„๋กœ์ ํŠธ ์‹คํ–‰์ด ๋˜์ง€ ์•Š์Œ. ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋„๋ก false๋กœ ์„ค์ •. (์ถœ์ฒ˜: https://private.tistory.com/76)

    credentials ์„ค์ • ๊ฐ™์€ ๊ฒฝ์šฐ git ์ €์žฅ์†Œ์— ์˜ฌ๋ผ๊ฐ€ ๊ณต๊ฐœ๋˜์ง€ ์•Š๋„๋ก ๋ณ„๋„์˜ ํŒŒ์ผ์— ์ž‘์„ฑํ•œ ๋‹ค์Œ .gitignore์— ๋“ฑ๋กํ•  ๊ฒƒ

code

  • Configuration

    @Configuration
    public class AwsConfig {
        @Value("${amazonProperties.accessKey}")
        private String accessKey;
        @Value("${amazonProperties.secretKey}")
        private String secretKey;
        @Value("${cloud.aws.region.static}")
        private String region;
        
        @Bean
        public BasicAWSCredentials basicAWSCredentials() {
            return new BasicAWSCredentials(accessKey, secretKey);
        }
    
        @Bean
        public AmazonS3 amazonS3Client() {
            return AmazonS3ClientBuilder.standard()
                    .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                    .withRegion(region)
                    .build();
        }
    }
  • S3Uploader

    @Component
    public class S3Uploader {
    
        private final AmazonS3Client amazonS3Client;
    
        @Value("${cloud.aws.s3.bucket}")
        private String bucket;
    
        private String upload(File uploadFile, String fileName) {
            amazonS3Client.putObject(new PutObjectRequest(bucket, fileName, uploadFile).withCannedAcl(CannedAccessControlList.PublicRead));
            return amazonS3Client.getUrl(bucket, fileName).toString();
        }
    
    }

MockS3

  • ํ…Œ์ŠคํŠธ๋ฅผ ํ•  ๋•Œ, ์‹ค์ œ S3 ์ €์žฅ์†Œ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ Mock์„ ํ™œ์šฉํ•ด ํ…Œ์ŠคํŠธ

  • build.gradle

    dependencies {
        testImplementation 'io.findify:s3mock_2.12:0.2.5'
    }
    
  • TestConfiguration

    @TestConfiguration
    public class AwsMockConfig {
    
        public static final String S3MOCK_ENDPOINT = "http://localhost:8001";
    
        @Value("${cloud.aws.region.static}")
        private String region;
    
        @Bean
        public S3Mock s3Mock() {
            return new S3Mock.Builder().withPort(8001).withInMemoryBackend().build();
        }
    
        @Bean
        @Primary
        public AmazonS3 amazonS3(S3Mock s3Mock) {
            s3Mock.start();
            AwsClientBuilder.EndpointConfiguration endpoint = new AwsClientBuilder.EndpointConfiguration(S3MOCK_ENDPOINT, region);
            AmazonS3 client = AmazonS3ClientBuilder
                    .standard()
                    .withPathStyleAccessEnabled(true)
                    .withEndpointConfiguration(endpoint)
                    .withCredentials(new AWSStaticCredentialsProvider(new AnonymousAWSCredentials()))
                    .build();
            client.createBucket(bucket);
    
            return client;
        }
    }
  • Example (S3UploaderTest)

    @Import(AwsMockConfig.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    class S3UploaderTest {
    
        @Autowired
        private S3Uploader s3Uploader;
    
        @Autowired
        private AmazonS3 mockS3Client;
    
        @Autowired
        private String bucket;
    
        private ByteArrayResource testFile = new ByteArrayResource(new byte[]{1, 2, 3, 4}) {
            @Override
            public String getFilename() {
                return "test_file.jpg";
            }
        };
        private String fileName = "savedFileName";
    
        @Test
        void ํŒŒ์ผ_์—…๋กœ๋“œ_ํ…Œ์ŠคํŠธ() throws IOException {
            //when
            String savedUrl = s3Uploader.upload(testFile, fileName);
    
            // then
            String resourceUrl = String.format("%s/%s/%s", S3MOCK_ENDPOINT, bucket, fileName);
            assertThat(savedUrl).isEqualTo(resourceUrl);
        }
    }

Reference

https://jojoldu.tistory.com/300

https://a1010100z.tistory.com/entry/AWSS3Spring-boot-Spring-boot%EC%99%80-S3%EB%A5%BC-%EC%97%B0%EB%8F%99%ED%95%98%EC%97%AC-%EC%9D%B4%EB%AF%B8%EC%A7%80%EB%A5%BC-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C-%EB%B0%9B%EC%95%84%EB%B3%B4%EC%9E%90

<ํ…Œ์ŠคํŠธ ๊ด€๋ จ>

https://github.com/findify/s3mock

https://normal93.tistory.com/27

โš ๏ธ **GitHub.com Fallback** โš ๏ธ