Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,6 @@ out/

build/generated/
application-local.properties
application-test.properties
application-test.properties
application-s3.properties
test_img_dir
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,12 @@ dependencies {
// Health Check
implementation 'org.springframework.boot:spring-boot-starter-actuator'

// AWS 서비스 연동을 쉽게 도와주는 Spring Cloud 통합 패키지
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.mysql:mysql-connector-j'
// runtimeOnly 'com.h2database:h2'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testCompileOnly 'org.projectlombok:lombok'
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/example/moim/club/dto/ClubImgInput.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.example.moim.club.dto;

import com.example.moim.global.util.ValidFile;
import com.example.moim.global.util.file.exception.ValidFile;
import lombok.Data;
import org.springframework.web.multipart.MultipartFile;

Expand Down
8 changes: 4 additions & 4 deletions src/main/java/com/example/moim/club/service/ClubService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import com.example.moim.club.repository.UserClubRepository;
import com.example.moim.club.exception.ClubPasswordException;
import com.example.moim.club.exception.ClubPermissionException;
import com.example.moim.global.util.FileStore;
import com.example.moim.global.util.file.service.FileService;
import com.example.moim.notification.dto.ClubJoinEvent;
import com.example.moim.user.entity.User;
import com.example.moim.user.repository.UserRepository;
Expand All @@ -26,11 +26,11 @@ public class ClubService {
private final ClubRepository clubRepository;
private final UserClubRepository userClubRepository;
private final UserRepository userRepository;
private final FileStore fileStore;
private final FileService fileService;
private final ApplicationEventPublisher eventPublisher;

public ClubOutput saveClub(User user, ClubInput clubInput) throws IOException {
Club club = clubRepository.save(Club.createClub(clubInput, fileStore.storeFile(clubInput.getProfileImg())));
Club club = clubRepository.save(Club.createClub(clubInput, fileService.upload(clubInput.getProfileImg(), "/club_profile")));
UserClub userClub = userClubRepository.save(UserClub.createLeaderUserClub(user, club));
return new ClubOutput(club, userClub.getCategory());
}
Expand All @@ -47,7 +47,7 @@ public ClubOutput updateClub(User user, ClubUpdateInput clubUpdateInput) throws
throw new ClubPasswordException("모임 비밀번호가 틀렸습니다.");
}

club.updateClub(clubUpdateInput, fileStore.storeFile(clubUpdateInput.getProfileImg()));
club.updateClub(clubUpdateInput, fileService.upload(clubUpdateInput.getProfileImg(), "/club_profile"));
return new ClubOutput(club);
}

Expand Down
41 changes: 0 additions & 41 deletions src/main/java/com/example/moim/global/util/FileStore.java

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.example.moim.global.util.file.config;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import lombok.extern.slf4j.Slf4j;
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;

@Slf4j
@Profile("!test")
@Configuration
public class AwsS3Config {

@Value("${cloud.aws.credentials.access-key}")
private String accessKey;

@Value("${cloud.aws.credentials.secret-key}")
private String secretKey;

@Value("${cloud.aws.region.static}")
private String region;

@Bean
public BasicAWSCredentials basicAWSCredentials() {
return new BasicAWSCredentials(accessKey, secretKey);
}

@Bean
public AmazonS3 amazonS3(BasicAWSCredentials basicAWSCredentials) {
return AmazonS3ClientBuilder.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(basicAWSCredentials))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.example.moim.global.util.file.config;

import lombok.extern.slf4j.Slf4j;
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;

import java.io.File;

@Slf4j
@Profile("test")
@Configuration
public class LocalFileConfig {

@Value("${local.upload.directory}")
private String fileUploadDir;

// @Bean
// public File file() {
//
// File directory = new File(fileUploadDir);
//
// if (!directory.exists()) {
// directory.mkdir();
// }
//
// return directory;
// }
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.example.moim.global.util;
package com.example.moim.global.util.file.exception;

import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import org.springframework.web.multipart.MultipartFile;

public class ValidFileValidator implements ConstraintValidator<ValidFile, MultipartFile> {
public class FileValidator implements ConstraintValidator<ValidFile, MultipartFile> {

@Override
public boolean isValid(MultipartFile file, ConstraintValidatorContext context) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.example.moim.global.util;
package com.example.moim.global.util.file.exception;

import jakarta.validation.Constraint;
import jakarta.validation.Payload;
Expand All @@ -10,7 +10,7 @@

@Target(value = ElementType.FIELD)
@Retention(value = RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ValidFileValidator.class)
@Constraint(validatedBy = FileValidator.class)
public @interface ValidFile {
String message() default "유효하지 않은 파일입니다.";

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.example.moim.global.util.file.exception.advice;

import com.example.moim.global.exception.GeneralException;
import com.example.moim.global.exception.ResponseCode;

public class AwsS3ControllerAdvice extends GeneralException {
public AwsS3ControllerAdvice(ResponseCode responseCode) {
super(responseCode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.example.moim.global.util.file.exception.advice;

import com.example.moim.global.exception.GeneralException;
import com.example.moim.global.exception.ResponseCode;

public class LocalFileControllerAdvice extends GeneralException {
public LocalFileControllerAdvice(ResponseCode responseCode) {
super(responseCode);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.example.moim.global.util.file.model;

import lombok.*;

@Builder
@Getter @Setter
@NoArgsConstructor
@AllArgsConstructor
public class AwsS3 {

private String key;
private String path;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.example.moim.global.util.file.service;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.CannedAccessControlList;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.example.moim.global.exception.ResponseCode;
import com.example.moim.global.util.file.model.AwsS3;
import com.example.moim.global.util.file.exception.advice.AwsS3ControllerAdvice;
import com.example.moim.global.util.uuid.UuidHolder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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;

@Slf4j
//@Service
//@Profile("!test")
@RequiredArgsConstructor
public class AwsS3FileService implements FileService {

private final AmazonS3 amazonS3;
private final UuidHolder uuidHolder;

@Value("${cloud.aws.s3.bucket}")
private String bucket;

public String upload(MultipartFile multipartFile, String directoryName) {

// 확장자 가져오기
String originalFilename = multipartFile.getOriginalFilename();
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));

String fileName = uuidHolder.randomUuid() + extension;
String key = directoryName + "/" + fileName;
log.info("upload key : {}", key);

// 메타 데이터 설정
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(multipartFile.getSize());
metadata.setContentType(multipartFile.getContentType());

try {
// 파일 업로드
PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, key, multipartFile.getInputStream(), metadata)
.withCannedAcl(CannedAccessControlList.PublicRead); // Public Read 권한 설정
amazonS3.putObject(putObjectRequest);
} catch (IOException e) {
throw new AwsS3ControllerAdvice(ResponseCode.S3_UPLOAD_FAIL);
}

String path = amazonS3.getUrl(bucket, key).toString();
log.info("upload path : {}", path);

AwsS3 result = AwsS3
.builder()
.key(key)
.path(path)
.build();

return result.getPath();
}

public void remove(String path) {

if (!amazonS3.doesObjectExist(bucket, path)) {
log.error("{} 이 존재하지 않습니다.", path);
throw new AwsS3ControllerAdvice(ResponseCode.S3_PATH_NOT_FOUND);
}
amazonS3.deleteObject(bucket, path);

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.example.moim.global.util.file.service;

import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

public interface FileService {
String upload(MultipartFile multipartFile, String directoryName) throws IOException;
void remove(String path);
}
Loading