Skip to content
This repository was archived by the owner on Jul 4, 2025. It is now read-only.

Releases: cloudcreate-dk/essentials-project

Release 0.40.24 Spring Boot 3.3.*

Pre-release

Choose a tag to compare

@cloudcreate-dk cloudcreate-dk released this 05 May 21:42
e2a2c11

What's Changed

Full Changelog: 0.40.23...0.40.24

Release Notes Summary

🚨 Important Defaults and Potential Breaking Changes

  • Upgraded to Spring Boot 3.3.* - the last version compatible with Spring Boot 3.2 is version 0.40.23
  • Centralized Message Fetcher for PostgreSQL durable queues is enabled by default in Spring-Boot starters. Adjust or disable explicitly if not required.
  • EventProcessor now extends AbstractEventProcessor. Please report any backwards compatibility issues!

🚀 New Features

PostgreSQL Durable Queues

  • Centralized Message Fetcher: Introduced a single-threaded polling mechanism (CentralizedMessageFetcher) to reduce DB load by distributing tasks to worker threads.

    • Configurable via essentials.durable-queues.use-centralized-message-fetcher (default: enabled) and essentials.durable-queues.centralized-message-fetcher-polling-interval (default: 20 ms).
    • New integration tests: CentralizedFetcherDurableQueueIT.
  • New method: hasOrderedMessageQueuedForKey for message inspection.

Event Processing and Subscription

  • ViewEventProcessor (Experimental):

    • Direct processing of PersistedEvents; fallback to durable queues on processing errors.
      • ViewEventProcessor is an abstraction for processing events that are projected into views (e.g. in a relational database).
      • It integrates with a distributed locking mechanism to ensure exclusive access during processing.
      • PersistedEvent's are processed directly and only in case of an error handling the event will this event (and later events associated with the same aggregate id) be queued onto the underlying durable queue associated with this processor.
  • Enhanced subscription management via asynchronous methods:

    • subscribeToAggregateEventsAsynchronously and improved reset handling.
    • Batch subscription (batchSubscribeToAggregateEventsAsynchronously) introduced for increased throughput with retries and improved error handling:
      • BatchedPersistedEventHandler supports receiving multiple Events in a batch.

🛠️ Refactoring & Improvements

  • Improved integration tests for PostgreSQL durable queues:
    • Standardized visibility and abstracted common test logic.
  • Refined implementations of equals, hashCode in MessageMetaData, and improved documentation across multiple classes.
  • Handling SQLTransientException now supported in IOExceptionUtil.
  • Graceful handling (Flux.empty()) when listener closure fails in ListenNotify.

📚 Documentation

  • Documented new properties for centralized message fetching in READMEs.

📦 Dependency Updates

  • Kotlin: 2.0.21 → 2.1.20

  • Spring Boot: 3.2.12 → 3.3.11

  • Spring Framework BOM: 6.1.18 → 6.1.19

  • Reactor BOM: 2023.0.16 → 2023.0.17

  • Spring Data MongoDB: 4.2.12 → 4.3.11

  • Spring Data JPA: 3.2.12 → 3.3.11

  • MongoDB Driver Sync: 4.11.5 → 5.0.1

  • SnakeYAML: 2.3 → 2.4

  • Micrometer: 1.12.13 → 1.13.13

  • Micrometer Tracing: 1.2.12 → 1.3.11

  • Netty BOM: 4.1.119.Final → 4.2.0.Final

  • JUnit BOM: 5.12.1 → 5.12.2

  • Testcontainers BOM: 1.20.6 → 1.21.0

  • JDBI3 BOM: 3.49.0 → 3.49.3

  • Jackson BOM: 2.18.3 → 2.19.0

  • Mockito BOM: 5.16.1 → 5.17.0

  • Removed unnecessary Tomcat dependencies.

Release 0.40.23 Spring Boot 3.2.*

Pre-release

Choose a tag to compare

@cloudcreate-dk cloudcreate-dk released this 10 Apr 20:30
6af9380

What's Changed

🚀 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

This will soon become the new home for the project


