Files
git.stella-ops.org/src/Scheduler/StellaOps.Scheduler.WebService/docs/SCHED-WEB-21-001-GRAPH-APIS.md
2025-10-28 15:10:40 +02:00

138 lines
4.3 KiB
Markdown

# SCHED-WEB-21-001 — Graph Job APIs
> Status: 2025-10-26 — **Complete** (developer preview)
Minimal API endpoints for Cartographer orchestration live under `/graphs`. Authentication now relies on Authority-issued bearer tokens carrying `graph:*` scopes. For development scenarios you can disable `Scheduler:Authority:Enabled` and continue using legacy headers:
- `X-Tenant-Id`: tenant identifier (matches Scheduler Models `tenantId`).
- `X-Scopes`: space-delimited scopes. `graph:write` is required for write operations, `graph:read` for queries.
Example configuration (`appsettings.json` or environment overrides):
```jsonc
{
"Scheduler": {
"Authority": {
"Enabled": true,
"Issuer": "https://authority.stella-ops.local",
"Audiences": [ "api://scheduler" ],
"RequiredScopes": [ "graph:read", "graph:write" ]
},
"Events": {
"GraphJobs": {
"Enabled": true
}
},
"Cartographer": {
"Webhook": {
"Enabled": true,
"Endpoint": "https://cartographer.stella-ops.local/hooks/graph/completed",
"ApiKeyHeader": "X-StellaOps-Webhook-Key",
"ApiKey": "change-me",
"TimeoutSeconds": 10
}
}
}
}
```
## Endpoints
### `POST /graphs/build`
Creates a `GraphBuildJob` in `pending` state.
Request body:
```jsonc
{
"sbomId": "sbom_alpha",
"sbomVersionId": "sbom_alpha_v1",
"sbomDigest": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"trigger": "sbom-version",
"metadata": {
"sbomEventId": "sbom_evt_20251026"
}
}
```
Response: `201 Created`
```jsonc
{
"id": "gbj_018dc2f5902147e2b7f2ea05f5de1f3f",
"tenantId": "tenant-alpha",
"kind": "build",
"status": "pending",
"payload": {
"schemaVersion": "scheduler.graph-build-job@1",
"id": "gbj_018dc2f5902147e2b7f2ea05f5de1f3f",
"tenantId": "tenant-alpha",
"sbomId": "sbom_alpha",
"sbomVersionId": "sbom_alpha_v1",
"sbomDigest": "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"status": "pending",
"trigger": "sbom-version",
"createdAt": "2025-10-26T12:00:00Z",
"metadata": {
"sbomeventid": "sbom_evt_20251026"
}
}
}
```
### `POST /graphs/overlays`
Creates a `GraphOverlayJob` in `pending` state. Include optional `buildJobId` and `subjects` filters.
### `POST /graphs/hooks/completed`
Webhook invoked by Scheduler Worker once Cartographer finishes a build/overlay job. Requires `graph:write`.
```jsonc
{
"jobId": "goj_018dc2f5929b4f5c88ad1e43d0ab3b90",
"jobType": "Overlay",
"status": "Completed", // Completed | Failed | Cancelled
"occurredAt": "2025-10-26T12:02:45Z",
"correlationId": "corr-123",
"resultUri": "oras://cartographer/offline/tenant-alpha/graph_snap_20251026"
}
```
The endpoint advances the job through `running → terminal` transitions via `GraphJobStateMachine`, captures the latest correlation identifier, and stores the optional `resultUri` in metadata for downstream exports.
### `GET /graphs/overlays/lag`
Returns per-tenant overlay lag metrics (counts, min/max/average lag seconds, and last five completions with correlation IDs + result URIs). Requires `graph:read`.
### `GET /graphs/jobs`
Returns a combined `GraphJobCollection`. Query parameters:
| Parameter | Description |
|-----------|-------------|
| `type` | Optional filter (`build` or `overlay`). |
| `status` | Optional filter using `GraphJobStatus`. |
| `limit` | Maximum number of results (default 50, max 200). |
Response example:
```jsonc
{
"jobs": [
{
"id": "gbj_018dc2f5902147e2b7f2ea05f5de1f3f",
"tenantId": "tenant-alpha",
"kind": "build",
"status": "pending",
"payload": { /* graph build job */ }
}
]
}
```
## Integration tests
`StellaOps.Scheduler.WebService.Tests/GraphJobEndpointTests.cs` covers scope enforcement and the build-list happy path using the in-memory store. Future work should add overlay coverage once Cartographer adapters are available.
## Known gaps / TODO
- Persist jobs to Scheduler storage and publish `scheduler.graph.job.completed@1` events + outbound webhook to Cartographer (see new `SCHED-WEB-21-004`).
- Extend `GET /graphs/jobs` with pagination cursors shared with Cartographer/Console.