클라우드 서비스 중에서 이미지나 동영상 등 용량이 큰 파일을 저장할 때는 s3 가 필수다. s3에 사진을 업로드 하는 코프링 서버를 만들어보잣 🧚♀️
s3 spring boot 프로젝트를 보고 참고하며 만들었다.
일단 aws 사이트에 접속해서 s3 버킷을 생성한다. 나는 그냥 디폴트 값으로 설정한 뒤 생성했다.
지금 s3는 아무나 접근할 수 없는 상태이다. s3에 접근하기 위해서 이에 대한 권한을 가진 user를 생성해줘야 한다.
aws에서 IAM에 들어가서 사용자를 추가한다.
프로그래밍 방식 액세스 선택
s3에 대해서 모든 권한을 가지는 정책을 선택한다.
이제 aws에서 모든 설정에 대한 부분은 끝났다. 이제 코드로 들어가보자.
spring cloud AWS starter
의존성을 gradle에 추가한다.
application.yml에서 s3 및 IAM에 대한 정보를 입력한다.
cloud:
aws:
credentials:
access-key: IAM의 access-key
secret-key: IAM의 secret-key
stack:
auto: false
region:
static: us-east-2
이 때 여기서 cloud.aws.stack.auto = false
는 EC2에서 Spring Cloud 프로젝트를 실행시키면 기본으로 CloudFormation 구성을 시작한다. 이 때 나는 CloudFormation이 없으므로 해당 내용을 사용하지 않도록 false를 입력한다.
@Configuration
class AwsConfig {
@Value("\${cloud.aws.credentials.access-key}")
private lateinit var awsAccessKey: String
@Value("\${cloud.aws.credentials.secret-key}")
private lateinit var awsSecretKey: String
@Value("\${cloud.aws.region.static}")
private lateinit var regions: Regions
// Primary 어노테이션을 사용해서 기존 오브젝트를 오버라이드 함
@Primary
@Bean
fun amazonSQSAsync(): AmazonS3? {
return AmazonS3ClientBuilder.standard().withRegion(regions)
.withCredentials(AWSStaticCredentialsProvider(BasicAWSCredentials(awsAccessKey, awsSecretKey)))
.build()
}
}
private val log : Logger get() = LoggerFactory.getLogger(this::class.java)
@Autowired
private lateinit var amazonS3: AmazonS3
@Value("\${cloud.aws.s3.bucket}")
private lateinit var bucketName: String
// 파일 업로드
fun fileUplaod(file: MultipartFile): String {
var fileName = ""
try {
fileName = UUID.randomUUID().toString() + file.originalFilename
val metadata = ObjectMetadata()
metadata.contentLength = file.size
amazonS3.putObject(bucketName, fileName, file.inputStream, metadata)
} catch (e: Exception) {
throw BusinessException(ErrorCode.FILE_UPLOAD_ERROR)
}
log.info("File Uploaded Successfully : {}", fileName)
return fileName
}
// 업로드한 파일 get
fun getFile(fileName: String): MultipartFile {
val s3Object = amazonS3.getObject(bucketName, fileName)
return MockMultipartFile(fileName, fileName, s3Object.objectMetadata.contentType, s3Object.objectContent)
}
파일 업로드 / 조회 함수가 포함된 클래스를 mock한 다음에 해당 함수가 수행됐는지 안됐는지 확인할 수 있을 것 같다.
verify(s3Amazon).fileUpload(any())