🧠 metrics

  • Introduced the MeasurementTaker API for pluggable performance tracking
    • Includes LoggingMeasurementRecorder and MicrometerMeasurementRecorder
  • Added support for per-subsystem execution time thresholds via configuration
  • Introduced:
    • RecordExecutionTimeCommandBusInterceptor
    • RecordExecutionTimeDurableQueueInterceptor
    • RecordExecutionTimeMessageHandlerInterceptor
    • RecordExecutionTimeEventStoreInterceptor
  • Logging can be configured for each interceptor with class-specific logger names
  • Most new properties to control metrics collection under essentials.metrics.*, others are under essentials.eventstore

📦 durable-queues

  • Introduced DurableQueueDeserializationException
  • DefaultDurableQueueConsumer:
    • Immediately marks failed deserialization messages as Dead-Letter-Messages
    • Supports new HandleQueuedMessage interceptor operation
  • Updated:
    • PostgresqlDurableQueues.getNextMessageReadyForDelivery
    • MongoDurableQueues.getNextMessageReadyForDelivery
  • Added RecordExecutionTimeDurableQueueInterceptor
  • Expanded DurableQueuesIT to test dead-letter behavior on deserialization failure

🧰 eventstore-postgresql

  • Introduced EventStoreSubscriptionObserver interface
  • Added MeasurementEventStoreSubscriptionObserver for tracking EventStoreSubscription delivery duration
  • DefaultEventStoreSubscriptionManager now uses MeasurementEventStoreSubscriptionObserver by default
  • Added:
    • RecordExecutionTimeEventStoreInterceptor for performance tracking
  • Improved:
    • Logging and exception description for OptimisticAppendToStreamException and AppendToStreamException
    • PollEventStoreTask poll logic to adapt to publishing activity
    • Handling of resolveBatchSizeForThisQuery edge case

🧱 eventsourced-aggregates

  • Improved logging in DefaultStatefulAggregateRepository
    • Changed default log level from TRACE to DEBUG

🔐 Mongo fenced-locking

  • Improved MongoFencedLockStorage handling of TransactionException and WriteConflict scenarios
  • Introduced MongoUtil.isWriteConflict and reused it across:
    • MongoFencedLockStorage
    • MongoDurableQueues
  • Adjusted DBFencedLockManagerIT for improved reliability under concurrency and connectivity issues
    • Improved reconnection timing logic for stability

🛠 unit-of-work

  • UnitOfWorkFactory and UnitOfWorkLifecycleCallback now use Throwable instead of Exception for broader rollback coverage
  • Unified error handling logic:
    • UnitOfWorkFactory.usingUnitOfWork now aligns with UnitOfWorkFactory.withUnitOfWork for consistent rollback behavior
  • SpringTransactionAwareUnitOfWorkFactory improved to correctly handle TransactionSynchronization.STATUS_UNKNOWN

🔄 command-handling

  • Introduced RecordExecutionTimeCommandBusInterceptor
  • Default bean name changed from commandBus to essentialsCommandBus for DurableLocalCommandBus
  • Improved bean configuration and auto-wiring consistency

📨 event-bus and messaging

  • Introduced RecordExecutionTimeMessageHandlerInterceptor
  • Default bean name changed from eventBus to essentialsEventBus for EventBus
  • Improved EventProcessor logging
  • Introduced InfrastructureLocalEventBus for technical/internal events

⚙️spring-starters

  • Added support for disabling ReactiveHandlersBeanPostProcessor via essentials.reactive-bean-post-processor-enabled
  • ReactiveHandlersBeanPostProcessor now ignores:
    • Beans with @AutoConfiguration
    • Beans with role BeanDefinition.ROLE_INFRASTRUCTURE

🧬 Module: essentials-types & essentials-types-jackson

  • Enhanced Jackson 2.18 compatibility:
    • AggregateType, EventName, EventType, CorrelationId, EventId, MessageId, SubscriberId, TenantId
    • CharSequenceType, CountryCode, CurrencyCode, EmailAddress
    • InboxName, LockName, OutboxName, QueueEntryId, QueueName
  • Improved documentation in both modules’ README.md files

