Fix/gateway dispatch admin route - #102
Conversation
- CompletableFuture.runAsync 제출 실패 시 outer try-catch 추가 (EventService, RelocationController) - RelocationController: RejectedExecutionException 발생 시 503 반환 - RestClient.Builder 빈 주입 방식으로 변경 (RelocationServiceClient, ControlServiceClient) - 좌표 키 'lng' → 'lon' 통일 (RelocationTriggerService) - DispatchServiceApplicationTests: Redis/Kafka 자동설정 제외 방식으로 변경 - SaveWeightServiceApplicationTests: test yml 기반으로 단순화
- DispatchServiceApplicationTests: spring.autoconfigure.exclude 제거 → test yml이 Redis/Kafka 커버 - RestClient.Builder.clone() 추가 (RelocationServiceClient, ControlServiceClient) — 공유 빌더 변경 부작용 방지 - RelocationTriggerService: 좌표 쌍 처리 chunked(2) 방식으로 가독성 개선
- KafkaConsumerConfig: concurrency를 KAFKA_DISPATCH_CONCURRENCY 환경변수로 제어 (기본값 4) - application.yml: staleness-threshold-seconds, kafka.dispatch.concurrency 환경변수 바인딩 추가 - 기본값: staleness 300초(5분), concurrency 4 (파티션 수와 일치)
…fix/gemini-review-only
block-internal-api에서 /dispatch/vehicles/*/active 제거 후 인증 없는 전용 어드민 라우트(dispatch-service-admin-vehicles-active)를 추가하여 baro-admin의 배차 정보 조회 복구
- TokenService: JWT어드민 role claim 포함 - AuthService: 토큰 발급 시 user.role 전달 - JwtAuthenticationGatewayFilterFactory: requiredRole Config 추가, FORBIDDEN 처리 - GatewayAuthenticationHeaders: X-Authenticated-Role 헤더 추가 - application.yml: dispatch/vehicles/*/active에 JwtAuthentication=ADMIN 적용
…fix/gateway-dispatch-admin-route
…fix/gateway-dispatch-admin-route
There was a problem hiding this comment.
Code Review
This pull request introduces a new public endpoint /dispatch/stands to retrieve taxi stands, adding the corresponding JPA entity, repository, controller, and gateway routing configuration. The feedback highlights a critical performance and security concern regarding the use of an unpaginated findAll() query on this endpoint, which could lead to memory exhaustion or Denial of Service (DoS) under load. It is recommended to implement pagination using Spring Data's Pageable to limit the number of records returned.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| @GetMapping | ||
| fun getStands(): List<TaxiStandResponse> = | ||
| taxiStandRepository.findAll().map { | ||
| TaxiStandResponse( | ||
| id = it.id, | ||
| longitude = it.longitude, | ||
| latitude = it.latitude, | ||
| name = it.name, | ||
| district = it.district, | ||
| ) | ||
| } |
There was a problem hiding this comment.
Exposing an unpaginated findAll() query on a public endpoint poses a significant performance and security risk. If the taxi_stands table grows large, this endpoint could cause high memory usage, database connection exhaustion, or OutOfMemoryError under load. Since this route is public and lacks authentication/rate-limiting, it is also highly vulnerable to Denial of Service (DoS) attacks.
Please implement pagination using Spring Data's Pageable to limit the number of records returned per request.
| @GetMapping | |
| fun getStands(): List<TaxiStandResponse> = | |
| taxiStandRepository.findAll().map { | |
| TaxiStandResponse( | |
| id = it.id, | |
| longitude = it.longitude, | |
| latitude = it.latitude, | |
| name = it.name, | |
| district = it.district, | |
| ) | |
| } | |
| @GetMapping | |
| fun getStands(pageable: org.springframework.data.domain.Pageable): org.springframework.data.domain.Page<TaxiStandResponse> = | |
| taxiStandRepository.findAll(pageable).map { | |
| TaxiStandResponse( | |
| id = it.id, | |
| longitude = it.longitude, | |
| latitude = it.latitude, | |
| name = it.name, | |
| district = it.district, | |
| ) | |
| } |
findAll() → findAll(pageable) 변경, @PageableDefault(size=500)으로 최대 반환 건수 제한. DoS 및 메모리 exhaustion 방지.
No description provided.