Broadleaf Microservices
  • v1.0.0-latest-prod

Sandbox Release Notes for 2.1.3-GA

Requirements

  • JDK 17 is required for Broadleaf release trains 2.0.0-GA, and beyond.

Important Updates

Important
The changes here are important, please ensure to read through them.

Mitigation of NotificationState buildup

Important
The changes described here are impactful and all clients are advised to read and follow these instructions.

Until now, NotificationAwareDomainMapperMember in SandboxServices was responsible for eagerly creating 'dormant' NotificationState records. These dormant records were effectively 'placeholders' that would not be eligible for send, retry, or even the common 'prune' logic in DataTracking. The expectation was for downstream operations to on-demand initialize these records for send as needed.

However, this led to a large buildup of NotificationState instances in the datastore, as if a transition operation was never performed, its NotificationState would never be cleared.

With this release of SandboxServices, a variety of changes have been introduced to mitigate this problem.

Changes to reduce future buildup

While NotificationAwareDomainMapperMember will still eagerly create 'dormant' notification states, these changes eliminate situations where records were being unnecessarily created.

  • Updated NotificationAwareDomainMapperMember to only initialize NotificationStates on entities where they are relevant rather than on all entities universally. For example, the various transition message states like PROMOTE are only relevant to ChangeSummary, but were being initialized on all the other domains like ChangeSummaryGroup and Sandbox. By being more intentional about when initialization occurs, we can reduce 'dead' bloat.

    Note
    As part of this change, NotificationAwareDomainMapperMember.setupGeneralNotificationContainerStates() is now a no-op since all other state initializations have been moved to other entity-specific methods. Please review the latest state of the class if you have overridden it.
  • Updated NotificationAwareMapperMember to only create SCHEDULE_DEPLOY notification states for ChangeDeploys that are being created with the SCHEDULING status. This reduces the amount of unnecessary bloat being generated. Previously, SCHEDULE_DEPLOY messages were being created for all ChangeDeploys, but only being initialized for send for SCHEDULING ChangeDeploys. With these changes, creation and initialization of the state are both gated on the SCHEDULING status.

Changes to periodically purge dormant states

These changes are focused on adding a scheduled mechanism to purge dormant notification states after a certain time period.

  • Introduced a new SandboxNotificationPruneRepository that will delete 'dormant' NotificationStates whose ULID timestamps match a value older than a configurable cutoff

  • Introduced a new SandboxNotificationPruneService that will engage the repository purge logic on a scheduled basis

Note
Please also see the configuration properties documentation.
Important

As there was no previous mechanism to purge 'dormant' NotificationState records, clients may find that there are a very large number of such records in their SandboxServices datastore. Because of this, the first execution of this purge job may be long-running as it works through removing this buildup. The aforementioned configuration properties around this job may be helpful to review to tune the execution settings.

Changes to make operations flexible on whether eagerly-created NotificationState records must be present

Many existing operations in SandboxServices were assuming the eagerly created NotificationState records were always present, and would not succeed if they were missing. These changes update those operations to gracefully handle the case when no eagerly created records exist. This is particularly important with the introduction of the above-mentioned scheduled purges of dormant states.

  • Modified JpaCustomizedChangeSummaryRepository#batchUpdateNotificationStates to insert new NotificationState records when they are missing instead of assuming they always exist. This assumption was already failing in certain niche cases, but is even more important to resolve with the new purging logic.

  • Introduced a new overload of the updateVals() method in the ChangeSummary service and repository that can insert a notification state if it does not already exist, and update DefaultIndexNotificationService to use this new method. As a result, the flow will still work even if there is no eagerly created BATCH_INDEX_REQUEST notification state available.

  • Introduced a new overload of the updateVals() method in the ChangeDeploy service and repository that can insert a notification state if it does not already exist, and update DefaultDeploymentRequestHandler to use this new method. As a result, the flow will still work even if there is no eagerly created UNSCHEDULE_DEPLOY notification state available. We lean into this by updating NotificationAwareDomainMapperMember to no longer initialize UNSCHEDULE_DEPLOY notification states in any capacity.

Miscellaneous Bug Fixes

  • Addressed an issue where Instant to JDBC Timestamp conversion logic specifically in JpaCustomizedChangeSummaryRepository was using a locally generated timestamp instead of converting the actual input value

  • Consolidated Instant to JDBC Timestamp conversion logic in various repositories to a new JdbcConversionUtils class

  • Fixed a bug where SANDBOX_DELETE notification states were being created, but never initialized in a way that would make them eligible for message send retry. If the explicit first-time notificationManager.handle() call failed, the notification state would never be found by the scheduled retry handler because its fields were insufficiently initialized. With the latest changes, the SANDBOX_DELETE state is now created and initialized only in the NotificationAwareDomainMapperMember.deleteMap() method, which engages at the time someone actually deletes a Sandbox.

  • Fixed a bug where sandboxIndexThreadPoolTaskExecutor bean was not overridable by clients