parkedRoutes

fun parkedRoutes(ops: ParkedOps, manifest: Manifest, authorizer: CommandAuthorizer? = null, callerResolver: CallerResolver = CallerResolver.ANONYMOUS, options: WowHttpOptions = WowHttpOptions()): RouterFunction<ServerResponse>

The operator's routes over a node's parked entries, under OpsPaths.PARKED:

  • GET /wow/ops/parked?subscription=&after=&limit=: a page of entries, by subscription and aggregate, with the cursor of the next page (next, passed back as after);

  • GET /wow/ops/parked/{subscription}/{context}/{aggregate}/{tenant}/{id}: one entry, of the subscription {subscription} names as the configuration keys it, <context>.<name> (SubscriptionId.key), on the aggregate {context}.{aggregate};

  • POST …/retry and POST …/skip: Retry and Skip, 200 when this node ran it (the entry resolved or still parked), 202 when it was left for the owner of the entry's partition. The body {"failedAt": <epoch ms>} names the parking the operator saw (the entry's failedAt): an entry parked at another time since, resolved and parked again, is refused as 409 wow.ledger.stale, as the ops context's RetryParked and SkipParked are. A skip requires it (400 without), since it discards what was parked; a retry may leave it out and acts on the current parking, since it only handles the parked streams again;

  • POST …/mark-recoverable ({"recoverable": "recoverable" | "unrecoverable" | "unknown"}) and POST …/apply-retry-spec ({"maxRetries": 5, "initialBackoff": "1m", "claimTtl": "2m"}, each duration written as the ops context's ApplyRetrySpec and the configuration write one, 500ms, 1h 30m or PT3M; a member left out keeps the value the entry is retried by now): 9.x's MarkRecoverable and ApplyRetrySpec, answering the entry.

An action's outcome (resolved, parked or requested) and the entry's recoverable, request and status are written, and recoverable read, by their wire names (WireNames), as every Wow enumeration on the wire; the failure ledger stores them as it always has.

An entry that is not parked is a 404. Every route authenticates the caller with callerResolver (401 otherwise), and keeps it in the tenants it reaches (TenantPolicy.reaches): a caller that may not act across scopes lists only its tenant's entries, which the ledger filters, and an entry of another tenant is a 404 to it, as one that is not parked. The four actions are then authorized by authorizer as the system commands OpsCommands names on the parked aggregate (a CommandAction without creation, in the caller's scope), so a CoSec policy guards them as it guards a command, and CoSec's WebFilter can guard the routes by their paths too; without an authorizer every action is refused (403 wow.auth.forbidden), never allowed by default. The reads are authorized the same way, as wow.ledger.Read (OpsPaths.READ) on each entry's aggregate, since an entry shows its failure's message: a listing leaves out the entries the caller may not read, and without an authorizer both reads are refused too. Errors are problems as on the other public routes, a store that is unavailable wow.storage.unavailable with Retry-After.