EventCodec

class EventCodec(mapper: JsonMapper = DEFAULT_MAPPER)

Turns events into what the log stores, and back. Events are named by the model, never by class name, so renaming or moving a class does not orphan its history. States go into and come out of snapshots the same way.

The default mapper is Wow's state mapper (StateJson.mapper, of me.ahoo.wow.spi.json.WowJson's configuration), which keeps every JSON number exact: an untyped value reads a decimal as a java.math.BigDecimal. It also fills a mutable state's read-only collections in place, and reads sets and maps back in the order they were written.

Constructors

Link copied to clipboard
constructor(mapper: JsonMapper = DEFAULT_MAPPER)

Properties

Link copied to clipboard

The sizes of the states this codec writes and reads, which a state cache weighs them by.

Functions

Link copied to clipboard
fun accessAfter(model: AggregateModel<*>, stream: EventStreamRecord, stateText: String): Map<String, Any?>

The declared access attributes after stream, a stream of model that left the state stateText: the stream's own when it holds model's current ones (a stamp may have given it later ones, which are still the aggregate's), else those of the state, decoded: a stream not stamped, or stamped before model declared what it declares now.

Link copied to clipboard
fun accessOf(model: AggregateModel<*>, state: Any): Map<String, Any?>

The declared access attributes of state, a state of model (AggregateModel.accessOf), in their stored form (AccessValues): an enum by the JSON name this codec writes it under. Empty when model declares none, without reading state.

Link copied to clipboard
fun commandText(command: Any): String

command as JSON: the body of a scheduled command, read back by its type when it is due.

Link copied to clipboard
fun current(model: AggregateModel<*>, record: EventRecord): EventRecord?

record as model reads it now: under its type's current name, at its current revision, its payload upgraded as decode upgrades it, but left a JSON text rather than bound to the class; null when model retired its name. A record of a name model does not know, or of a revision newer than its own, is left as stored.

Link copied to clipboard
fun decode(model: AggregateModel<*>, record: EventRecord): Any

The event record holds, read as model's current schema of its type: a record of an older revision goes through the type's upgrades one revision at a time, as a tree that keeps its numbers exact, and is then read as a record of the current revision is; a record named by a former name is still found. A record of a retired event fails, as one of a name the model does not know: skip it (decodeUnlessRetired).

Link copied to clipboard
fun decodeEvents(model: AggregateModel<*>, records: List<EventRecord>): List<Any>

The events records hold, in order, as decode reads them, without those model retired.

Link copied to clipboard
fun <S : Any> decodeState(model: AggregateModel<S>, text: String): S

The state text of a snapshot, read as model's state class: a Jackson exception when it does not parse, an IllegalArgumentException when the state read does not write back as the same JSON. A state that silently dropped what it could not take back (a read-only property Jackson does not fill) would decide on lost data; a computed property writes back the same and passes.

Link copied to clipboard
fun <T : Any> decodeTree(tree: JsonNode, type: Class<T>): T

tree read as a type: a state or an event another context published, into the subscriber's own class, with no model of the publisher's aggregate to check it against.

Link copied to clipboard

The event record holds, as decode reads it, or null when model retired its name (AggregateModel.isRetired): a retired record is skipped, never decoded.

Link copied to clipboard
fun encode(model: AggregateModel<*>, event: Any): EventRecord

event as a record of model.

Link copied to clipboard
fun <S : Any> snapshotOf(model: AggregateModel<S>, ref: AggregateRef, state: S, version: Int, scope: Scope, firstEventTime: Long, lastEventTime: Long, deleted: Boolean = false, operator: Operator? = null, firstOperator: Operator? = null, schedules: Map<String, ScheduleRule> = emptyMap()): SnapshotRecord

The snapshot of state, which folds ref's event streams up to version; scope is the aggregate's, the scope of the last of them, and firstEventTime and lastEventTime are the commit times of the first and the last. deleted and schedules are the aggregate's after them, evolved by the lifecycle and schedule events; a state the kernel loaded holds them (CachedState). operator and firstOperator are the operators of the last and the first of them.

fun snapshotOf(model: AggregateModel<*>, ref: AggregateRef, stateText: String, version: Int, scope: Scope, firstEventTime: Long, lastEventTime: Long, deleted: Boolean = false, operator: Operator? = null, firstOperator: Operator? = null, schedules: Map<String, ScheduleRule> = emptyMap(), access: Map<String, Any?>): SnapshotRecord

The snapshot of a state this codec already serialized as stateText: the shared state taken when the stream at version committed, so it is not serialized again, and access its declared access attributes in their stored form (accessOf, accessAfter). The rest is as for the snapshot of a state object.

Link copied to clipboard

Identifies the schema of model's state as this codec's mapper serializes it (StateJson.fingerprint): a snapshot written under another fingerprint is not read back; the state is replayed from the log instead (03-log-and-snapshot.md §3). Computed once per state class.

Link copied to clipboard
fun stateText(state: Any): String

state as text, to tell whether something changed it, and as a snapshot holds it; its length is measured.

Link copied to clipboard
fun stateTree(state: Any): JsonNode

state as a tree of the JSON stateText writes: a copy, keeping every number exact.