Eagerly initializing the archiving Cypher statements required for the new archiving event completion mode breaks our compatibility with Spring Boot 3.2 as that depends on a Cypher library version not containing the exists(…) operator yet. We now lazily instantiate those statements.
We now explicitly set the completion date property of newly created event publications to null. The copying data manipulation statements now properly copy all properties of the publication notes into the archive.
We now use two separate entity types for archived and non-archived event publications to rpevent hibernate hickups when inserting an instance of a subtype with he same id.
We now support an archiving completion mode that copies the entry to be completed into a dedicated archive to retain the completed event publications but also keep the main publication store small for more efficient data access.
Co-authored-by: Oliver Drotbohm <oliver.drotbohm@broadcom.com>
In case no ObjectMapper bean instance is present, we now fall back to creating a default one to render a JSON byte array. This is useful in case Jackson is on the class path but not necessarily the JacksonObjectMapperBuilder, which is located in spring-web.
DefaultEventPublicationRegistry.processIncompletePublications(…) now actively unregisters the publication from being considered in progress after completion (either successful or failed). While CompletionRegisteringAdvisor should take care of that on the target listeners we now leave the publications in progress in consistent state independent of the actual target being invoked. Decrease log level of the failed listener invocation as it's not unusual for the listener to fail.
Improved PublicationsInProgress by switching to a concurrent map internally to avoid ConcurrentModificationExceptions in case of multiple threads.
We now support SpEL expressions in routing targets for events to be externalized. Introduced a BrokerRouting.getTarget(Object) overload to allow access to the event object in the SpEL expression. To support those, event externalizers will have to call that method where they previously called ….getTarget().
EventExternalizationConfiguration now exposes a ….headers(Class<T>, Function<T, Map<String, Object>) to allow to define a function that extracts headers from the event that are supposed to added to the message to be sent out. The Kafka and AMQP implementations have been augmented to consider those configurations.
Furthermore, if the mapping step prior to the externalization creates a Spring Message<?>, we add routing information as fallback and send it out as is.
Switch Oracle schema definition to make the serialized event column non null. Adapt test cases to always contain some content for the serialized event.
Original pull request: GH-868.
We now use the ability to override transaction propagation introduce for GH-858 to tweak the application module listener declaration on DelegatingEventListener so that we do not create a transaction by default. This avoids a database connection being acquired as the listener is very likely to interact with a non-transactional resource anyway.
Actively reject attempts to use a dedicated schema with SQL Server. Prevent schema reset being executed if no schema is used. Properly report exception during database name detection.
Original pull request: GH-808.
We now expose a spring.modulith.events.completion-mode property, defaulting the previous behavior to a value of UPDATE. The property can also be configured to DELETE, which will cause the persistence implementations to flip to removing the database entries for event publications instead of setting the completion date.
We now additionally guard the completion query by event and target identifier to also only apply to publications that have not been completed yet. This will allow databases to optimize the query plan to apply simple comparisons (the date being null) over complex comparisons (the event payload) to reduce the intermediate results to process further and thus improve performance.
DefaultEventPublicationRegistry now tracks the event publications currently in progress, so that the completion step can use the database identifier to issue an update statement solely based on that.