티스토리 뷰
개발 환경
- Build : Gradle
- Spring boot : 3.3.1
- Java : 17
- OS : Windows
- IDE : IntelliJ IDEA
진행 상황 및 소개 기능
현재 벌점 기록 기능 개발 진행 중이다
거의 다 마쳤다고 생각했는데, 자동 삭제 기능이 없는 걸 깨닫고 자동 삭제 기능을 만들었다
일단 DB의 특정 데이터만 삭제한다고 하면 Spring의 Scheduled 기능을 사용하면 된다
구현하려는 기능 : 자동 삭제 기능
조건1 : 7일이 지난 벌점 기록은 삭제한다.
조건2 : 자정에 7일이 지난 데이터를 점검한다.
IF ~ DB의 데이터만 삭제하면 된다면
- build.gradle
// Scheduling
implementation 'org.springframework.boot:spring-boot-starter-scheduling'
- MainApplication
EnableScheduling 애노테이션 추가하기
@SpringBootApplication
@EnableScheduling
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(KickboardApplication.class, args);
}
}
- 해당 서비스 (me : PenaltyService)
@Scheduled(cron = "0 0 0 * * ?") // 매일 자정
@Transactional
public void deleteRecords(){
log.info("Starting scheduled task: deleteRecords");
penaltyRepository.deleteByDateBefore(LocalDateTime.now().minusDays(7)); // 7일
}
이렇게 간단하게 정해진 조건을 충족하면서 자동 삭제 기능을 만들 수 있다.
하지만 나와 같은 경우, Penalty db에 photo라는 AWS S3에 저장된 사진의 경로를 저장한 데이터가 존재한다.
DB의 photo에는 AWS S3의 버킷에 저장된 이미지 경로가 들어가게된다.
이 경로, 즉 URL은 패턴을 가지고 있다. (=url 형식이 일정하다)
패턴 : https://{bucket-name}.{region}.amazonaws.com/{filename}.{확장자}
ex. https://projecta.ap-northeast-2.amazonaws.com/output_img/capture_173388202.png
ex에서 output_img부터는 filename에 포함된다고 할 수 있다.
결과적으로 같은 버킷에 들어가는 데이터라면 .com까지는 같은 패턴이라는 것을 알 수 있다.
그러므로 우리는 .com 이후의 url를 보고 aws s3 파일 삭제를 고려하는 코드를 작성해주면 된다.
- 해당 서비스 (me : PenaltyService)
db에서 뿐만 아니라 aws s3의 데이터 삭제도 수행해야하기 때문에 이전에 적었던 코드와 달라진다.
일단 LocalDateTime.now().minusDays(7)의 코드는 LocalDateTime 타입의 변수로 받게된다.
변수로 받은 cutoffTime로 penaltyRepository에서 삭제해야할 Photo 목록을 deletePhoto로 받는다.
그 다음으로 DB에서 삭제해야 하는 코드는 정상적으로 삭제하고
AWS S3에서 삭제해야하는 URL 목록(Photo)을 for문을 통해 deleteImage 메소드를 수행하도록 한다.
@Scheduled(cron = "0 0 0 * * ?") // 매일 자정
@Transactional
public void deleteRecords(){
log.info("Starting scheduled task: deleteRecords");
LocalDateTime cutoffTime = LocalDateTime.now().minusDays(7); // 7일
// aws s3 데이터 삭제
List<String> deletePhoto = penaltyRepository.findIdPhotoDateBefore(cutoffTime);
// 데이터베이스 레코드 삭제
penaltyRepository.deleteByDateBefore(cutoffTime);
// S3 파일 삭제
if(deletePhoto != null && !deletePhoto.isEmpty()){
for(String url : deletePhoto)
s3Service.deleteImage(url);
}
}
- S3Service
아래 코드에 대한 자세한 설명을 적어놓았다.
@Service
public class S3Service {
private final S3Client s3Client;
@Autowired
public S3Service(S3Client s3Client) {
this.s3Client = s3Client;
}
@Value("${AWS_BUCKET_NAME}")
private String bucketName;
... 불필요한 코드 생략
// 이미지 삭제 메소드
public void deleteImage(String fileUrl) {
try {
String splitStr = ".com/";
String fileName = fileUrl.substring(fileUrl.lastIndexOf(splitStr) + splitStr.length());
DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder()
.bucket(bucketName)
.key(fileName)
.build();
s3Client.deleteObject(deleteObjectRequest);
}catch (S3Exception e){
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Failed to delete img from AWS S3 : " + e.awsErrorDetails().errorMessage());
}catch (Exception e){
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "Unexpected error occurred while delete img from AWS S3");
}
}
}
- 코드 설명
deleteImage 메소드는 S3Service에 위치한다.
왜냐하면 S3Client나 bucketName을 호출했던 service가 S3Service이기 때문이다.
위에서 말했던 것과 같이 .com이후에 파일이름을 추출하도록 하였고,
S3에서 삭제할 객체를 지정하는 요청을 생성했다.
String splitStr = ".com/";
String fileName = fileUrl.substring(fileUrl.lastIndexOf(splitStr) + splitStr.length());
DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder()
.bucket(bucketName)
.key(fileName)
.build();
S3 버킷에서 지정한 객체를 삭제한다.
s3Client.deleteObject(deleteObjectRequest);
그 외에는 예외처리이다
- 결과 확인하기
일단 결과를 테스트 해보기 위해 테스트 용으로 5분마다 scheduled가 실행되고, 등록된지 5분이 지난 데이터를 삭제하도록 하였다.
변경 코드
@Scheduled(cron = "0 0 0 * * ?") // 매일 자정
-> @Scheduled(fixedRate = 60000) // 매 5분마다 실행 : 테스트용
LocalDateTime cutoffTime = LocalDateTime.now().minusDays(7);
->LocalDateTime cutoffTime = LocalDateTime.now().minusMinutes(5); // 테스트용
일단 penalty를 검색해보면 4개의 데이터가 저장되어 있다.
date에서 등록된 시간을 확인할 수 있다. 상위 2개의 데이터는 aws s3에 사진이 들어가있는 데이터이고
하위 2개의 데이터는 postman으로 넣은 데이터이기 때문에 aws s3에 사진이 들어가 있지 않은 데이터이다.
그래서 아래 aws s3에 등록된 파일을 보면 2개의 파일만 저장되어 있는 것을 확인할 수 있다.
이때 시간은 오후 3:43, 등록된지 5분이 지난 데이터는 삭제되었다.
aws s3를 확인해보면 정상적으로 삭제된 것을 확인할 수 있다.
끝!
'JAVA & Spring' 카테고리의 다른 글
- Total
- Today
- Yesterday
- UnsupportedClassVersionError
- 사람검출
- 오븐시계
- randrange
- gradleload오류
- konlpy
- 터틀그래픽 명령어
- 터틀그래픽
- JAVA오류해결
- Kkma
- randint
- 10828번
- 사람수세기
- 문제풀이
- 파이썬
- tweepy
- database연결
- 백준
- 에러발생
- 다인승
- yolov8
- 터틀그래픽예제
- streamlistener
- Turtle Graphic
- python공부
- SPRING오류해결
- 다인승탑승
- baekjoon
- YOLO
- springboot
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |