Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6fbabfb
feat : S3 의존성 추가 (초기세팅)
Kimminu7 Jun 21, 2025
b7c4a35
refactor : 호환 이슈로 S3 버전 변경
Kimminu7 Jun 23, 2025
55c5806
refactor, feat : s3 버킷 변경, config, uploader 추가
Kimminu7 Jun 23, 2025
4862eca
feat : prefix 관리를 위한 enum 추가
Kimminu7 Jun 23, 2025
ea5d02d
docs : 주석 추가
Kimminu7 Jun 23, 2025
b600d4f
feat : S3 업로드 실패 예외처리 적용 ( 커스텀 예외처리 )
Kimminu7 Jun 24, 2025
727390a
refactor : 엔티티 수정 ( 문제, 문제 이미지 ), 메소드 추가
Kimminu7 Jun 24, 2025
8675969
feat : 컨트롤러 , 서비스 이미지 기능 추가
Kimminu7 Jun 24, 2025
cbf38af
refactor : S3Upload log 추가 ( 업로드가 성공적으로 되는지 체크 )
Kimminu7 Jun 24, 2025
a30c4d6
refactor : 주석 수정
Kimminu7 Jun 24, 2025
fe0aa77
feat : 이미지 파일만 업로드 가능 ( MIME )
Kimminu7 Jun 25, 2025
992c083
refactor : ProblemImage 엔티티 삭제 -> Problem 컬럼 추가
Kimminu7 Jun 25, 2025
c832545
refactor : Problem 컬럼 추가 ( 총 제출 횟수, 정답 제출 횟수 )
Kimminu7 Jun 25, 2025
998d300
feat : S3 의존성 추가 (초기세팅)
Kimminu7 Jun 21, 2025
169f5e2
refactor : 호환 이슈로 S3 버전 변경
Kimminu7 Jun 23, 2025
c21b48a
refactor, feat : s3 버킷 변경, config, uploader 추가
Kimminu7 Jun 23, 2025
69135e7
feat : prefix 관리를 위한 enum 추가
Kimminu7 Jun 23, 2025
1f7ad95
docs : 주석 추가
Kimminu7 Jun 23, 2025
3f8fe5e
feat : S3 업로드 실패 예외처리 적용 ( 커스텀 예외처리 )
Kimminu7 Jun 24, 2025
895e99f
refactor : 엔티티 수정 ( 문제, 문제 이미지 ), 메소드 추가
Kimminu7 Jun 24, 2025
cf1e394
feat : 컨트롤러 , 서비스 이미지 기능 추가
Kimminu7 Jun 24, 2025
145ba95
refactor : S3Upload log 추가 ( 업로드가 성공적으로 되는지 체크 )
Kimminu7 Jun 24, 2025
e462e46
refactor : 주석 수정
Kimminu7 Jun 24, 2025
d420f56
feat : 이미지 파일만 업로드 가능 ( MIME )
Kimminu7 Jun 25, 2025
d2634ea
refactor : ProblemImage 엔티티 삭제 -> Problem 컬럼 추가
Kimminu7 Jun 25, 2025
3463157
refactor : Problem 컬럼 추가 ( 총 제출 횟수, 정답 제출 횟수 )
Kimminu7 Jun 25, 2025
7ebd0ff
Merge remote-tracking branch 'origin/feature/problemS3' into feature/…
Kimminu7 Jun 25, 2025
eabee5e
refactor : HTTP 상태코드 수정
Kimminu7 Jun 25, 2025
153ea22
refactor : addImage 메소드 유효성 검증 추가
Kimminu7 Jun 25, 2025
cd607a6
refactor : S3Uploader 예외처리 개선
Kimminu7 Jun 25, 2025
978fd60
Merge remote-tracking branch 'origin/dev' into feature/problemS3
Kimminu7 Jun 25, 2025
00cea6c
fix : CodetestApplicationTests 테스트 코드 클래스 제거
Kimminu7 Jun 25, 2025
1912347
refactor : 커스텀 예외처리 리팩토링
Kimminu7 Jun 25, 2025
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
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ dependencies {
//email-smtp
implementation 'org.springframework.boot:spring-boot-starter-mail'


// S3 SDK
implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
}

tasks.named('test') {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package org.ezcode.codetest.application.problem.service;

import org.ezcode.codetest.application.problem.dto.request.ProblemCreateRequest;
import org.ezcode.codetest.domain.problem.model.ProblemSearchCondition;
import org.ezcode.codetest.application.problem.dto.request.ProblemUpdateRequest;
import org.ezcode.codetest.application.problem.dto.response.ProblemDetailResponse;
import org.ezcode.codetest.application.problem.dto.response.ProblemResponse;
import org.ezcode.codetest.domain.problem.model.ProblemSearchCondition;
import org.ezcode.codetest.domain.problem.model.entity.Problem;
import org.ezcode.codetest.domain.problem.service.ProblemDomainService;
import org.ezcode.codetest.domain.user.model.entity.AuthUser;
import org.ezcode.codetest.domain.user.model.entity.User;
import org.ezcode.codetest.domain.user.service.UserDomainService;
import org.ezcode.codetest.infrastructure.s3.S3Directory;
import org.ezcode.codetest.infrastructure.s3.S3Uploader;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import lombok.RequiredArgsConstructor;

Expand All @@ -23,16 +26,22 @@ public class ProblemService {

private final ProblemDomainService problemDomainService;
private final UserDomainService userDomainService;
private final S3Uploader s3Uploader;

// 문제 생성 ( 관리자 )
@Transactional
public ProblemDetailResponse createProblem(ProblemCreateRequest requestDto, AuthUser authUser) {
public ProblemDetailResponse createProblem(ProblemCreateRequest requestDto, MultipartFile image, AuthUser authUser) {

User user = userDomainService.getUserById(authUser.getId());

Problem savedProblem = problemDomainService.createProblem(
ProblemCreateRequest.toEntity(requestDto, user)
);
Problem problem = ProblemCreateRequest.toEntity(requestDto, user);
Problem savedProblem = problemDomainService.createProblem(problem);

// 문제 이미지 있다면?
if (image != null && !image.isEmpty()) {
String imageUrl = s3Uploader.upload(image, S3Directory.PROBLEM.getDir());
savedProblem.addImage(imageUrl);
}
Comment on lines +37 to +44
Copy link

@coderabbitai coderabbitai bot Jun 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

트랜잭션 범위 내 외부 서비스 호출 검토 필요

S3 업로드가 트랜잭션 내에서 실행되고 있습니다. 이는 다음과 같은 문제를 야기할 수 있습니다.

문제점:

  1. S3 업로드 실패 시 DB 트랜잭션도 롤백됨
  2. S3 업로드 성공 후 DB 저장 실패 시 S3에 불필요한 파일 남음
  3. 트랜잭션이 오래 지속됨

개선 방안:

@Transactional
public ProblemDetailResponse createProblem(ProblemCreateRequest requestDto, MultipartFile image, AuthUser authUser) {
    User user = userDomainService.getUserById(authUser.getId());
    Problem problem = ProblemCreateRequest.toEntity(requestDto, user);
    Problem savedProblem = problemDomainService.createProblem(problem);
    
    // 트랜잭션 완료 후 S3 업로드 수행
    if (image != null && !image.isEmpty()) {
        String imageUrl = uploadImageAfterTransaction(image, savedProblem.getId());
        updateProblemWithImage(savedProblem.getId(), imageUrl);
    }
    
    return ProblemDetailResponse.from(savedProblem);
}

@Transactional
public void updateProblemWithImage(Long problemId, String imageUrl) {
    Problem problem = problemDomainService.getProblem(problemId);
    problem.addImage(imageUrl);
}

private String uploadImageAfterTransaction(MultipartFile image, Long problemId) {
    try {
        return s3Uploader.upload(image, S3Directory.PROBLEM.getDir());
    } catch (Exception e) {
        // 업로드 실패 시 로깅하고 기본값 반환 또는 재시도 로직
        log.error("Problem {} 이미지 업로드 실패", problemId, e);
        throw e;
    }
}
🤖 Prompt for AI Agents
In
src/main/java/org/ezcode/codetest/application/problem/service/ProblemService.java
around lines 37 to 44, the S3 upload is performed inside the transaction, which
can cause rollback issues and leave orphan files on S3. To fix this, refactor
the code to perform the S3 upload after the transaction commits by first saving
the Problem entity within the transaction, then uploading the image outside the
transaction, and finally updating the Problem entity with the image URL in a
separate transactional method.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throw new S3Exception(S3ExceptionCode.S3_UPLOAD_FAILED); 이렇게 커스텀 예외처리 해보는게 좋을거같아 적용해봐

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Kimminu7 좋은 제안이네요! 커스텀 예외를 사용하면 일관성 있는 예외 처리가 가능하겠어요. 제안하신 방식으로 개선해보겠습니다:

@Transactional
public ProblemDetailResponse createProblem(ProblemCreateRequest requestDto, MultipartFile image, AuthUser authUser) {
    User user = userDomainService.getUserById(authUser.getId());
    Problem problem = ProblemCreateRequest.toEntity(requestDto, user);
    Problem savedProblem = problemDomainService.createProblem(problem);
    
    // 트랜잭션 완료 후 S3 업로드 수행
    if (image != null && !image.isEmpty()) {
        String imageUrl = uploadImageAfterTransaction(image, savedProblem.getId());
        updateProblemWithImage(savedProblem.getId(), imageUrl);
    }
    
    return ProblemDetailResponse.from(savedProblem);
}

@Transactional
public void updateProblemWithImage(Long problemId, String imageUrl) {
    Problem problem = problemDomainService.getProblem(problemId);
    problem.addImage(imageUrl);
}

private String uploadImageAfterTransaction(MultipartFile image, Long problemId) {
    try {
        return s3Uploader.upload(image, S3Directory.PROBLEM.getDir());
    } catch (Exception e) {
        // 커스텀 예외로 일관성 있는 예외 처리
        log.error("Problem {} 이미지 업로드 실패", problemId, e);
        throw new S3Exception(S3ExceptionCode.S3_UPLOAD_FAILED);
    }
}

이렇게 하면 S3Uploader 내부의 예외 처리와 동일한 패턴을 유지하면서 일관성 있는 예외 처리가 가능하겠네요!

   (\   /)
  ( ._. )
 o_(")(")

Copy link
Collaborator Author

@Kimminu7 Kimminu7 Jun 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

안되는데? S3ExceptionCode.S3_UPLOAD_FAILED 생성자 생성하라고하네

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

@Kimminu7 어떤 부분이 안 되는지 구체적으로 알려주실 수 있을까요?

컴파일 에러인지, 실행 시 에러인지, 아니면 다른 문제인지 확인해보고 싶어요. 현재 코드베이스 구조를 더 자세히 살펴보고 정확한 해결책을 제공해드리겠습니다.

구체적인 에러 메시지나 문제 상황을 알려주시면 더 정확한 도움을 드릴 수 있어요!

   (>.<)
  o_(")(")

🏁 Script executed:

#!/bin/bash
# S3Exception과 관련 import들이 올바른지 확인
echo "=== S3Exception 클래스 확인 ==="
cat "src/main/java/org/ezcode/codetest/infrastructure/s3/exception/S3Exception.java"

echo -e "\n=== S3ExceptionCode 확인 ==="
cat "src/main/java/org/ezcode/codetest/infrastructure/s3/exception/code/S3ExceptionCode.java"

echo -e "\n=== ProblemService 현재 import 확인 ==="
head -20 "src/main/java/org/ezcode/codetest/application/problem/service/ProblemService.java"

echo -e "\n=== 로깅 관련 import나 annotation 확인 ==="
rg "import.*log|@Slf4j" "src/main/java/org/ezcode/codetest/application/problem/service/ProblemService.java"

Length of output: 3056


@Kimminu7 아, 문제를 찾았어요! 몇 가지 이슈가 있었네요:

  1. S3Exception 생성자 문제: S3Exception은 3개의 파라미터가 필요한데 1개만 전달했어요
  2. 로깅 import 누락: log 객체가 없는데 사용하려고 했어요
  3. 필요한 import 누락

다음과 같이 수정하면 됩니다:

// 필요한 import 추가
import org.ezcode.codetest.infrastructure.s3.exception.S3Exception;
import org.ezcode.codetest.infrastructure.s3.exception.code.S3ExceptionCode;
import lombok.extern.slf4j.Slf4j;

@Slf4j  // 로깅을 위한 어노테이션 추가
@Service
@RequiredArgsConstructor
public class ProblemService {
    // ... 기존 코드 ...

    private String uploadImageAfterTransaction(MultipartFile image, Long problemId) {
        try {
            return s3Uploader.upload(image, S3Directory.PROBLEM.getDir());
        } catch (Exception e) {
            log.error("Problem {} 이미지 업로드 실패", problemId, e);
            // S3Exception 생성자에 필요한 모든 파라미터 전달
            throw new S3Exception(
                S3ExceptionCode.S3_UPLOAD_FAILED,
                S3ExceptionCode.S3_UPLOAD_FAILED.getStatus(),
                S3ExceptionCode.S3_UPLOAD_FAILED.getMessage()
            );
        }
    }
}

또는 더 간단하게 S3ExceptionCode의 정보를 직접 사용할 수도 있어요:

throw new S3Exception(
    S3ExceptionCode.S3_UPLOAD_FAILED,
    S3ExceptionCode.S3_UPLOAD_FAILED.getStatus(),
    S3ExceptionCode.S3_UPLOAD_FAILED.getMessage()
);

이제 제대로 작동할 거예요!

   (\   /)
  ( ^.^ )
 o_(")(")


return ProblemDetailResponse.from(savedProblem);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
Expand Down Expand Up @@ -67,9 +69,18 @@ public class Problem extends BaseEntity {
@Column(nullable = false)
private Boolean isDeleted;

@Column(nullable = false)
private Long totalSubmissions;

@Column(nullable = false)
private Long correctSubmissions;

@OneToMany(mappedBy = "problem", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Testcase> testcases = new ArrayList<>();

@ElementCollection(fetch = FetchType.LAZY)
private List<String> imageUrl = new ArrayList<>();

@Builder
public Problem(User creator, Category category, String title, String description, int score, String difficulty,
Long memoryLimit, Long timeLimit, Reference reference) {
Expand All @@ -83,6 +94,8 @@ public Problem(User creator, Category category, String title, String description
this.timeLimit = timeLimit;
this.reference = reference;
isDeleted = false;
this.totalSubmissions = 0L;
this.correctSubmissions = 0L;
}

// 여러개를 하나의 객체로 만드는 것
Expand Down Expand Up @@ -122,4 +135,18 @@ public void update(User creator, Category category, String title, String descrip
public void softDelete() {
this.isDeleted = true;
}

// 이미지 추가
public void addImage(String image) {
if (image == null || image.trim().isEmpty()) {
throw new IllegalArgumentException("이미지 URL을 찾을수 없습니다");
}

if (imageUrl.contains(image)) {
return; // 중복된 URL 무시
}

imageUrl.add(image);
}

}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.ezcode.codetest.infrastructure.s3;

/**
* S3 prefix를 enum으로 관리
* */
public enum S3Directory {
PROBLEM("problem"),
PROFILE("profile");

// 소문자로 패키지 관리 하기 위해 dir추가
private final String dir;

S3Directory(String dir) {
this.dir = dir;
}

public String getDir() {
return dir;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package org.ezcode.codetest.infrastructure.s3;

import java.io.IOException;
import java.util.UUID;

import org.ezcode.codetest.infrastructure.s3.exception.S3Exception;
import org.ezcode.codetest.infrastructure.s3.exception.code.S3ExceptionCode;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.AmazonS3Exception;
import com.amazonaws.services.s3.model.ObjectMetadata;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Component
@RequiredArgsConstructor
@Slf4j
public class S3Uploader {

private final AmazonS3 amazonS3;

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

public String upload(MultipartFile multipartFile, String dirName) {
try {
// MIME 타입 검사 (png, jpeg, jpg, webp 만 가능)
String contentType = multipartFile.getContentType();
if (contentType == null || !contentType.startsWith("image/")) {
throw new S3Exception(S3ExceptionCode.S3_INVALID_FILE_TYPE);
}

// S3 파일명 지정 ( 디렉토리/UUID-원본파일명 )
String fileName = dirName + "/" + UUID.randomUUID() + "-" + multipartFile.getOriginalFilename();

ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(multipartFile.getSize());
metadata.setContentType(contentType);

amazonS3.putObject(bucket, fileName, multipartFile.getInputStream(), metadata);
String result = amazonS3.getUrl(bucket, fileName).toString(); // 업로드 파일 URL로 변환 ( 문자열 )
log.info("S3 버킷 이미지 업로드 완료 {}", result);

return result;

} catch (IOException e) {
log.error("S3 업로드 중 IO 오류 발생",e);
throw new S3Exception(S3ExceptionCode.S3_UPLOAD_FAILED);
} catch (AmazonS3Exception e) {
log.error("S3 서비스 오류 발생: {}", e.getErrorMessage(), e);
throw new S3Exception(S3ExceptionCode.S3_UPLOAD_FAILED);
} catch (Exception e) {
log.error("예상치 못한 업로드 오류 발생", e);
throw new S3Exception(S3ExceptionCode.S3_UPLOAD_FAILED);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.ezcode.codetest.infrastructure.s3.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

import lombok.RequiredArgsConstructor;

/**
* S3 연동
* */
@Configuration
@RequiredArgsConstructor

public class S3Config {

@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 AmazonS3 amazonS3() {
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
return AmazonS3ClientBuilder.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.ezcode.codetest.infrastructure.s3.exception;

import org.ezcode.codetest.common.base.exception.BaseException;
import org.ezcode.codetest.common.base.exception.ResponseCode;
import org.ezcode.codetest.infrastructure.s3.exception.code.S3ExceptionCode;
import org.springframework.http.HttpStatus;

import lombok.Getter;

@Getter
public class S3Exception extends BaseException {

private final ResponseCode responseCode;

private final HttpStatus httpStatus;

private final String message;

public S3Exception(S3ExceptionCode responseCode) {
this.responseCode = responseCode;
this.httpStatus = responseCode.getStatus();
this.message = responseCode.getMessage();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package org.ezcode.codetest.infrastructure.s3.exception.code;

import org.ezcode.codetest.common.base.exception.ResponseCode;
import org.springframework.http.HttpStatus;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum S3ExceptionCode implements ResponseCode {

S3_UPLOAD_FAILED(false, HttpStatus.INTERNAL_SERVER_ERROR, "S3 이미지 업로드 중 오류가 발생했습니다."),
S3_INVALID_FILE_TYPE(false, HttpStatus.BAD_REQUEST, "이미지 파일만 업로드할 수 있습니다.");

private final boolean success;

private final HttpStatus status;

private final String message;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.ezcode.codetest.application.problem.service.ProblemService;
import org.ezcode.codetest.domain.user.model.entity.AuthUser;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
Expand All @@ -14,7 +15,9 @@
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
Expand All @@ -30,17 +33,18 @@ public class ProblemAdminController {

private final ProblemService problemService;

@PostMapping
@PostMapping(consumes = { MediaType.MULTIPART_FORM_DATA_VALUE })
@Operation(summary = "문제 등록", description = "문제를 등록합니다.")
@ApiResponse(responseCode = "201", description = "문제 생성 성공")
public ResponseEntity<ProblemDetailResponse> createProblem(
@Valid @RequestBody ProblemCreateRequest request,
@RequestPart @Valid ProblemCreateRequest request,
@RequestPart(value = "image", required = false) MultipartFile image,
@AuthenticationPrincipal AuthUser user
) {

return ResponseEntity
.status(HttpStatus.CREATED)
.body(problemService.createProblem(request, user));
.body(problemService.createProblem(request, image, user));
}

@PutMapping("/{problemId}")
Expand Down
11 changes: 11 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,17 @@ spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.timeout=5000
spring.mail.properties.mail.smtp.starttls.enable=true

# ========================
# S3
# ========================
cloud.aws.credentials.access-key=${ACCESS_KEY}
cloud.aws.credentials.secret-key=${SECRET_KEY}

cloud.aws.s3.bucket=ezcode-s3
cloud.aws.region.static=ap-northeast-2
cloud.aws.stack.auto=false


#logging.level.org.springframework.security=DEBUG
#logging.level.org.springframework.security.oauth2=DEBUG
#logging.level.org.springframework.security.oauth2.client=TRACE
Expand Down
Loading