Aller au contenu principal

Multi-Gateway Orchestration

STOA's Control Plane orchestrates multiple API gateways through a unified Adapter pattern. Register any supported gateway, and the Control Plane handles API synchronization, policy enforcement, and consumer provisioning across all of them.

Architecture

Supported Gateways

GatewayTypeStorageAdmin APIAdapter Status
STOARust, axumIn-memoryREST (/admin/*)Full support
KongLua, OpenRestyDB-less YAMLREST (:8001)Full support
GraviteeJavaMongoDB + ESREST (:8083)Full support
webMethodsJavaElasticsearchREST (:5555)Full support (16/16 methods)

Adapter Interface

Every gateway adapter implements 16 abstract methods organized in 5 categories:

Lifecycle (3 methods)

MethodPurposeReturns
health_check()Verify gateway connectivityAdapterResult
connect()Initialize connection/sessionNone
disconnect()Clean up resourcesNone

API Management (3 methods)

MethodPurposeReturns
sync_api(api_spec, tenant_id)Create or update an API routeAdapterResult
delete_api(api_id)Remove an API routeAdapterResult
list_apis()List all managed APIslist[dict]

Policy Management (3 methods)

MethodPurposeReturns
upsert_policy(policy_spec)Create or update a policy (rate limit, CORS)AdapterResult
delete_policy(policy_id)Remove a policyAdapterResult
list_policies()List all managed policieslist[dict]

Consumer Management (3 methods)

MethodPurposeReturns
provision_application(app_spec)Register a consumer with credentialsAdapterResult
deprovision_application(app_id)Remove a consumerAdapterResult
list_applications()List all managed consumerslist[dict]

Extended (4 methods, gateway-specific)

MethodPurposeSupported By
upsert_auth_server(auth_spec)Configure OIDC providerwebMethods
upsert_strategy(strategy_spec)Set auth strategywebMethods
upsert_scope(scope_spec)Define OAuth scopeswebMethods
upsert_alias(alias_spec)Configure endpoint aliaswebMethods
apply_config(config_spec)Apply full configurationwebMethods
export_archive()Export gateway backupwebMethods

Unsupported methods return AdapterResult(success=False, error="Not supported by <gateway>").

AdapterResult

All adapter methods return a standardized result:

@dataclass
class AdapterResult:
success: bool
resource_id: str | None = None
data: dict | None = None
error: str | None = None

Gateway Registration

Register gateways via the Control Plane API or CRD:

Via API

Configure your environment

The examples below use environment variables. Set them for your STOA instance:

export STOA_API_URL="https://api.gostoa.dev"       # Replace with your domain
export STOA_AUTH_URL="https://auth.gostoa.dev" # Keycloak OIDC provider
export STOA_GATEWAY_URL="https://mcp.gostoa.dev" # MCP Gateway endpoint

Self-hosted? Replace gostoa.dev with your domain.

curl -X POST "${STOA_API_URL}/v1/gateways" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"name": "kong-production",
"display_name": "Kong Production (GRA)",
"gateway_type": "kong",
"base_url": "http://kong-admin:8001",
"environment": "prod",
"capabilities": ["rest", "rate_limiting"]
}'

Via CRD

apiVersion: gostoa.dev/v1alpha1
kind: GatewayInstance
metadata:
name: kong-production
namespace: stoa-system
spec:
displayName: Kong Production (GRA)
gatewayType: kong
environment: prod
baseUrl: http://kong-admin:8001
capabilities: [rest, rate_limiting]

Gateway Types

Valid gateway_type values:

TypeDescription
stoaSTOA Gateway (generic)
stoa_edge_mcpSTOA in edge-mcp mode
stoa_sidecarSTOA in sidecar mode
stoa_proxySTOA in proxy mode
stoa_shadowSTOA in shadow mode
kongKong (DB-less)
graviteeGravitee APIM v4
webmethodsSoftware AG webMethods
apigeeGoogle Apigee
aws_apigatewayAWS API Gateway

Per-Gateway Details

STOA Gateway (Rust)

AspectDetail
Admin APIPOST /admin/apis, POST /admin/policies, GET /admin/health
AuthBearer token (admin_api_token)
StorageIn-memory (Control Plane is source of truth)
Idempotencysync_api and upsert_policy are both upserts
Key behaviorAll state lost on restart; CP API re-syncs automatically
# Health check
curl "${STOA_GATEWAY_URL}/admin/health" \
-H "Authorization: Bearer ${ADMIN_TOKEN}"

Kong (DB-less)

AspectDetail
Admin APIGET /services, GET /plugins, POST /config
AuthKong-Admin-Token header
StorageDeclarative YAML via POST /config (atomic reload)
State patternRead current → merge changes → POST full config
Config version_format_version: "3.0" required

Kong DB-less mode makes the Admin API read-only for individual writes. All mutations follow the read-merge-post pattern:

1. GET /services + /plugins + /consumers → current state
2. Merge desired change (upsert by name/tag)
3. POST /config with full declarative payload → atomic reload

Gravitee (APIM v4)

AspectDetail
Management API/management/v2/environments/DEFAULT/apis
AuthBasic auth (configurable)
StorageMongoDB + Elasticsearch (full CRUD)
API lifecycleCREATED → PUBLISHED → STARTED → DEPLOYED
PlansRate limiting via Plans with flows (not standalone policies)

Gravitee APIs require explicit lifecycle transitions:

1. POST /apis (create, V4 definition)
2. POST /apis/{id}/_start (start)
3. POST /apis/{id}/deployments (deploy)

webMethods (Software AG)

AspectDetail
Admin API/rest/apigateway/*
AuthBasic auth (Administrator:manage)
StorageElasticsearch (internal)
Feature setFull 16/16 methods (most complete adapter)
OpenAPI importOnly 3.0.x supported (not 3.1.0)

webMethods is the most feature-complete adapter, supporting OIDC integration, endpoint aliases, configuration management, and full backup/export.

Sync Workflow

When you create or update an API in the Control Plane, it syncs to all bound gateways:

For multi-gateway setups, the Control Plane syncs to each bound gateway:

Adding a New Gateway Adapter

  1. Copy control-plane-api/src/adapters/template/ to adapters/<new_gateway>/
  2. Implement all 16 abstract methods in adapter.py
  3. Create spec translation functions in mappers.py
  4. Register in adapters/registry.py
  5. Add the type to the gateway_type_enum database migration
  6. Write tests (~30+ unit tests with mocked HTTP calls)

Adapter Contract Rules

  • All methods must be idempotent (calling twice produces the same result)
  • Return AdapterResult(success=False, error="...") for failures; never raise exceptions
  • Use httpx.AsyncClient for HTTP calls (async, connection pooling)
  • Log warnings for non-critical failures (e.g., plan not subscribable)

Troubleshooting

ProblemCauseFix
sync_api returns 404Gateway not registeredRegister via API or CRD first
Kong config reload failsInvalid service in payloadAll-or-nothing: one bad service breaks the reload
Gravitee API not reachableAPI not started/deployedRun the full lifecycle: create → plan → publish → deploy → start
webMethods import failsOpenAPI 3.1.0 specConvert to 3.0.3: sed 's/3.1.0/3.0.3/'
Adapter returns "Not supported"Extended method on non-webMethodsExpected; only webMethods supports all 16 methods