AggregateModelBuilder

class AggregateModelBuilder<S : Any>(val type: AggregateType, val stateType: Class<S>)

The Kotlin DSL of an aggregate model. Command and event types are named context.aggregate.Name after their class's @Name, else its simple name, unless a name is given: the name the compiler gives them, so a model written by hand stores what the Manifest says. A name given that disagrees with the class's @Name, or an aggregate named otherwise than its @AggregateRoot state class, fails here: the log would hold names the Manifest does not.

Constructors

Link copied to clipboard
constructor(type: AggregateType, stateType: Class<S>)

Properties

Link copied to clipboard
Link copied to clipboard

Functions

Link copied to clipboard
fun <V : Any> access(attribute: AccessAttribute.Multiple<S, V>, read: (S) -> Collection<V>)

Declares the access attribute attribute, several values of the state that read gives, as access of one value does.

fun <V : Any> access(attribute: AccessAttribute.Single<S, V>, read: (S) -> V?)

Declares the access attribute attribute, one value of the state that read gives, null for none: a fact the aggregate's access policies compare with a caller's claims (AggregateModel.accessOf). read is a pure, cheap function of the state, derived on each commit: it reads the state alone, does no I/O, reads no clock and draws no random number. A state member marked @Access calls it in a generated model, a value class unwrapped.

Link copied to clipboard
fun addAggregateId(commandType: Class<*>, read: (Any) -> String?)

Reads the aggregate id of a command of commandType from its body; see the reified overload.

Link copied to clipboard
fun addAlias(typeClass: Class<*>, former: String)
Link copied to clipboard
fun addCommitEvolver(eventClass: Class<*>, name: String, revision: Int, evolver: (S, Any, EventStream) -> S)
Link copied to clipboard
fun addDecider(commandType: Class<*>, name: String, decider: DecideFunction<S>)

Adds the decide function of commandType. A decide function of a lifecycle command overrides the kernel's, to add domain rules to it: it decides the command's own lifecycle event (AggregateDeleted for DeleteAggregate) beside the aggregate's own events, NoOp or a rejection, and deciding another lifecycle event fails the command (LifecycleOverride). An override of RestoreAggregate is decided on a deleted aggregate as the kernel's is, so it takes no onDeleted. The schedule commands (wow.schedule.*) are the kernel's alone: a decide function schedules with DecideScope.schedule.

Link copied to clipboard
fun addEvolver(eventClass: Class<*>, name: String, revision: Int, evolver: (S, Any) -> S)
Link copied to clipboard
fun addMounted(commandType: Class<*>, name: String)
Link copied to clipboard
fun addUpgrade(eventClass: Class<*>, from: Int, upgrade: EventUpgrade)
Link copied to clipboard
fun after(include: Set<Class<*>> = emptySet(), exclude: Set<Class<*>> = emptySet(), produces: Set<Class<*>>? = null, after: DecideScope.(S, Any) -> List<Any>)

An after hook for every command that is one of include and none of exclude: its events follow the command's own in the same stream. An empty include is every command of the model's own decide functions, not the system commands the kernel decides (lifecycle and wow.schedule): a hook runs after one of those only when include names it. With produces, the events it may return, any other fails the command (AfterFunction.produces).

Link copied to clipboard
fun afterBlocking(include: Set<Class<*>> = emptySet(), exclude: Set<Class<*>> = emptySet(), produces: Set<Class<*>>? = null, after: suspend DecideScope.(S, Any) -> List<Any>)

An after hook that blocks its thread (@Blocking): it runs on a virtual thread; see after.

Link copied to clipboard
fun afterSuspending(include: Set<Class<*>> = emptySet(), exclude: Set<Class<*>> = emptySet(), produces: Set<Class<*>>? = null, after: suspend DecideScope.(S, Any) -> List<Any>)

A suspending after hook; see after.

Link copied to clipboard
inline fun <reified C : Any> aggregateId(noinline read: (C) -> String?)

Reads the id of the aggregate a command of type C acts on from its body, as its @AggregateId property holds it: its request need not name its aggregate. read gives null for a creation that leaves it out, which then gets an id. C is a command this model decides.

Link copied to clipboard
inline fun <reified T : Any> alias(former: String)

A former name of the command or event type T: records of an event stored under it are read as T, and a request id recorded with a command under it is a retry of T.

Link copied to clipboard
Link copied to clipboard
inline fun <reified C : Any> decide(creation: Creation = Creation.NONE, name: String = defaultName(C::class.java), onDeleted: Boolean = false, produces: Set<Class<*>>? = null, noinline decide: DecideScope.(S, C) -> Decision)