🧠 Module: shared

  • Introduced:
    • QuadFunction: a generic 4-arg functional interface
    • InvocationTracker: for tracking method execution via PatternMatchingMethodInvoker
    • FunctionalInterfaceLoggingNameResolver: 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 organization and organizationUrl to Trustworks and https://www.trustworks.dk as 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 MeasurementEventStoreSubscriptionObserver and RecordExecutionTimeEventStoreInterceptor which 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-enabled to disable the ReactiveHandlersBeanPostProcessor
  • Changed default bean name:
    • essentialsCommandBus instead of commandBus for DurableLocalCommandBus
    • essentialsEventBus instead of eventBus for EventBus
  • Auto configuration of RecordExecutionTimeMessageHandlerInterceptor, RecordExecutionTimeCommandBusInterceptor and RecordExecutionTimeDurableQueueInterceptor for essentials metrics collection and logging
    • Performance tracking is not enabled per default
    • To enable tracking and controlling logging you can use
    # 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
    and logging levels using:
    <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 `Dur...
Read more

Release 0.40.22 Spring Boot 3.2.*

Pre-release

Choose a tag to compare

@cloudcreate-dk cloudcreate-dk released this 20 Feb 12:47
d34f108

What's Changed

Full Changelog: 0.40.21...0.40.22

  • Added ability to register EventProcessor's that always starts consuming from the lastest event
  • Improved CommandBus/DurableLocalCommandBus documentation and Spring configuration of RedeliveryPolicy/SendAndDontWaitErrorHandler
  • Introduced new Exceptions methods which are used by code that catches Throwable to avoid suppressing unrecoverable errors (such as VirtualMachineError) that should not be caught/handled by framework logic:
    • rethrowIfCriticalError
    • isCriticalError
  • DBFencedLockManager integration tests now perform deleteAllLocksInDB prior to starting the lock manager nodes
  • Added Exceptions.rethrowIfCriticalError/isCriticalError checks where Throwable is caught
  • Improved DBFencedLockManager's cleanup logic/logging and reporting in case a lock couldn't be confirmed
    • Added Exceptions.rethrowIfCriticalError where Throwable is caught
  • MultiTableChangeListener
    • Improved javadoc
    • Now implements Lifecycle
    • Improved cleanup logic/logging
    • Added Exceptions.rethrowIfCriticalError where Throwable is caught
  • Added information about default property values in EventStoreSubscriptionManagerBuilder
  • Improved DefaultEventStoreSubscriptionManager's cleanup logic/logging
    • Changed saveResumePoints scheduled process thread name to start with EventStoreSubscriptionManager-SaveResumePoints-
    • Added Exceptions.rethrowIfCriticalError where Throwable is caught
    • onErrorHandlingEvent now accepts a Throwable instead of an Exception
  • Added EventProcessor integration test
  • Added more logging to DurableLocalCommandBus
  • Corrected the event published from DBFencedLockManager start to be FencedLockManagerStarted
  • Adjusted default EventProcessor.getNumberOfParallelInboxMessageConsumers to 1 instead of the number of available CPU processors !
  • Changed to CopyOnWriteArrayList in LocalEventBusTest's BlockingEventHandler to avoid potential ConcurrentModificationException
  • Added parallelization for maven-surefire-plugin and maven-failsafe-plugin

Updated 3rd party dependencies:

  • Spring 6.1.17
  • Reactor 2023.0.15
  • Json-Smart 2.5.2
  • Netty 4.1.118.Final
  • Jdbi 3.48.0

Updated Maven plugins:

  • dependency-check-maven 12.1.0

Release 0.40.21 Spring Boot 3.2.*

Pre-release

Choose a tag to compare

@cloudcreate-dk cloudcreate-dk released this 06 Feb 08:44
5177b37

What's Changed

Full Changelog: 0.40.20...0.40.21

  • Improved shared module documentation
  • Improved EventProcessor and InTransactionEventProcessor JavaDoc
  • EventStore's startStream now calls appendToStream with NO_EVENTS_PREVIOUSLY_PERSISTED (-1) as appendEventsAfterEventOrder value to ensure that startStream only can be used to start a new aggregate event-stream
  • Refined SendAndDontWaitErrorHandler documentation
  • Refined SendAndDontWaitErrorHandler documentation in the context of DurableLocalCommandBusBuilder
  • Added IOExceptionUtil.isIOException checks to DBFencedLockManager.stop
  • Added more assertions to MessageDeliveryErrorHandlerBuilderTest
  • MultiTableChangeListener
    • stop: Added additional try/catch around scheduledFuture.cancel and an explicit call to executorService.shutdownNow
    • pollForNotifications: Added additional scheduledFuture checks to skip polling early
  • Added spring-web test dependency
  • DurableQueues: Formatted code and organized imports
  • PostgresqlDurableQueues:
    • Formatted code and organized imports
    • Added additional IOExceptionUtil.isIOException during stop
    • Removed interception of ConsumeFromQueue and StopConsumingFromQueue in SingleOperationTransactionDurableQueuesInterceptor as they don't require to be run in a UnitOfWork
  • MongoDurableQueues:
    • Formatted code and organized imports
    • Added additional IOExceptionUtil.isIOException during stop
  • Aligned log level to DEBUG for all log statements logged when IOExceptionUtil.isIOException returns true
  • Updated dependency-check-maven to 12.0.2

Release 0.40.20 Spring Boot 3.2.*

Pre-release

Choose a tag to compare

@cloudcreate-dk cloudcreate-dk released this 23 Jan 16:03
74ad9f3

What's Changed

Full Changelog: 0.40.19...0.40.20

  • Added additional isIOException check to DBFencedLockManager to reduce logging severity in case of IO issues
  • Allowed DBFencedLockManager.acquireLockAsync to be performed without the DBFencedLockManager having been started
  • Added additional isIOException check to MultiTableChangeListener.unlisten to reduce logging severity in case of IO issues
  • Added more IOExceptionUtil.isIOException checks to ListenNotify and MultiTableChangeListener
  • Added a toString method to the class returned from QueuePollingOptimizer.None()
  • Added additional isIOException check to DefaultDurableQueueConsumer to reduce logging severity in case of IO issues
  • Added DurableQueueConsumer.consumerName() method
  • Improved DurableQueueBasedInbox and DurableQueueBasedOutbox logging
  • Added additional isIOException check to PostgresqlDurableSubscriptionRepository.saveResumePoints to reduce logging severity in case of IO issues
  • Added additional logging to PostgresqlDurableQueues.consumeFromQueue and MongoDurableQueues.consumeFromQueue
  • Switched from using ArrayList to using CopyOnWriteArrayList for the list of interceptors
  • Changed DefaultLifecycleManager to use the SmartLifecycle to attempt to start Essentials Lifecycle beans AFTER other resources, such as DataSource, has been started; as well as stop Lifecycle Beans are stopped prior other resources
  • Refined the IOExceptionUtil.isIOException method
      - Generalized many of the special cases into the following logic:
         - Exception or its Root-Cause is a subclass of IOException
         - The Exception's message contains a known error messages across Jdbi, JPA, JDBC, Mongo
         - If the exception's causal chain contains an exception that is either a subclass of ConnectionException or a subclass of MongoSocketException
         - Removed checks for org.jdbi.v3.core.statement.UnableToExecuteStatementException - please report back if this is an issue
      - Added IOExceptionUtilTest in foundation, postgresql-queue and springdata-mongo-queue
  • Refined Exceptions.getRootCause
      - Added ExceptionsTest
  • Added support for QueuedMessage.markForRedeliveryIn(Duration deliveryDelay)
      - Made causeForRetry in DurableQueues.retryMessage optional
  • Clarified RedeliveryPolicy.isPermanentError arguments
  • Clarified MessageDeliveryErrorHandler.isPermanentError arguments
      - Adjusted MessageDeliveryErrorHandler.StopRedeliveryOn's isPermanentError to use the new Exceptions.doesStackTraceContainExceptionOfType method
      - Adjusted MessageDeliveryErrorHandlerBuilder.shouldAlwaysRetryOn logic to use the new Exceptions.doesStackTraceContainExceptionOfType method
  • PostgresqlDurableQueues
      - Switched to use Instant.now() instead of OffsetDateTime.now(Clock.systemUTC())
      - Added null handling for getCauseForRetry()
  • MongoDurableQueues
      - Added null handling for getCauseForRetry()
  • Updated copyright year

Updated 3rd party dependencies:

  • spring-framework 6.1.16
  • log4j 2.24.3
  • junit 5.11.4
  • jackson 2.28.2
  • mockito 5.15.2
  • logback 1.5.16
  • reactor 2023.0.14
  • assertj 3.27.3
  • postgresql 42.7.5
  • netty 4.1.117.Final

Updated maven plugins:

  • dokka 2.0.0
  • maven-project-info-reports-plugin 3.8.0
  • maven-site-plugin 3.21.0
  • maven-javadoc-plugin 3.11.2
  • dependency-check-maven 12.0.1

Release 0.40.19 Spring Boot 3.2.*

Pre-release

Choose a tag to compare

@cloudcreate-dk cloudcreate-dk released this 04 Dec 07:56
23a424c

What's Changed

Full Changelog: 0.40.18...0.40.19

There are many changes in this release, please test thoroughly and provide feedback if you experience any issues.

  • Updated queue gauge value on message handled
  • Added ability to add multiple messages to an Inbox at once
  • Refined Javadoc for Inbox/Outbox and Inboxes/Outboxes
  • Added ability to add multiple messages to an Outbox at once (Added sendMessageList and sendMessages to Outbox)
  • Added integration test using a combination of InTransactionEventProcessor and StatefulAggregateRepository to verify that the StatefulAggregateRepositoryUnitOfWorkLifecycleCallback's beforeCommit logic, in combination with GenericHandleAwareUnitOfWorkFactory's beforeCommit logic, allows synchronous EventBus EventHandler's to participate in persisting additional event(s) as part of the same UnitOfWork
  • Added a default fencedLocksTableName value to PostgresqlFencedLockManagerBuilder
  • Added an elapsed method to StopWatch
  • Added filterDuplicateNotifications to the MultiTableChangeListenerProperties in the spring-boot-starter-postgresql autoconfiguration properties  (adjusted README.md to reflect this)
      - This is related to the new NotificationDuplicationFilter concept supported by the MultiTableChangeListener
  • Added commandBusParallelSendAndDontWaitConsumers to the ReactiveProperties in the spring-boot-starter-postgresql and spring-boot-starter-mongodb autoconfiguration properties (adjusted README.md to reflect this)
    • Renamed parallelThreads to eventBusParallelThreads in the ReactiveProperties  (adjusted README.md to reflect this)
  • Refined the javadoc and clarified UnitOfWork handling for EventStoreEventBus, EventProcessor, InTransactionEventProcessor, EventStoreSubscriptionManager
  • Refined the UnitOfWorkLifecycleCallback.BeforeCommitProcessingStatus processing status logic in GenericHandleAwareUnitOfWorkFactory and SpringTransactionAwareUnitOfWorkFactory so it supports having multiple unitOfWorkLifecycleCallbackResources
  • Improved SimpleQueuePollingOptimizer polling skip logic by switching from ThreadLocal to AtomicLong since multiple threads can be involved.
  • Improved DefaultDurableQueueConsumer
      - Added uncaughtExceptionHandler to the polling scheduler
      - Added more TRACE logging to pollQueue
      - Changed processNextMessageReadyForDelivery logic
  • Changed default parallelSendAndDontWaitConsumers value for DurableLocalCommandBus from 10 to the number of available processors
  • Introduced NotificationFilterChain + NotificationDuplicationFilter to MultiTableChangeListener which can reduce notification load for nearly identical notifications, where the difference isn't important to the listener.
      - If two or more Notification's in a given poll batch share the same duplication key, then only one of them will be published to the listeners registered with the MultiTableChangeListener
      - Example: if 100 messages are queued for the same QueueName in the same UnitOfWork, then the MultiTableChangeListener will notify
        the PostgresqlDurableQueues with 100 TableChangeNotification's. Using the QueueNameDuplicationFilter, the PostgresqlDurableQueues
        will only receive a single TableChangeNotification for that specific QueueName. Filtering is only performed on Notifications
        returned in a single database notification poll
  • Added QueueNameDuplicationFilter to PostgresqlDurableQueues setup to reduce notification load when multiple messages are queued for the same QueueName within a short amount of time (e.g. within a single UnitOfWork)
  • Optimized PostgresqlDurableQueues indexes to reduce index update time when inserting a lot of messages in a short amount of time
  • Added DurableQueuesLoadIT to test adding a lot of message within a single UnitOfWork doesn't delay message consumption due to slow index updates
  • Added more logging to PostgresqlDurableQueues.getNextMessageReadyForDelivery and switched to using multiline string
  • Improved StatefulAggregateRepository logging
  • Added isActive to EventProcessor and InTransactionEventProcessor
  • Added more UnitOfWork.info logging
    - ExclusiveInTransactionSubscription#isActive now returns active instead of started
    - Refined javadoc for EssentialsComponentsProperties

Release 0.40.18 Spring Boot 3.2.*

Pre-release

Choose a tag to compare

@cloudcreate-dk cloudcreate-dk released this 25 Nov 13:58
ec40e15

What's Changed

Full Changelog: 0.40.17...0.40.18

  • Clarified Inbox/Outbox UnitOfWork/transaction handling
  • Improved lag logging in SubscriberGlobalOrderMicrometerMonitor
  • All Classes.forName now use a classloader when converting Fully Qualified Java Class names to Class instances.
  • Added getClassLoader and setClassLoader to JSONSerializer to encapsulate setting the class loader on the underlying JSON serializer implementation.
  • Added new methods to AggregateEventStreamPersistenceStrategy
    • resolveGlobalEventOrderSequenceName
    • findLowestGlobalEventOrderPersisted
  • Added EventStore#findLowestGlobalEventOrderPersisted(AggregateType)
  • PostgresqlDurableSubscriptionRepository
    • Added EventStore a constructor argument
    • Removed HandleAwareUnitOfWorkFactory<?> unitOfWorkFactory argument from PostgresqlDurableSubscriptionRepository, which acquires the HandleAwareUnitOfWorkFactory from the EventStore
    • createResumePoint now uses EventStore.findLowestGlobalEventOrderPersisted to lookup the lowest GlobalEventOrder persisted and uses this value if it's greater than the provided onFirstSubscriptionSubscribeFromAndIncludingGlobalOrder (which typically defaults to GlobalEventOrder#FIRST_GLOBAL_EVENT_ORDER)
      • This solves an issue where (Re)Subscriptions after the EventStream table(s) have been truncated, but the corresponding GlobalEventOrder sequence hasn't been reset, would result in a slow catchup towards the lowest persisted GlobalEventOrder, due to EventStream Gap detection being cautious with regards to how fast Subscriptions increase the global-event-order range that's included in EventStore polling requests.
  • Switched to use log-level DEBUG for SqlExecutionTimeLogger.logException, instead of level ERROR
  • Improved PostgresqlEventStreamGapHandler log output
  • Improved the OptimisticAppendToStreamException detection in SeparateTablePerAggregateTypePersistenceStrategy and removed the cause exception from OptimisticAppendToStreamException and AppendToStreamException
  • Improved OptimisticAppendToStreamException testing in SingleTenantPostgresqlEventStoreIT
  • Improved EventJSON, EventMetaDataJSON, EventMetaData and PersistedEvent - added unit tests
  • Improved EventStoreSubscriptionManager_subscribeToAggregateEventsAsynchronously_IT test
  • Moved Lifecycle to the Shared module - kept Lifecycle in Foundation for backwards compatibility
  • EventBus now extends Lifecycle
  • Redesigned the LocalEventBus
    • Removed Optional's from constructors and introduced a Builder
    • async publisher code, which now has improved Overflow handling. It supports controlling the Flux backpressure buffer size, queue task cap size, overflow max retries
    • Improved shutdown logic
  • Improved EventStoreEventBus
    • Removed Optional's from constructors
  • Added equals/hashCode/toString to EventJSONTest
  • Added BeforeCommitProcessingStatus return value to UnitOfWorkLifecycleCallback#beforeCommit to allow GenericHandleAwareUnitOfWorkFactory and SpringTransactionAwareEventStoreUnitOfWorkFactory to rerun the beforeCommit phase to capture aggregate changes resulting from in-transaction event handling (e.g. from code listening to the EventBus)
  • Changed the UnitOfWorkLifecycleCallback in FlexAggregateRepository and StatefulAggregateRepository to return BeforeCommitProcessingStatus.REQUIRED as long as each beforeCommit run returns changes to aggregates.
  • Added info method to UnitOfWork
  • Added debug logging of UnitOfWork#info in UnitOfWorkFactory
  • Added copying PersistedEvent's list in PersistedEvents since the associated lists are reset in EventStoreManagedUnitOfWork across beforeCommit runs
  • Adjusted before/after commit callback logic in SpringTransactionAwareEventStoreUnitOfWorkFactory
  • Renamed Spring EventStore integration test classes from being called "Test" to "IT"
  • Added ReactiveProperties to EssentialsComponentsConfiguration to allow controlling the LocalEventBus/EventStoreEventBus properties
  • Updated README.md
  • Added support for exclusivelySubscribeToAggregateEventsInTransaction in EventStoreSubscriptionManager (work in progress)
  • Added InTransactionEventProcessor (work in progress)

Updated to Kotlin 2.0.21
Updated 3rd party dependencies

  • Spring Boot 3.2.12
  • Spring Framework 6.1.15
  • Reactor 2023.0.12
  • Spring Data MongoDB 4.2.12
  • Spring Data JPA 3.2.12
  • mongodb-driver-sync 4.11.5
  • log4j-to-slf4j 2.24.2
  • micrometer 1.12.13
  • micrometer-tracing 1.2.12
  • netty 4.1.115.Final
  • JUnit 5.11.3
  • TestContainers 1.20.4
  • JDBI 3.47.0
  • Jackson 2.18.1
  • LogBack 1.5.12

Updated Maven plugins

  • maven-javadoc-plugin 3.10.1
  • maven-dependency-plugin 3.8.1
  • maven-failsafe-plugin / maven-surefire-plugin 3.5.2
  • versions-maven-plugin 2.18.0
  • dependency-check-maven 11.1.0

Release 0.40.17 Spring Boot 3.2.*

Pre-release

Choose a tag to compare

@cloudcreate-dk cloudcreate-dk released this 02 Oct 08:45
b07e727

What's Changed

Full Changelog: 0.40.16...0.40.17

  • Improved IOExceptionUtil further by using a ConcurrentHashMap (to avoid ConcurrentModificationException) and defaulting Exception messages that are null to an empty String to avoid potential NullPointerException's
  • Improved IOExceptionUtil further by defaulting Root Cause Exception messages that are null to an empty String to avoid potential NullPointerException's
  • Introduced releaseAcquiredLocksInCaseOfIOExceptionsDuringLockConfirmation configuration to DBFencedLockManager, which allows a developer/user to control if a FencedLock acquired by a given FencedLockManager should be released in case calls to FencedLockStorage#confirmLockInDB(DBFencedLockManager, UnitOfWork, DBFencedLock, OffsetDateTime) fails with an exception where IOExceptionUtil#isIOException(Throwable) returns true. If releaseAcquiredLocksInCaseOfIOExceptionsDuringLockConfirmation is true, then FencedLock's will be released locally,
    otherwise we will retain the FencedLock's as locked.
  • Added DBFencedLockManager_MultiNode_ReleaseLockIT (and provider specific subclasses) to test locally acquired locks being released if releaseAcquiredLocksInCaseOfIOExceptionsDuringLockConfirmation is true
  • Improved DBFencedLockManager#confirmAllLocallyAcquiredLocks, DBFencedLockManager#releaseLock, DBFencedLockManager#acquireLockAsync
  • Improved PostgresqlFencedLockStorage#updateLockInDB to include the timed-out locks last lock_last_confirmed_ts timestamp to reduce the risk of two nodes trying to acquire the same lock concurrently
  • Improved MongoFencedLockStorage#updateLockInDB to include the timed-out locks last lockLastConfirmedTimestamp timestamp to reduce the risk of two nodes trying to acquire the same lock concurrently
  • Added ReleaseAcquiredLocksInCaseOfIOExceptionsDuringLockConfirmation to the FencedLockManager Properties for both the MongoDB and Postgresql SpringBoot starter configuration (default value is false)
  • Expanded documentation related to configuring the fenced lock manager's release lock in case of IO exceptions during lock confirmation setting: essentials.fenced-lock-manager.release-acquired-locks-in-case-of-i-o-exceptions-during-lock-confirmation=false

Updated 3rd party dependencies:

  • TestContainers 1.20.2
  • Mockito 5.14.1

Release 0.40.16 Spring Boot 3.2.*

Pre-release

Choose a tag to compare

@cloudcreate-dk cloudcreate-dk released this 29 Sep 09:15
9312627

What's Changed

Full Changelog: 0.40.15...0.40.16

  • Ensured Types compatibility with Jackson 2.18.0 by adding explicit String (for subclasses of CharSequenceType)  or Number (for subclasses of NumberType) constructors to concrete semantic types
  • Made providing an Exception optional when marking a DurableQueue message as a dead-letter message
  • Added support for providing an optional String description/cause when marking a DurableQueue message as dead-letter message
  • Added test to DurableQueuesIT, for a case where a Message handler during consumption manually marks the message as a dead-letter message, to confirm that the message is marked as a dead-letter message
  • Changed PostgresqlDurableQueues#acknowledgeMessageAsHandled(AcknowledgeMessageAsHandled) to only delete a message if it's NOT marked as a dead-letter message
  • Changed MongoDurableQueues#markAsDeadLetterMessage(MarkAsDeadLetterMessage) to not require that the message is marked is isBeingDelivered. The operation now also resets nextDeliveryTimestamp to null. This aligns with PostgresqlDurableQueues behaviour
  • Changed MongoDurableQueues#acknowledgeMessageAsHandled(AcknowledgeMessageAsHandled) to only delete a message if it's NOT marked as a dead-letter message and not require that the message is marked is isBeingDelivered
  • Since many operations are initiated by a new UnitOfWork, the DBFencedLockManager's version of withUnitOfWork and usingUnitOfWork now requires an error handler to make error handling explicit
  • The internal DBFencedLockManager#confirmAllLocallyAcquiredLocks no longer releases locks in case of an IO Exception during call to lockStorage.confirmLockInDB. If DB connectivity is broken it's better to retain the lock ownership as all nodes accessing the DB will likely experience the same behaviour
  • Added tests to DBFencedLockManagerIT, thereby PostgresqlFencedLockManagerIT and MongoFencedLockManagerIT, that tests the behaviour in case database connectivity is interrupted
  • Fixed potential NoClassDefFoundException in IOExceptionUtil
  • Added tests to DurableQueue integration tests to verify the behaviour in case database connectivity is interrupted
  • Improved EventStoreSubscription javadoc
  • Introduced PersistedEventSubscriber in EventStoreSubscriptionManager to handle all EventStore#pollEvent related logic, event forwarding and error handling related to asynchronous subscriptions
  • Added EventStoreSubscriptionManager tests that verify behaviour when the database connectivity is interrupted

Updated 3rd party dependencies:

  • Spring-Boot 3.2.10
  • Spring-Data-MongoDB 4.2.10
  • Spring-Data-JPA 3.2.10
  • MongoDB Driver Sync 4.11.4
  • log4j 2.24.0
  • snakeyaml 2.3
  • micrometer 1.12.10
  • micrometer-tracing 1.2.10
  • netty 4.1.113.Final
  • Junit 5.11.1
  • Jackson 2.18.0
  • Reactor 2023.0.10
  • Spring 6.1.13
  • Mockito 5.14.0
  • Logback 1.5.8

Updated maven plugins:

  • maven-failsafe-plugin / maven-surefire-plugin 3.5.0
  • dependency-check-maven 10.0.4
  • maven-gpg-plugin 3.2.7

Release 0.40.15 Spring Boot 3.2.*

Pre-release

Choose a tag to compare

@cloudcreate-dk cloudcreate-dk released this 29 Aug 14:58
edd177d

What's Changed

Full Changelog: 0.40.14...0.40.15

  • Improved DefaultDurableQueueConsumer message handling error logging, plus adjusted behaviour in case TransactionalMode.FullyTransactional is used as TransactionalMode
  • Added #getObjectMapper to JacksonJSONSerializer to support changes to EssentialsComponentsConfiguration
  • EssentialsComponentsConfiguration: If org.springframework.boot:spring-boot-devtools is added to the classpath (to support class reloading during development time), then we add support for dynamically changing ClassLoaders, in order to avoid ClassCastException's for messages/events/etc. that are deserialized from JSON
       - This is done by checked if org.springframework.boot.devtools.restart.RestartScope is on the classpath
       - In that case the SpringBootDevToolsClassLoaderChangeContextRefreshedListener is added to the ApplicationContext to ensure that JacksonJSONSerializer#getObjectMapper uses the same ClassLoader as the ApplicationContext

Upgraded 3rd party dependencies

  • mockito 5.13.0

Downgraded 3rd party dependencies to retain Spring Boot 3.2.x compatibility:

  • micrometer 1.12.9
  • micrometer-tracing 1.2.9

Downgraded maven-javadoc-plugin to version 3.7.0 because version 3.8.0 was reporting VM memory errors, such as:

[INFO] The goal 'org.apache.maven.plugins:maven-javadoc-plugin:3.8.0:javadoc' has not been previously called for the module: 'dk.cloudcreate.essentials:types:jar:DEV-SNAPSHOT'. Trying to invoke it...
[ERROR] Error occurred during initialization of VM, trying to use an empty MAVEN_OPTS...
[ERROR] MavenInvocationException: Error occurred during initialization of VM, try to reduce the Java heap size for the MAVEN_OPTS environment variable using -Xms:<size> and -Xmx:<size>.