Occurrent 0.4.0 is now available. The release contains several new features an upgrade to CloudEvent SDK 2.0.0.RC1. The SDK now contains a PojoCloudEventData
type that makes DocumentCloudEventData
, that was introduced in the previous release of Occurrent, superfluous. Another really important thing is that
the cloud event extensions added automatically by Occurrent (for stream id and stream version) has been renamed from streamId
and streamVersion
to streamid
and streamversion
.
This is because according to the cloud event specification, it’s not allowed to have attributes named with camelcase (must be lowercase).
Here are all changes:
- Upgraded to Kotlin 1.4.20
- Upgraded to cloud events 2.0.0.RC1
- Breaking change! The attributes added by the Occurrent cloud event extension has been renamed from “streamId” and “streamVersion” to “streamid” and “streamversion” to comply with the specification.
- Added optimized support for
io.cloudevents.core.data.PojoCloudEventData
. Occurrent can convertPojoCloudEventData
that containsMap<String, Object>
andString
efficiently. - Breaking change! Removed
org.occurrent.eventstore.mongodb.cloudevent.DocumentCloudEventData
since it’s no longer needed after the CloudEvent SDK has introducedPojoCloudEventData
. UsePojoCloudEventData
and pass the document or preferably, map, to it. - Removed the
org.occurrent:application-service-blocking-kotlin
module, useorg.occurrent:application-service-blocking
instead. The Kotlin extension functions are provided with that module instead. -
Added partial function application support for Kotlin. Depend on module
org.occurrent:command-composition
and import extension functions fromorg.occurrent.application.composition.command.partial
. This means that instead of doing:val playerId = ... applicationService.execute(gameId) { events -> Uno.play(events, Timestamp.now(), playerId, DigitCard(Three, Blue)) }
you can do:
val playerId = ... applicationService.execute(gameId, Uno::play.partial(Timestamp.now(), playerId, DigitCard(Three, Blue)))
-
Added command composition support for Kotlin. Depend on module
org.occurrent:command-composition
and import extension functions fromorg.occurrent.application.composition.command.*
. This means that you can compose two functions like this using theandThen
(infix) function:val numberOfPlayers = 4 val timestamp = Timestamp.now() applicationService.execute(gameId, Uno::start.partial(gameId, timestamp, numberOfPlayers) andThen Uno::play.partial(timestamp, player1, DigitCard(Three, Blue)))
In the example above,
start
andplay
will be composed together into a single “command” that will be executed atomically.If you have more than two commands, it could be easier to use the
composeCommand
function instead of repeatingandThen
:val numberOfPlayers = 4 val timestamp = Timestamp.now() applicationService.execute(gameId, composeCommands( Uno::start.partial(gameId, timestamp, numberOfPlayers), Uno::play.partial(timestamp, player1, DigitCard(Three, Blue)), Uno::play.partial(timestamp, player2, DigitCard(Four, Blue)) ) )
- Added Kotlin extension functions to the blocking event store. They make it easier to write, read and query the event store with Kotlin
Sequence
’s. Import extension functions from packageorg.occurrent.eventstore.api.blocking
. -
Added support for deleting events from event store using a
org.occurrent.filter.Filter
. For example:eventStoreOperations.delete(streamId("myStream").and(streamVersion(lte(19L)));
This will delete all events in stream “myStream” that has a version less than or equal to 19. This is useful if you implement “closing the books” or certain types of snapshots, and don’t need the old events anymore. This has been implemented for all MongoDB event stores (both blocking and reactive) but not for the InMemory event store.