Decides commands of type C, named name, with a plain function: the fast path. An onDeleted command is decided on a deleted aggregate too (DecideFunction.onDeleted). With produces, the events it may decide, a decision holding another fails the command (DecideFunction.produces).

Link copied to clipboard
inline fun <reified C : Any> decideBlocking(creation: Creation = Creation.NONE, name: String = defaultName(C::class.java), onDeleted: Boolean = false, produces: Set<Class<*>>? = null, noinline decide: suspend DecideScope.(S, C) -> Decision)

Decides commands of type C, named name, with a function that blocks its thread (@Blocking), such as one calling JDBC: the kernel runs it on its blocking dispatcher, a virtual thread, so it does not hold a worker thread.

fun <C : Any> decideBlocking(commandType: Class<C>, creation: Creation = Creation.NONE, name: String = defaultName(commandType), onDeleted: Boolean = false, produces: Set<Class<*>>? = null, decide: suspend DecideScope.(S, C) -> Decision)

Decides commands of commandType with a function that blocks its thread; see the reified overload.

Link copied to clipboard
inline fun <reified C : Any> decideSuspending(creation: Creation = Creation.NONE, name: String = defaultName(C::class.java), onDeleted: Boolean = false, produces: Set<Class<*>>? = null, noinline decide: suspend DecideScope.(S, C) -> Decision)

Decides commands of type C, named name, with a suspending function, for decisions that read other systems.

Link copied to clipboard
fun defaultName(typeClass: Class<*>): String

The name of a command or event type declared without one: context.aggregate.SimpleName, or the system name of a lifecycle command or event (Lifecycle).

Link copied to clipboard
inline fun <reified E : Any> evolve(name: String = defaultName(E::class.java), revision: Int = 1, noinline evolve: S.(E) -> Unit)

Evolves the state by changing it in place: the default, concise form.

inline fun <reified E : Any> evolve(name: String = defaultName(E::class.java), revision: Int = 1, noinline evolve: S.(E, EventStream) -> Unit)

Evolves the state in place, reading the commit the event belongs to (EventStream: its time, operator and version, as the log records them), which a rebuild reads again alike.

Link copied to clipboard
inline fun <reified E : Any> evolveTo(name: String = defaultName(E::class.java), revision: Int = 1, noinline evolve: (S, E) -> S)

Evolves the state by returning a new one, for immutable states.

inline fun <reified E : Any> evolveTo(name: String = defaultName(E::class.java), revision: Int = 1, noinline evolve: (S, E, EventStream) -> S)

Evolves an immutable state by returning a new one, reading the commit the event belongs to.

Link copied to clipboard
fun id(source: AggregateIdSource)

Where the aggregate's id comes from: AggregateIdSource.ASSIGNED unless this is called. @AggregateRoot(idSource) calls it in a generated model.

Link copied to clipboard
fun initial(factory: (AggregateRef) -> S)

The state of an aggregate that has no event yet.

Link copied to clipboard
fun lifecycle(vararg commands: Class<*>)

Enables only the lifecycle commands commands; all are enabled unless this is called, and calling it with none disables them. A command disabled is not handled, as any command the model does not decide; the lifecycle events stay readable. A decide function declared for a lifecycle command enables it too.

Link copied to clipboard
inline fun <reified C : Any> mount(name: String = defaultName(C::class.java))

Mounts commands of type C, named name, under this aggregate's routes without deciding them: a transformer of the service turns each into a command that is decided.

Link copied to clipboard
fun ownership(ownership: Ownership)

Who the aggregate belongs to besides its tenant: Ownership.OWNER unless this is called. @AggregateRoot(ownership) calls it in a generated model.

Link copied to clipboard
fun retired(vararg names: String)

Retires the events stored under names (9.x DroppedEvent): the aggregate no longer has them, and their records left in the log are skipped, never decoded. Each is a full stored name, context.aggregate.Event; none may name a current event or command type, or be one of their former names. @AggregateRoot(retiredEvents) calls it in a generated model.

Link copied to clipboard
fun stateRevision(revision: Int)

The revision of the state's structure its snapshots are written at: 1 unless this is called. @AggregateRoot(stateRevision) calls it in a generated model.

Link copied to clipboard
inline fun <reified E : Any> upgrade(from: Int, upgrade: EventUpgrade)

Reads revision from payloads of event E as revision from + 1 ones.