Command

class Command<C : Any> @InternalWowApi constructor(val id: String, val requestId: String, val ref: AggregateRef, val body: C, val expectedVersion: Int? = null, val scope: Scope = Scope.NONE, val headers: Map<String, String> = emptyMap(), val causation: Causation? = null, val operator: Operator? = null, val wait: WaitPlan = WaitPlan.DEFAULT, val caller: Caller? = null)

An admitted command: who it targets and what it asks, with every fact decided once at admission and read-only afterwards.

requestId makes the command idempotent within its tenant and aggregate type: a second command with the same request id, to an aggregate of the same type, is never decided again; one to an aggregate of another type is another request. expectedVersion, when set, is the version the caller believes the aggregate is at.

scope and headers are what admission learned about the request: the caller's owner and space (from the principal) and the request facts it chose to carry, such as the calling application. A decide function reads them through DecideScope.command. The headers are written into the committed event stream, so admission carries only request facts here; what serves only delivery, such as a trace id, travels as transport metadata instead.

causation links the command to the chain it belongs to; a command a user sends directly has none.

operator is whose name the command and what it commits are recorded in: admission takes it from the caller (me.ahoo.wow.api.caller.Caller.toOperator), null for an anonymous one; a command a saga derives, a compensation and a scheduled command keep the root command's.

wait is what the caller waits for before it is answered, by default until the snapshot holds the commit. It stays on the node that took the command: only a wait context travels with it.

caller is who sent it, as admission resolved them, acting in the tenant and scope the command names: the aggregate's access policy compares its claims with the aggregate's access attributes before and after deciding. It is Wow's own, never recorded: not in the stream, its headers, its operator or the audit. It travels with the command to the node that decides it, through the cluster channel and the command topics. A command no caller sent has none: a derived one (causation), one an older node relayed, or one a producer wrote on a command topic without one.

Fields may be added: admission builds a command, and the test DSL builds one for a test; the constructor is internal to Wow.

Constructors

Link copied to clipboard
constructor(id: String, requestId: String, ref: AggregateRef, body: C, expectedVersion: Int? = null, scope: Scope = Scope.NONE, headers: Map<String, String> = emptyMap(), causation: Causation? = null, operator: Operator? = null, wait: WaitPlan = WaitPlan.DEFAULT, caller: Caller? = null)

Properties

Link copied to clipboard
val body: C
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
val id: String
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard
Link copied to clipboard

Which time of a schedule this command was sent for, read from its headers; null when it was not sent by a schedule. Read once, when the command is built.

Link copied to clipboard
Link copied to clipboard

Functions

Link copied to clipboard
fun copyWith(id: String = this.id, requestId: String = this.requestId, ref: AggregateRef = this.ref, body: C = this.body, expectedVersion: Int? = this.expectedVersion, scope: Scope = this.scope, headers: Map<String, String> = this.headers, causation: Causation? = this.causation, operator: Operator? = this.operator, wait: WaitPlan = this.wait, caller: Caller? = this.caller): Command<C>

This Command with the given fields replaced: Wow's own copy, left out of the ABI.

Link copied to clipboard
open operator override fun equals(other: Any?): Boolean
Link copied to clipboard
open override fun hashCode(): Int
Link copied to clipboard
open override fun toString(): String