Skip to content

Multiple data store support - #202

Merged
brucetony merged 15 commits into
mainfrom
197-refactor-kong
Jul 29, 2026
Merged

Multiple data store support#202
brucetony merged 15 commits into
mainfrom
197-refactor-kong

Conversation

@brucetony

@brucetony brucetony commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features
    • Added background cleanup that automatically removes stale Kong analysis consumers after terminal states, with configurable interval and start/stop lifecycle.
    • Added S3-based datastore creation plus tag-based project↔datastore linking, type-aware listing, and datastore-specific health checks.
  • Bug Fixes
    • Corrected S3 vs MinIO service reporting across storage and improved authentication header behavior on failures.
    • Improved handling of missing Kong consumers during analysis termination.
  • Refactor
    • Strengthened Kong resolution and error messages using tags and standardized HTTP exception details.

@brucetony brucetony linked an issue Jul 29, 2026 that may be closed by this pull request
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c8d96260-c299-47d0-a08d-3c792c7d842a

📥 Commits

Reviewing files that changed from the base of the PR and between 8865ae5 and c2a489b.

📒 Files selected for processing (8)
  • hub_adapter/__init__.py
  • hub_adapter/conf.py
  • hub_adapter/errors.py
  • hub_adapter/integration_test.py
  • hub_adapter/maintenance.py
  • hub_adapter/routers/kong.py
  • tests/router_tests/test_kong.py
  • tests/test_maintenance.py
🚧 Files skipped from review as they are similar to previous changes (7)
  • hub_adapter/conf.py
  • hub_adapter/integration_test.py
  • tests/test_maintenance.py
  • tests/router_tests/test_kong.py
  • hub_adapter/maintenance.py
  • hub_adapter/errors.py
  • hub_adapter/routers/kong.py

📝 Walkthrough

Walkthrough

This PR refactors Kong datastore and project integration around tags, adds S3 configuration and health probing, standardizes Kong errors, and introduces configurable background cleanup for stale analysis consumers.

Changes

Kong identity and error contracts

Layer / File(s) Summary
Tag, validation, settings, response, and error primitives
hub_adapter/utils.py, hub_adapter/conf.py, hub_adapter/errors.py, hub_adapter/schemas/kong.py, hub_adapter/constants.py
Adds Kong identity helpers, validation, cleanup settings, S3 configuration, UnlinkResponse, service tags, and specialized errors.
Supporting tests and logging
tests/test_utils.py, tests/test_errors.py, hub_adapter/__init__.py
Tests identity and error behavior and enables JSON console formatting.

Datastore services and links

Layer / File(s) Summary
Datastore and project-link lifecycle
hub_adapter/routers/kong.py, hub_adapter/schemas/kong.py
Adds tag-based datastore lookup and filtering, S3 gateway plugin setup, cascade deletion, project linking, plugin/probe rollback, and revised unlink responses.
Fixtures, integration cleanup, and endpoint contracts
hub_adapter/integration_test.py, tests/constants.py, tests/router_tests/*, hub_adapter/routers/storage.py
Updates Kong fixtures, route expectations, datastore/link tests, integration cleanup, and S3 terminology.

Project, analysis, and probing flow

Layer / File(s) Summary
Project and analysis routing
hub_adapter/routers/kong.py, hub_adapter/routers/meta.py, hub_adapter/autostart.py
Uses project, datastore, and analysis tags for route and consumer resolution, updates analysis termination behavior, and reads valid projects from route tags.
Health and connection probing
hub_adapter/routers/kong.py, tests/router_tests/test_kong.py
Adds health-consumer reuse or creation, datastore-specific probe paths, FHIR metadata probing, UUID validation, and explicit upstream errors.
Route and lifecycle tests
tests/router_tests/routes.py, tests/router_tests/test_meta.py, tests/test_autostart.py
Updates endpoint contracts and verifies termination and tag-based project discovery behavior.

Consumer cleanup lifecycle

Layer / File(s) Summary
Reaper, manager, and application integration
hub_adapter/maintenance.py, hub_adapter/server.py, hub_adapter/routers/node.py, hub_adapter/conf.py, hub_adapter/schemas/logs.py
Adds terminal-state consumer reaping, configurable polling, lifecycle start/stop/restart handling, application wiring, and cleanup events.
Cleanup validation
tests/test_maintenance.py
Tests grace periods, history management, fetch/delete failures, stale-consumer pruning, and manager lifecycle behavior.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ServerLifespan
  participant KongCleanupManager
  participant KongConsumerReaper
  participant Hub
  participant Kong

  ServerLifespan->>KongCleanupManager: start cleanup loop
  KongCleanupManager->>KongConsumerReaper: run sweep
  KongConsumerReaper->>Kong: list analysis consumers
  KongConsumerReaper->>Hub: fetch analysis execution status
  KongConsumerReaper->>Kong: delete terminal analysis consumers
  ServerLifespan->>KongCleanupManager: stop cleanup loop
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 55.21% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main theme of the PR and reflects the expanded multi-datastore/Kong support.
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.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 197-refactor-kong

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.

@brucetony brucetony changed the title Support multiple data stores per analysis feat(kong)!: multiple data store support Jul 29, 2026
@brucetony brucetony changed the title feat(kong)!: multiple data store support Multiple data store support Jul 29, 2026

@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: 9

🧹 Nitpick comments (8)
hub_adapter/maintenance.py (2)

65-77: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Sync Kong client call blocks the event loop. get_analyses is a synchronous function performing HTTP I/O via kong_admin_client; calling it directly inside this coroutine stalls the whole event loop for the duration of the Kong request (including timeouts). Consider await run_in_threadpool(get_analyses, self.settings).

🤖 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 `@hub_adapter/maintenance.py` around lines 65 - 77, Update the coroutine’s
get_analyses call to execute via await run_in_threadpool(get_analyses,
self.settings), preserving the existing ApiException/HTTPException handling and
deleted return path.

33-37: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Constant name doesn't match its use. EXECUTED_AFTER_RUNNING_GRACE is applied only to failed/stopped analyses that were previously seen executing (Line 131); executed deletes immediately with no grace. Something like TERMINAL_AFTER_EXECUTING_GRACE would read truer.

🤖 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 `@hub_adapter/maintenance.py` around lines 33 - 37, Rename
EXECUTED_AFTER_RUNNING_GRACE to a name that reflects its use for failed or
stopped analyses previously observed as executing, such as
TERMINAL_AFTER_EXECUTING_GRACE, and update all references including the logic
near the terminal-status handling. Keep the immediate deletion behavior for
executed analyses unchanged.
hub_adapter/server.py (1)

52-52: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Inconsistent tag value formatting. Only the PodOrc entry uses .value; every other entry in tags_metadata passes the ServiceTag member. Since ServiceTag is a str Enum both serialize the same, so either revert this or apply .value to all entries for consistency.

🤖 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 `@hub_adapter/server.py` at line 52, Standardize the tag value representation
in the tags_metadata definition: update the PodOrc entry using
ServiceTag.PODORC.value to match the other ServiceTag entries, or consistently
convert every entry to .value. Preserve the existing tag values and choose one
representation throughout tags_metadata.
hub_adapter/routers/kong.py (2)

537-537: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Mutable default for protocols.

Ruff B006. Use None and fall back to DEFAULT_PROTOCOLS (already defined on Line 88) inside the body, matching link_project_to_datastore.

♻️ Proposed change
-    ] = ["http"],
+    ] = None,

and pass protocols=protocols or DEFAULT_PROTOCOLS to link_project_to_datastore.

🤖 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 `@hub_adapter/routers/kong.py` at line 537, Update the function parameter
defining protocols to use None instead of the mutable list default, then inside
the function pass protocols or DEFAULT_PROTOCOLS to link_project_to_datastore,
matching the existing link_project_to_datastore pattern.

Source: Linters/SAST tools


763-763: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Stringify the ACL group for consistency.

ensure_health_consumer (Line 837) and the route ACL (Line 502) both use str(project_id). Here the raw value is passed, so a uuid.UUID caller would serialize to a group that doesn't match the route's allow-list.

♻️ Proposed change
-                group=project_id,
+                group=str(project_id),
🤖 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 `@hub_adapter/routers/kong.py` at line 763, Update the ACL group argument in
the relevant ensure_health_consumer call to pass str(project_id), matching the
route ACL and other ensure_health_consumer usage so UUID project IDs serialize
consistently.
hub_adapter/utils.py (1)

152-153: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Comment contradicts the rule it documents.

The regex deliberately excludes , and / (they'd corrupt tag filters and link paths). The current wording reads as if they were allowed.

📝 Suggested wording
-# Kong can use ',' and '/' in tags
+# Kong treats ',' as a tag-filter separator and '/' is meaningful in route paths, so both are excluded
 _NAME_PATTERN = re.compile(r"^[a-zA-Z0-9._~-]+$")
🤖 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 `@hub_adapter/utils.py` around lines 152 - 153, Update the comment above
_NAME_PATTERN to state that Kong cannot safely use commas or slashes in tags
because they would corrupt tag filters and link paths; keep the regex unchanged.
tests/router_tests/test_meta.py (1)

187-187: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove leftover commented-out assertion.

Dead code artifact from editing; can be dropped.

🤖 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 `@tests/router_tests/test_meta.py` at line 187, Remove the leftover
commented-out assertion from the test at the indicated location in
tests/router_tests/test_meta.py, leaving the surrounding test logic unchanged.
hub_adapter/errors.py (1)

155-302: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use SERVICE for the detail service key.

The imported SERVICE constant already resolves to "service", so these repeated "service": "Kong" entries can use SERVICE: "Kong" instead of hardcoding the literal key.

♻️ Example fix pattern
-                "service": "Kong",
+                SERVICE: "Kong",

Apply consistently to all new classes in this range.

🤖 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 `@hub_adapter/errors.py` around lines 155 - 302, Update every detail dictionary
in the new error classes from KongDataStoreLinkedError through KongUpstreamError
to use the imported SERVICE constant as the service key instead of the hardcoded
"service" literal, preserving the existing "Kong" value and all other fields.
🤖 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 `@hub_adapter/conf.py`:
- Around line 18-25: Constrain the interval field in KongCleanupSettings to
accept only positive values, rejecting zero and negative values during model
validation. Preserve the optional configuration and existing default while
ensuring all KongCleanupManager.start() and router restart paths receive a valid
sleep interval.

In `@hub_adapter/errors.py`:
- Around line 290-300: The KongUpstreamError constructor must stop exposing raw
upstream response text and must not always attach WWW-Authenticate. Sanitize and
truncate the message before storing it in detail, and only include the
authentication header for status codes or responses that genuinely require a
bearer challenge; otherwise omit it while preserving the existing error details.

In `@hub_adapter/integration_test.py`:
- Line 205: Update the exception tuple in the cleanup handler to reference the
imported HTTP client alias httpx2 instead of the undefined httpx name,
preserving handling for HTTPException and HTTP status errors without masking the
original cleanup failure.

In `@hub_adapter/maintenance.py`:
- Around line 190-201: Move KongConsumerReaper construction from before the loop
into the while loop’s try block so initialization failures are handled by the
existing cleanup error path. Ensure KongConsumerReaper() exceptions produce the
kong_cleanup.error log and do not terminate _run_cleanup without retrying
subsequent cleanup cycles.
- Around line 141-152: Update _delete to catch both HTTPException and
ApiException from delete_analysis, matching the exception handling used by
sweep(). Keep the existing kong_cleanup.delete_error logging and False return
behavior so Kong-level failures do not escape and abort subsequent cleanup work.
- Around line 173-188: Enforce a positive minimum for kong_cleanup.interval in
the UserSettings/Pydantic settings model, and ensure KongCleanupManager.start
uses a safe validated value when loading persisted settings during reloads or
restarts. Prevent interval 0 or other invalid persisted values from reaching
asyncio.sleep or creating a tight cleanup loop.

In `@hub_adapter/routers/kong.py`:
- Around line 460-481: Update the route creation flow around CreateRouteRequest
to leave name unset instead of using route_name, avoiding global name collisions
and optional-service-name failures. Import and use link_path(project_id, svc.id)
for the sole paths entry so each project/datastore link receives a
project-specific route path, while preserving the existing tags and other route
settings.
- Around line 507-517: Extend the route-creation flow around
create_plugin_for_route so failures from either key-auth or ACL plugin creation
delete the newly created route before propagating the exception. Reuse the
existing Kong route deletion logic and preserve the probe_connection rollback
behavior, ensuring no route remains when plugin setup is incomplete.

In `@tests/test_maintenance.py`:
- Around line 152-155: Update every patch target in
test_delete_success_clears_history and the other tests in this file to remove
the stray “.py” segment, changing references from
hub_adapter.maintenance.py.<symbol> to hub_adapter.maintenance.<symbol>. Apply
this consistently to all patch decorators without changing the patched symbols
or test behavior.

---

Nitpick comments:
In `@hub_adapter/errors.py`:
- Around line 155-302: Update every detail dictionary in the new error classes
from KongDataStoreLinkedError through KongUpstreamError to use the imported
SERVICE constant as the service key instead of the hardcoded "service" literal,
preserving the existing "Kong" value and all other fields.

In `@hub_adapter/maintenance.py`:
- Around line 65-77: Update the coroutine’s get_analyses call to execute via
await run_in_threadpool(get_analyses, self.settings), preserving the existing
ApiException/HTTPException handling and deleted return path.
- Around line 33-37: Rename EXECUTED_AFTER_RUNNING_GRACE to a name that reflects
its use for failed or stopped analyses previously observed as executing, such as
TERMINAL_AFTER_EXECUTING_GRACE, and update all references including the logic
near the terminal-status handling. Keep the immediate deletion behavior for
executed analyses unchanged.

In `@hub_adapter/routers/kong.py`:
- Line 537: Update the function parameter defining protocols to use None instead
of the mutable list default, then inside the function pass protocols or
DEFAULT_PROTOCOLS to link_project_to_datastore, matching the existing
link_project_to_datastore pattern.
- Line 763: Update the ACL group argument in the relevant ensure_health_consumer
call to pass str(project_id), matching the route ACL and other
ensure_health_consumer usage so UUID project IDs serialize consistently.

In `@hub_adapter/server.py`:
- Line 52: Standardize the tag value representation in the tags_metadata
definition: update the PodOrc entry using ServiceTag.PODORC.value to match the
other ServiceTag entries, or consistently convert every entry to .value.
Preserve the existing tag values and choose one representation throughout
tags_metadata.

In `@hub_adapter/utils.py`:
- Around line 152-153: Update the comment above _NAME_PATTERN to state that Kong
cannot safely use commas or slashes in tags because they would corrupt tag
filters and link paths; keep the regex unchanged.

In `@tests/router_tests/test_meta.py`:
- Line 187: Remove the leftover commented-out assertion from the test at the
indicated location in tests/router_tests/test_meta.py, leaving the surrounding
test logic unchanged.
🪄 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: 33c44365-ff2e-4fe8-8339-79930e3a0a0e

📥 Commits

Reviewing files that changed from the base of the PR and between f16c7f5 and 8865ae5.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock
📒 Files selected for processing (23)
  • hub_adapter/autostart.py
  • hub_adapter/conf.py
  • hub_adapter/constants.py
  • hub_adapter/errors.py
  • hub_adapter/integration_test.py
  • hub_adapter/maintenance.py
  • hub_adapter/routers/kong.py
  • hub_adapter/routers/meta.py
  • hub_adapter/routers/node.py
  • hub_adapter/routers/storage.py
  • hub_adapter/schemas/kong.py
  • hub_adapter/schemas/logs.py
  • hub_adapter/server.py
  • hub_adapter/utils.py
  • pyproject.toml
  • tests/constants.py
  • tests/router_tests/routes.py
  • tests/router_tests/test_kong.py
  • tests/router_tests/test_meta.py
  • tests/test_autostart.py
  • tests/test_errors.py
  • tests/test_maintenance.py
  • tests/test_utils.py

Comment thread hub_adapter/conf.py
Comment thread hub_adapter/errors.py
Comment thread hub_adapter/integration_test.py Outdated
Comment thread hub_adapter/maintenance.py
Comment thread hub_adapter/maintenance.py
Comment thread hub_adapter/maintenance.py
Comment thread hub_adapter/routers/kong.py Outdated
Comment thread hub_adapter/routers/kong.py Outdated
Comment thread tests/test_maintenance.py
@brucetony
brucetony merged commit f0898ec into main Jul 29, 2026
7 checks passed
@brucetony
brucetony deleted the 197-refactor-kong branch July 29, 2026 12:24
@coderabbitai coderabbitai Bot mentioned this pull request Jul 30, 2026
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.

Refactor kong

1 participant