This repository was archived by the owner on Jul 4, 2025. It is now read-only.
Release 0.40.23 Spring Boot 3.2.*
Pre-release
Pre-release
What's Changed
- Release 0.40.23 by @cloudcreate-dk in #117
🚀 Release Highlights – v0.40.23
This release brings major improvements across observability, error handling, configuration, MongoDB integration, and internal architecture — now grouped for clarity.
🏢 Project Metadata
- Updated project
organizationto Trustworks - Updated project
organizationUrlto https://www.trustworks.dk
This will soon become the new home for the project
🧠 metrics
- Introduced the
MeasurementTakerAPI for pluggable performance tracking- Includes
LoggingMeasurementRecorderandMicrometerMeasurementRecorder
- Includes
- Added support for per-subsystem execution time thresholds via configuration
- Introduced:
RecordExecutionTimeCommandBusInterceptorRecordExecutionTimeDurableQueueInterceptorRecordExecutionTimeMessageHandlerInterceptorRecordExecutionTimeEventStoreInterceptor
- Logging can be configured for each interceptor with class-specific logger names
- Most new properties to control metrics collection under
essentials.metrics.*, others are underessentials.eventstore
📦 durable-queues
- Introduced
DurableQueueDeserializationException DefaultDurableQueueConsumer:- Immediately marks failed deserialization messages as Dead-Letter-Messages
- Supports new
HandleQueuedMessageinterceptor operation
- Updated:
PostgresqlDurableQueues.getNextMessageReadyForDeliveryMongoDurableQueues.getNextMessageReadyForDelivery
- Added
RecordExecutionTimeDurableQueueInterceptor - Expanded
DurableQueuesITto test dead-letter behavior on deserialization failure
🧰 eventstore-postgresql
- Introduced
EventStoreSubscriptionObserverinterface - Added
MeasurementEventStoreSubscriptionObserverfor trackingEventStoreSubscriptiondelivery duration DefaultEventStoreSubscriptionManagernow usesMeasurementEventStoreSubscriptionObserverby default- Added:
RecordExecutionTimeEventStoreInterceptorfor performance tracking
- Improved:
- Logging and exception description for
OptimisticAppendToStreamExceptionandAppendToStreamException PollEventStoreTaskpoll logic to adapt to publishing activity- Handling of
resolveBatchSizeForThisQueryedge case
- Logging and exception description for
🧱 eventsourced-aggregates
- Improved logging in
DefaultStatefulAggregateRepository- Changed default log level from
TRACEtoDEBUG
- Changed default log level from
🔐 Mongo fenced-locking
- Improved
MongoFencedLockStoragehandling ofTransactionExceptionandWriteConflictscenarios - Introduced
MongoUtil.isWriteConflictand reused it across:MongoFencedLockStorageMongoDurableQueues
- Adjusted
DBFencedLockManagerITfor improved reliability under concurrency and connectivity issues- Improved reconnection timing logic for stability
🛠 unit-of-work
UnitOfWorkFactoryandUnitOfWorkLifecycleCallbacknow useThrowableinstead ofExceptionfor broader rollback coverage- Unified error handling logic:
UnitOfWorkFactory.usingUnitOfWorknow aligns withUnitOfWorkFactory.withUnitOfWorkfor consistent rollback behavior
SpringTransactionAwareUnitOfWorkFactoryimproved to correctly handleTransactionSynchronization.STATUS_UNKNOWN
🔄 command-handling
- Introduced
RecordExecutionTimeCommandBusInterceptor - Default bean name changed from
commandBustoessentialsCommandBusforDurableLocalCommandBus - Improved bean configuration and auto-wiring consistency
📨 event-bus and messaging
- Introduced
RecordExecutionTimeMessageHandlerInterceptor - Default bean name changed from
eventBustoessentialsEventBusforEventBus - Improved
EventProcessorlogging - Introduced
InfrastructureLocalEventBusfor technical/internal events
⚙️spring-starters
- Added support for disabling
ReactiveHandlersBeanPostProcessorviaessentials.reactive-bean-post-processor-enabled ReactiveHandlersBeanPostProcessornow ignores:- Beans with
@AutoConfiguration - Beans with role
BeanDefinition.ROLE_INFRASTRUCTURE
- Beans with
🧬 Module: essentials-types & essentials-types-jackson
- Enhanced Jackson 2.18 compatibility:
AggregateType,EventName,EventType,CorrelationId,EventId,MessageId,SubscriberId,TenantIdCharSequenceType,CountryCode,CurrencyCode,EmailAddressInboxName,LockName,OutboxName,QueueEntryId,QueueName
- Improved documentation in both modules’
README.mdfiles
🧠 Module: shared
- Introduced:
QuadFunction: a generic 4-arg functional interfaceInvocationTracker: for tracking method execution viaPatternMatchingMethodInvokerFunctionalInterfaceLoggingNameResolver: for logging-friendly names from lambdas and method references
📚 Kotlin event-sourcing
- Added Kotlin doc examples to
GivenWhenThenScenario
📦 Dependency & Plugin Updates (All Modules)
- Upgraded core dependencies:
- Spring Framework, Reactor, Netty, SLF4J, Jackson, JUnit, Mockito, Testcontainers, Awaitility, JDBI
- Security: upgraded Tomcat to 10.1.39 to resolve CVE in 10.1.33 (included with Spring Boot 3.2.12)
- Maven Plugin upgrades:
maven-compiler-plugin,maven-surefire-plugin,dependency-check-maven, and more
Full Changelog: 0.40.22...0.40.23
All changes:
- Updated the project's
organizationandorganizationUrltoTrustworksandhttps://www.trustworks.dkas this will become the new home for the project - Updated 3rd party dependencies:
- spring-framework 6.1.18
- reactor 2023.0.16
- slf4j 2.0.17
- awaitility 4.3.0
- netty 4.1.119.Final
- junit 5.12.1
- testcontainers 1.20.6
- jdbi3 3.49.0
- jackson 2.18.3
- mockito 5.16.1
- logback 1.5.18
- tomcat 10.1.39 (Due to CVE in version 10.1.33 included by Spring Boot 3.2.12)
- Updated maven plugins:
- maven-project-info-reports-plugin 3.9.0
- maven-clean-plugin 3.4.1
- maven-install-plugin 3.1.4
- maven-deploy-plugin 3.1.4
- maven-failsafe-plugin / maven-surefire-plugin 3.5.3
- maven-compiler-plugin 3.14.0
- dependency-check-maven 12.1.1
- flatten-maven-plugin 1.7.0
- Added configuration of
MeasurementEventStoreSubscriptionObserverandRecordExecutionTimeEventStoreInterceptorwhich can be configured using these properties:-
# Event Store metrics configuration essentials.event-store.metrics.enabled=true essentials.event-store.metrics.thresholds.debug=25ms essentials.event-store.metrics.thresholds.info=200ms essentials.event-store.metrics.thresholds.warn=500ms essentials.event-store.metrics.thresholds.error=5000ms essentials.event-store.subscription-manager.metrics.enabled=true essentials.event-store.subscription-manager.metrics.thresholds.debug=25ms essentials.event-store.subscription-manager.metrics.thresholds.info=200ms essentials.event-store.subscription-manager.metrics.thresholds.warn=500ms essentials.event-store.subscription-manager.metrics.thresholds.error=5000ms - and logging can be configured using
<logger name="dk.cloudcreate.essentials.components.eventsourced.eventstore.postgresql.observability.micrometer.MeasurementEventStoreSubscriptionObserver" level="DEBUG"/> <logger name="dk.cloudcreate.essentials.components.eventsourced.eventstore.postgresql.interceptor.micrometer.RecordExecutionTimeEventStoreInterceptor" level="DEBUG"/>
-
- Introduced
essentials.reactive-bean-post-processor-enabledto disable theReactiveHandlersBeanPostProcessor - Changed default bean name:
essentialsCommandBusinstead ofcommandBusforDurableLocalCommandBusessentialsEventBusinstead ofeventBusforEventBus
- Auto configuration of
RecordExecutionTimeMessageHandlerInterceptor,RecordExecutionTimeCommandBusInterceptorandRecordExecutionTimeDurableQueueInterceptorfor essentials metrics collection and logging- Performance tracking is not enabled per default
- To enable tracking and controlling logging you can use
and logging levels using:# Durable Queues metrics configuration essentials.metrics.durable-queues.enabled=true essentials.metrics.durable-queues.thresholds.debug=25ms essentials.metrics.durable-queues.thresholds.info=200ms essentials.metrics.durable-queues.thresholds.warn=500ms essentials.metrics.durable-queues.thresholds.error=5000ms # Command Bus metrics configuration essentials.metrics.command-bus.enabled=true essentials.metrics.command-bus.thresholds.debug=25ms essentials.metrics.command-bus.thresholds.info=200ms essentials.metrics.command-bus.thresholds.warn=500ms essentials.metrics.command-bus.thresholds.error=5000ms # Message Handler metrics configuration essentials.metrics.message-handler.enabled=true essentials.metrics.message-handler.thresholds.debug=25ms essentials.metrics.message-handler.thresholds.info=200ms essentials.metrics.message-handler.thresholds.warn=500ms essentials.metrics.message-handler.thresholds.error=5000ms
<logger name="dk.cloudcreate.essentials.components.foundation.interceptor.micrometer.RecordExecutionTimeCommandBusInterceptor" level="DEBUG"/> <logger name="dk.cloudcreate.essentials.components.foundation.interceptor.micrometer.RecordExecutionTimeDurableQueueInterceptor" level="DEBUG"/> <logger name="dk.cloudcreate.essentials.components.foundation.interceptor.micrometer.RecordExecutionTimeMessageHandlerInterceptor" level="DEBUG"/>
- Expanded
DurableQueuesITto verifyjson_deserialization_problem_causes_message_to_be_marked_as_dead_letter_message - Expanded
PostgresqlDurableQueues.getNextMessageReadyForDeliveryandMongoDurableQueues.getNextMessageReadyForDeliveryto handleDurableQueueDeserializationExceptionand immediately mark the failed message as a Dead-Letter-Message - Introduced the
QuadFunction - Introduced
MeasurementTakerand its supporting classesMeasurementContext,MeasurementRecorderLoggingMeasurementRecordersupports logging performance measurements to the log with configurable logging levels according to theLogThresholdsMicrometerMeasurementRecorderwhich uses Micrometer'sTimerto record execution times.
- Added
InvocationTrackerthat can be used withPatternMatchingMethodInvokerto track invocation performance - Introduced
FunctionalInterfaceLoggingNameResolverthat attempts to extract informative names from lambda expressions and method references - useful for logging - Improved
ReactiveHandlersBeanPostProcessor. It now skips post-processing for Beans withAutoConfigurationannotation or roleBeanDefinition.ROLE_INFRASTRUCTURE - Improved
README.mdfor thetypes-jacksonmodule CharSequenceType,CountryCode,CurrencyCodeandEmailAddressare now compatible with Jackson version 2.18.*- Improved
README.mdfor thetypesmodule - Improved
EventProcessorlogging - Introduced
EventStoreSubscriptionObserverwhich is used for trackingEventStoreSubscriptionstatistics- Added
MeasurementEventStoreSubscriptionObserveras the defaultEventStoreSubscriptionObserverimplementation - Added
EventStoreSubscriptionObservertoDefaultEventStoreSubscriptionManager
- Added
- Added
isExclusive,isAsynchronousandisInTransactionmethods toEventStoreSubscription - Introduced
RecordExecutionTimeEventStoreInterceptorthat records execution time for event store operations using theMeasurementTakerAPI - Added more
OptimisticAppendToStreamExceptionmessage explanation and improved logging formatting - Improved
SeparateTablePerAggregateTypePersistenceStrategy's message and logging in case ofOptimisticAppendToStreamExceptionorAppendToStreamExceptionduringpersist - Improved
PostgresqlEventStore:- Added support for
resolveBatchSizeForThisQuerycorner case when no events have been persisted for an aggregate type. - Improved
PollEventStoreTaskpoll interval logic if events were published vs when no events were published
- Added support for
- Added examples to
GivenWhenThenScenario's Kotlin doc AggregateType,EventName,EventType,CorrelationId,EventId,MessageId,SubscriberIdandTenantIdare now compatible with Jackson version 2.18.*- Introduced
InfrastructureLocalEventBusfor publishing internal technical events - Introduced
DurableQueueDeserializationExceptionto indicate Message JSON payload deserialization issues - Added
HandleQueuedMessageas anDurableQueuesInterceptoroperation. DefaultDurableQueueConsumer:- Immediately marks messages that fail due to
DurableQueueDeserializationExceptionas dead-letter-messages - Added
HandleQueuedMessageinterception
- Immediately marks messages that fail due to
InboxName,LockName,OutboxName,QueueEntryIdandQueueNameare now compatible with Jackson version 2.18.*- Introduced
RecordExecutionTimeCommandBusInterceptor,RecordExecutionTimeDurableQueueInterceptorandRecordExecutionTimeMessageHandlerInterceptor,
which measure processing time for theCommandBus,DurableQueuesand@MessageHandlerannotated methods, using the newMeasurementTakerAPI. - Improved
DefaultStatefulAggregateRepositorylogging and changed default level from TRACE to DEBUG - Improved
MongoFencedLockStorageTransactionException and WriteConflict handling - Added
MongoUtil.isWriteConflictand called it fromMongoFencedLockStorageandMongoDurableQueues - Adjusted
DBFencedLockManagerITtimeout and reconnection logic UnitOfWorkFactoryandUnitOfWorkLifecycleCallbackswitched to working withThrowableinstead ofExceptionfor rollbacks- Improved handling of TransactionSynchronization.STATUS_UNKNOWN in
SpringTransactionAwareUnitOfWorkFactory