Skip to content

Push all GW origin artifacts to CP on connection#2757

Merged
thivindu merged 1 commit into
wso2:mainfrom
thivindu:dp-to-cp-bug-fixes
Jul 21, 2026
Merged

Push all GW origin artifacts to CP on connection#2757
thivindu merged 1 commit into
wso2:mainfrom
thivindu:dp-to-cp-bug-fixes

Conversation

@thivindu

Copy link
Copy Markdown
Contributor

Purpose

When a gateway reconnects to a different control plane, to a control plane whose database was purged/restored, or re-registers as a different gateway, the AI artifacts it created (REST APIs, LLM Providers, LLM Provider Templates, LLM Proxies, MCP Proxies) were never re-synced. Once an artifact had synced successfully its cp_sync_status latched to success, and the reconnect push only ever offered pending/failed artifacts — so the new/empty control plane never received them. The gateway keeps no record of which control plane it synced to, so "success" effectively meant "synced once, to someone."

This PR makes the gateway repopulate any control plane it connects to, while keeping already-synced control planes free of duplicate deployments.

Approach

  1. Full reconcile on connect (data plane). On every (re)connect the gateway now re-offers all of its gateway-origin artifacts, not just the incomplete ones. This is what actually lands artifacts on a new, purged, or re-registered target.
  2. Idempotent deployment write (control plane). To keep the full reconcile from piling up duplicate deployment records on a control plane that already has the artifact, each push now carries a stable per-deployment revision (derived from the deployment time). The control plane records it in the deployment's existing metadata and, on a re-push that matches the current revision, recognizes the replay — it keeps the artifact and its gateway association but skips inserting a duplicate deployment. Genuinely distinct deployments carry distinct revisions and are always recorded; a different gateway never matches (the check is per gateway); and last-in-wins conflict resolution is unchanged, so re-pushes never overwrite control-plane-side edits.

The revision is stored as a string in metadata, so it round-trips exactly regardless of timestamp column precision across SQLite/PostgreSQL/SQL Server.

Changes

Gateway (data plane)

  • pkg/storage: new GetGatewayOriginArtifactsForSync() returning all gateway-origin artifacts regardless of cp_sync_status.
  • pkg/controlplane/sync.go: the (re)connect reconcile now pushes that full set.
  • pkg/utils/api_utils.go: the import request now carries a deploymentRevision in its properties.

Control plane (platform-api)

  • internal/repository/deployment.go: new per-gateway GetLatestDeploymentRevision(...).
  • internal/service/artifact_import.go: writeDeployment now dedupes replay re-pushes on the revision and stamps it into deployment metadata.

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b3c374f9-6da5-4961-898f-c7c41bbb1bb8

📥 Commits

Reviewing files that changed from the base of the PR and between 7969135 and 16f773e.

📒 Files selected for processing (19)
  • docs/ai-workspace/bottom-up-ai-artifact-deployment-guide.md
  • gateway/gateway-controller/pkg/api/handlers/handlers_test.go
  • gateway/gateway-controller/pkg/controlplane/api_deleted_test.go
  • gateway/gateway-controller/pkg/controlplane/push_artifacts_test.go
  • gateway/gateway-controller/pkg/controlplane/sync.go
  • gateway/gateway-controller/pkg/secrets/service_test.go
  • gateway/gateway-controller/pkg/storage/interface.go
  • gateway/gateway-controller/pkg/storage/llm_provider_template_artifacts_test.go
  • gateway/gateway-controller/pkg/storage/sql_store.go
  • gateway/gateway-controller/pkg/subscriptionxds/subscription_snapshot_test.go
  • gateway/gateway-controller/pkg/utils/api_utils.go
  • gateway/gateway-controller/pkg/utils/api_utils_test.go
  • gateway/gateway-controller/pkg/utils/mock_db_test.go
  • platform-api/internal/repository/api_deployments_test.go
  • platform-api/internal/repository/deployment.go
  • platform-api/internal/repository/interfaces.go
  • platform-api/internal/service/artifact_import.go
  • platform-api/internal/service/artifact_import_test.go
  • platform-api/internal/utils/import_artifacts.go

📝 Walkthrough

Walkthrough

Changes

Artifact reconciliation

Layer / File(s) Summary
Gateway artifact selection
gateway/gateway-controller/pkg/storage/..., gateway/gateway-controller/pkg/*/
Storage now returns all gateway-originated artifact metadata, including previously synced artifacts, with updated test doubles and coverage.
Gateway full reconciliation and revision propagation
gateway/gateway-controller/pkg/controlplane/..., gateway/gateway-controller/pkg/utils/..., docs/ai-workspace/...
Reconnect synchronization re-pushes all gateway artifacts, and deployable requests include a timestamp-derived deployment revision.
Revision-aware deployment import
platform-api/internal/repository/..., platform-api/internal/service/..., platform-api/internal/utils/...
Imports compare revisions per artifact and gateway, avoid duplicate deployment records for replayed revisions, and retain gateway associations.

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

Sequence Diagram(s)

sequenceDiagram
  participant Gateway
  participant ControlPlaneSync
  participant ArtifactStorage
  participant ArtifactImporter
  participant DeploymentRepository
  Gateway->>ControlPlaneSync: Reconnect and start full reconciliation
  ControlPlaneSync->>ArtifactStorage: Get all gateway-originated artifacts
  ArtifactStorage-->>ControlPlaneSync: Artifact metadata
  ControlPlaneSync->>ArtifactImporter: Import artifact with deploymentRevision
  ArtifactImporter->>DeploymentRepository: Read latest gateway-scoped revision
  DeploymentRepository-->>ArtifactImporter: Stored revision
  ArtifactImporter->>ArtifactImporter: Skip duplicate or create deployment
Loading

Suggested reviewers: renuka-fernando, chamilaadhi, malinthaprasan, pubudu538, ashera96

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers purpose and approach, but most template sections are missing, including goals, tests, security, and test environment. Add the missing template sections: Goals, User stories, Documentation, Automation tests, Security checks, Samples, Related PRs, and Test environment.
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: pushing all gateway-origin artifacts to the control plane on connect.
Linked Issues check ✅ Passed The PR addresses #2659 by re-syncing gateway-created artifacts on reconnect so previously synced LLM providers are offered again.
Out of Scope Changes check ✅ Passed No clearly unrelated code changes stand out; the additions support full reconnect sync and replay deduplication for the requested behavior.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain modules listed in go.work or their selected dependencies"


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.

@thivindu
thivindu merged commit 25a0178 into wso2:main Jul 21, 2026
15 checks passed
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.

[Bug]: LLM Providers sync only once from bottom-up approach

2 participants