Skip to content

Fix/gateway dispatch admin route - #100

Merged
ION127 merged 17 commits into
mainfrom
fix/gateway-dispatch-admin-route
Jun 23, 2026
Merged

Fix/gateway dispatch admin route#100
ION127 merged 17 commits into
mainfrom
fix/gateway-dispatch-admin-route

Conversation

@ION127

@ION127 ION127 commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

ION127 added 15 commits June 19, 2026 16:29
- 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 (파티션 수와 일치)
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 적용

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a message lag check in CarStateConsumer to ignore Kafka messages older than 10 seconds, changes Redis GEO logging levels from INFO to DEBUG in RedisDispatchableCarProjection, and configures the Kafka consumer's auto-offset-reset to latest in application.yml. The reviewer pointed out a potential issue where a missing or invalid Kafka timestamp header could cause listener failures or incorrect message discarding, and recommended making the timestamp header optional and validating it before performing the lag check.

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.

Comment on lines +28 to +34
@Header(KafkaHeaders.RECEIVED_TIMESTAMP) producedAt: Long = System.currentTimeMillis(),
) {
val lagMs = System.currentTimeMillis() - producedAt
if (lagMs > MAX_MESSAGE_LAG_MS) {
log.warn("랙 초과 메시지 무시: carId={}, lag={}ms", message.carId, lagMs)
return
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Issue: Potential Message Drop or Listener Failure due to Missing/Invalid Kafka Timestamp

  1. Listener Failure on Missing Header: By default, @Header has required = true. If a Kafka message is received without a timestamp header (e.g., from older clients, misconfigured topics, or certain test environments), Spring Kafka will throw a ListenerExecutionFailedException and fail to process the message.
  2. Incorrect Message Discarding on Invalid Timestamp: If the timestamp is present but invalid/negative (e.g., -1 which represents RecordBatch.NO_TIMESTAMP in Kafka), System.currentTimeMillis() - producedAt will result in a very large positive number (approximately equal to the current epoch time). This will exceed MAX_MESSAGE_LAG_MS and cause the message to be silently and incorrectly ignored.

Recommendation

Make the producedAt header optional (required = false), use a nullable Long? type defaulting to null, and perform the lag check only if a valid positive timestamp is present.

        @Header(name = KafkaHeaders.RECEIVED_TIMESTAMP, required = false) producedAt: Long? = null,
    ) {
        if (producedAt != null && producedAt > 0) {
            val lagMs = System.currentTimeMillis() - producedAt
            if (lagMs > MAX_MESSAGE_LAG_MS) {
                log.warn("랙 초과 메시지 무시: carId={}, lag={}ms", message.carId, lagMs)
                return
            }
        }

@ION127
ION127 merged commit c830ffc into main Jun 23, 2026
7 checks passed
@ION127
ION127 deleted the fix/gateway-dispatch-admin-route branch June 23, 2026 02:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant