Skip to content

Feat(#21): RabbitMQ 기반 스미싱 분석 요청 Consumer 구현 - #25

Merged
pearseona merged 6 commits into
developfrom
feat/21-consume-analysis-request
Jul 28, 2026
Merged

Feat(#21): RabbitMQ 기반 스미싱 분석 요청 Consumer 구현#25
pearseona merged 6 commits into
developfrom
feat/21-consume-analysis-request

Conversation

@pearseona

@pearseona pearseona commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

📝 개요

Spring에서 RabbitMQ로 발행한 문자 분석 요청을 FastAPI가 소비하고, 기존 스미싱 분석 파이프라인으로 전달하도록 구현했습니다.

🔗 관련 이슈

🎯 주요 변경 사항

  • RabbitMQ 연결 및 분석 요청 Queue 구독 구현
  • Spring 분석 요청 이벤트 스키마와 유효성 검증 추가
  • 수신 이벤트를 기존 SmishingAnalysisService와 연결
  • ACK, reject 및 1회 재시도 처리 추가
  • FastAPI Lifespan에 Consumer 시작·종료 연결
  • RabbitMQ 설정 및 Docker 환경변수 구성 추가
  • 이벤트, Handler, Consumer 및 Lifespan 테스트 추가

✅ PR 체크리스트

  • 관련 이슈를 연결했습니다.
  • 구현 범위와 변경 이유를 설명했습니다.
  • 로컬 테스트(uvicorn 구동 또는 테스트 코드)를 통과했습니다.
  • API 변경 사항이 있다면 Swagger / API 명세에 반영했습니다.
  • 민감 정보(API Key, 시크릿 키 등)가 코드·로그·테스트 데이터에 포함되지 않았습니다.
  • 프론트엔드 또는 메인 백엔드(Spring)에 영향을 주는 응답 스키마 또는 Enum 변경이 있다면 팀에 공유했습니다.
  • 병합(Merge) 전 작업 브랜치를 삭제하지 않았습니다.

Summary by CodeRabbit

  • New Features
    • Added RabbitMQ integration for receiving and processing analysis requests.
    • Added configurable messaging settings, queue management, and optional consumer startup.
    • Added structured validation for incoming analysis events, including source, identifiers, timestamps, and message content.
    • Added controlled retry handling for failed processing attempts.
  • Bug Fixes
    • Improved message acknowledgment and rejection behavior to prevent repeated failures.
  • Tests
    • Added coverage for messaging, validation, processing, lifecycle, cleanup, and error scenarios.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@pearseona, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 38 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 16a5035d-fa18-4f96-9421-0fe4d3b760c6

📥 Commits

Reviewing files that changed from the base of the PR and between 9760e71 and 8dbfc04.

📒 Files selected for processing (5)
  • app/infrastructure/rabbitmq/consumer.py
  • app/main.py
  • docker-compose.yml
  • tests/infrastructure/rabbitmq/test_consumer.py
  • tests/infrastructure/rabbitmq/test_lifecycle.py
📝 Walkthrough

Walkthrough

Adds a RabbitMQ-backed analysis request consumer with strict event schemas, durable topology setup, retry handling, pipeline integration, configurable FastAPI startup/shutdown management, Compose settings, dependency updates, and comprehensive tests.

Changes

RabbitMQ analysis processing

Layer / File(s) Summary
Event contract and RabbitMQ settings
app/core/config.py, app/infrastructure/rabbitmq/schemas.py, tests/infrastructure/rabbitmq/test_schemas.py
Adds environment-backed RabbitMQ settings and strict versioned analysis request schemas with validation for identifiers, timestamps, content, enums, and unknown fields.
Connection and topology setup
app/infrastructure/rabbitmq/connection.py, requirements.txt, docker-compose.yml, tests/infrastructure/rabbitmq/test_connection.py
Adds robust RabbitMQ connection management, QoS configuration, durable exchange/queue declaration and binding, cleanup behavior, and Compose wiring.
Consumer retry and pipeline handling
app/infrastructure/rabbitmq/consumer.py, app/infrastructure/rabbitmq/handler.py, tests/infrastructure/rabbitmq/test_consumer.py, tests/infrastructure/rabbitmq/test_handler.py
Consumes validated events, invokes the analysis pipeline, acknowledges successful messages, retries first failures, rejects redelivered failures, and verifies logging behavior.
Application lifecycle wiring
app/main.py, tests/analysis/test_router.py, tests/infrastructure/rabbitmq/test_lifecycle.py
Adds optional RabbitMQ consumer startup and shutdown to the FastAPI lifespan and disables the consumer explicitly in API tests.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RabbitMQ
  participant AnalysisRequestConsumer
  participant AnalysisRequestHandler
  participant SmishingAnalysisService
  RabbitMQ->>AnalysisRequestConsumer: Deliver analysis request
  AnalysisRequestConsumer->>AnalysisRequestHandler: Handle validated event
  AnalysisRequestHandler->>SmishingAnalysisService: Analyze message content
  SmishingAnalysisService-->>AnalysisRequestHandler: Return analysis result
  AnalysisRequestHandler-->>AnalysisRequestConsumer: Report success or failure
  AnalysisRequestConsumer->>RabbitMQ: Acknowledge, retry, or reject
Loading

Possibly related issues

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 47.06% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: implementing a RabbitMQ-based consumer for smishing analysis requests.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/21-consume-analysis-request

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
app/infrastructure/rabbitmq/schemas.py (1)

18-26: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Consider bounding content length.

sender and clientMessageId are capped, but content is unbounded and flows directly into the analysis pipeline (likely an LLM call). A malformed or oversized message could trigger expensive or failing downstream calls.

♻️ Proposed bound
-    content: str
+    content: str = Field(max_length=5000)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/infrastructure/rabbitmq/schemas.py` around lines 18 - 26, Update the
AnalysisRequestedPayload.content field to enforce an explicit maximum length
using Pydantic Field, matching the bounded validation style already used for
sender and clientMessageId. Choose the appropriate limit for analysis input and
preserve content’s required-string behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/infrastructure/rabbitmq/consumer.py`:
- Around line 108-140: The _handle_processing_failure method incorrectly treats
message.redelivered as proof that this handler already retried the message.
Replace that check with application-level retry-attempt state, increment or
record the attempt when requeueing, and reject only after the configured single
retry has actually been attempted; preserve the existing logging and nack/reject
outcomes.

In `@app/main.py`:
- Around line 57-60: Update the shutdown flow around consumer.stop() so
rabbitmq.close() executes in a finally block even when consumer shutdown raises.
Keep the consumer None check and ensure the RabbitMQ connection is always
closed.

In `@docker-compose.yml`:
- Around line 12-18: Add a fallback default to the RABBITMQ_URL environment
entry in the Compose configuration, using the same local RabbitMQ URL expected
by config.py when RABBITMQ_DOCKER_URL is unset. Preserve the existing override
behavior when RABBITMQ_DOCKER_URL is provided.

---

Nitpick comments:
In `@app/infrastructure/rabbitmq/schemas.py`:
- Around line 18-26: Update the AnalysisRequestedPayload.content field to
enforce an explicit maximum length using Pydantic Field, matching the bounded
validation style already used for sender and clientMessageId. Choose the
appropriate limit for analysis input and preserve content’s required-string
behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ae0d14fa-84b3-4229-a26f-e8394fa962b1

📥 Commits

Reviewing files that changed from the base of the PR and between 009162c and 9760e71.

📒 Files selected for processing (16)
  • app/core/config.py
  • app/infrastructure/rabbitmq/__init__.py
  • app/infrastructure/rabbitmq/connection.py
  • app/infrastructure/rabbitmq/consumer.py
  • app/infrastructure/rabbitmq/handler.py
  • app/infrastructure/rabbitmq/schemas.py
  • app/main.py
  • docker-compose.yml
  • requirements.txt
  • tests/analysis/test_router.py
  • tests/infrastructure/rabbitmq/__init__.py
  • tests/infrastructure/rabbitmq/test_connection.py
  • tests/infrastructure/rabbitmq/test_consumer.py
  • tests/infrastructure/rabbitmq/test_handler.py
  • tests/infrastructure/rabbitmq/test_lifecycle.py
  • tests/infrastructure/rabbitmq/test_schemas.py

Comment thread app/infrastructure/rabbitmq/consumer.py Outdated
Comment thread app/main.py Outdated
Comment thread docker-compose.yml
@pearseona pearseona self-assigned this Jul 28, 2026
@pearseona pearseona added the feat New feature or functional additions to the application label Jul 28, 2026
@pearseona
pearseona merged commit 2d2a60c into develop Jul 28, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat New feature or functional additions to the application

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant