-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* feat: 로그 요청 유효성 검사를 위한 커스텀 어노테이션 추가 - ValidLogRequests 어노테이션 생성 * feat: 로그 요청 목록 유효성 검사 기능 구현 - LogRequestsValidator 클래스 생성 - 빈 요청, 개별 요청, 전체 요청의 유효성 검사 로직 구현 - 유효하지 않은 요청 필터링 및 오류 메시지 생성 기능 추가 * test: 여러 로그 POST 요청에 대한 테스트 케이스 추가 - 빈 요청 시 400 에러 반환 테스트 - 모든 요청 무효 시 400 에러 반환 테스트 - 일부 요청만 유효한 경우 정상 처리 테스트 - 전체 요청 유효 시 정상 처리 테스트 * test: 빈 줄을 허용하는 비즈니스 로직 변화로 테스트 코드 수정 - data가 빈 줄일 때에 대한 예외상황을 허용하도록 변경 * feat: LogController에 로그 요청 유효성 검사 적용 - @ValidLogRequests 어노테이션을 LogController의 saveLogs 메서드에 적용 * refactor: indexOf 연산을 사용하지 않기 위한 리팩토링 - requests로 stream을 돌리지 않고 ,IntStream을 통해 index 기반 접근하여 반환하도록 수정했습니다.
- Loading branch information
Showing
4 changed files
with
225 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
128 changes: 128 additions & 0 deletions
128
...at/src/main/java/info/logbat/domain/log/presentation/validation/LogRequestsValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
package info.logbat.domain.log.presentation.validation; | ||
|
||
import info.logbat.domain.log.presentation.payload.request.CreateLogRequest; | ||
import jakarta.validation.ConstraintValidator; | ||
import jakarta.validation.ConstraintValidatorContext; | ||
import jakarta.validation.ConstraintViolation; | ||
import jakarta.validation.Validator; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.IntStream; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
|
||
/** | ||
* 로그 요청 목록의 유효성을 검사하는 밸리데이터 클래스입니다. 빈 요청, 개별 요청의 유효성, 전체 요청의 유효성을 검사합니다. | ||
*/ | ||
@Component | ||
@RequiredArgsConstructor | ||
public class LogRequestsValidator implements | ||
ConstraintValidator<ValidLogRequests, List<CreateLogRequest>> { | ||
|
||
private final Validator validator; | ||
|
||
/** | ||
* 로그 요청 목록의 유효성을 검사합니다. | ||
* | ||
* @param requests 검사할 로그 요청 목록 | ||
* @param context 제약 조건 컨텍스트 | ||
* @return 유효성 검사 결과 (true: 유효, false: 무효) | ||
*/ | ||
@Override | ||
public boolean isValid(List<CreateLogRequest> requests, ConstraintValidatorContext context) { | ||
if (isEmptyRequest(requests, context)) { | ||
return false; | ||
} | ||
|
||
List<String> errorMessages = new ArrayList<>(); | ||
List<CreateLogRequest> validRequests = filterValidRequests(requests, errorMessages); | ||
|
||
updateRequestsList(requests, validRequests); | ||
|
||
if (requests.isEmpty()) { | ||
addErrorMessage(context, String.join("\n", errorMessages)); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
/** | ||
* 요청 목록이 비어있는지 확인합니다. | ||
* | ||
* @param requests 검사할 요청 목록 | ||
* @param context 제약 조건 컨텍스트 | ||
* @return 비어있으면 true, 그렇지 않으면 false | ||
*/ | ||
private boolean isEmptyRequest(List<CreateLogRequest> requests, | ||
ConstraintValidatorContext context) { | ||
if (requests == null || requests.isEmpty()) { | ||
addErrorMessage(context, "빈 요청이 전달되었습니다."); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
/** | ||
* 유효한 요청만 필터링합니다. | ||
* | ||
* @param requests 전체 요청 목록 | ||
* @param errorMessages 오류 메시지를 저장할 리스트 | ||
* @return 유효한 요청 목록 | ||
*/ | ||
private List<CreateLogRequest> filterValidRequests(List<CreateLogRequest> requests, | ||
List<String> errorMessages) { | ||
|
||
return IntStream.range(0, requests.size()) | ||
.filter(index -> isValidRequest(requests.get(index), index + 1, errorMessages)) | ||
.mapToObj(requests::get) | ||
.toList(); | ||
} | ||
|
||
/** | ||
* 개별 요청의 유효성을 검사합니다. | ||
* | ||
* @param request 검사할 요청 | ||
* @param index 요청의 인덱스 | ||
* @param errorMessages 오류 메시지를 저장할 리스트 | ||
* @return 유효하면 true, 그렇지 않으면 false | ||
*/ | ||
private boolean isValidRequest(CreateLogRequest request, int index, | ||
List<String> errorMessages) { | ||
Set<ConstraintViolation<CreateLogRequest>> violations = validator.validate(request); | ||
if (!violations.isEmpty()) { | ||
String message = violations.stream() | ||
.map(ConstraintViolation::getMessage) | ||
.collect(Collectors.joining(", ")); | ||
errorMessages.add("Request " + index + ": " + message); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* 요청 목록을 유효한 요청만으로 갱신합니다. | ||
* | ||
* @param requests 원본 요청 | ||
* @param validRequests 유효한 요청 목록 | ||
*/ | ||
private void updateRequestsList(List<CreateLogRequest> requests, | ||
List<CreateLogRequest> validRequests) { | ||
requests.clear(); | ||
requests.addAll(validRequests); | ||
} | ||
|
||
/** | ||
* 사용자 정의 제약 조건 위반을 추가합니다. | ||
* | ||
* @param context 제약 조건 컨텍스트 | ||
* @param message 제약 조건 위반 메시지 | ||
*/ | ||
private void addErrorMessage(ConstraintValidatorContext context, String message) { | ||
context.disableDefaultConstraintViolation(); | ||
context.buildConstraintViolationWithTemplate(message) | ||
.addConstraintViolation(); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
logbat/src/main/java/info/logbat/domain/log/presentation/validation/ValidLogRequests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package info.logbat.domain.log.presentation.validation; | ||
|
||
import jakarta.validation.Constraint; | ||
import jakarta.validation.Payload; | ||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
@Constraint(validatedBy = LogRequestsValidator.class) | ||
@Target({ElementType.PARAMETER}) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface ValidLogRequests { | ||
|
||
String message() default "유효하지 않은 로그 요청입니다."; | ||
|
||
Class<?>[] groups() default {}; | ||
|
||
Class<? extends Payload>[] payload() default {}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters