Skip to content

fix(spring-config): init OkapiMicrometerAutoConfiguration considering multiple PTMs - #81

Merged
rawo merged 2 commits into
mainfrom
bugfix/issue-80
Jul 28, 2026
Merged

fix(spring-config): init OkapiMicrometerAutoConfiguration considering multiple PTMs#81
rawo merged 2 commits into
mainfrom
bugfix/issue-80

Conversation

@rawo

@rawo rawo commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Fixes #80: OkapiMicrometerAutoConfiguration.micrometerOutboxMetrics() crashed Spring context startup with NoUniqueBeanDefinitionException whenever 2+ PlatformTransactionManager beans were present — even when okapi.transaction-manager-qualifier was set to disambiguate, since it never looked at that property at all. It used a bare ObjectProvider.getIfAvailable(), which throws on ambiguity instead of returning null or honoring a qualifier.

OutboxAutoConfiguration already had correct qualifier-aware resolution logic (resolvePlatformTransactionManager()), just not shared.

What changed

  • Extracted the qualifier-lookup half of OutboxAutoConfiguration.resolvePlatformTransactionManager() into a new internal resolvePlatformTransactionManagerByQualifier(beanFactory, qualifier), including its okapi-specific error rewrapping (actionable messages for "no bean with that name" and "bean exists but is the wrong type" — e.g. a DataSource name typoed into the qualifier property). resolvePlatformTransactionManager() now delegates to it instead of duplicating the logic.
  • OkapiMicrometerAutoConfiguration.micrometerOutboxMetrics() now uses the same resolver: if okapi.transaction-manager-qualifier is set, resolve that specific bean (throwing the same actionable errors OutboxAutoConfiguration would); otherwise fall back to ObjectProvider.getIfUnique(), which returns null on ambiguity instead of throwing. The PTM stays optional here (unlike OutboxAutoConfiguration's required one) — metrics just run without a read-only snapshot transaction when none is available or the beans are ambiguous.
  • @EnableConfigurationProperties on OkapiMicrometerAutoConfiguration now also registers OkapiProperties, needed to read the qualifier.

No behavior change for the existing single-PTM or zero-PTM cases; this only changes what happens when 2+ PlatformTransactionManager beans are present.

Test plan

  • New OkapiMicrometerAutoConfigurationTest (7 cases): reproduces the OkapiMicrometerAutoConfiguration should reuse transaciton init function OutboxAutoConfiguration.resolvePlatformTransactionManager() #80 crash with 2 PTM beans and no qualifier, confirms the qualifier fixes it, confirms a bad qualifier value still fails fast with an actionable message (proving the resolver is actually shared, not reimplemented), confirms the zero-PTM case still starts, and confirms — via TransactionSynchronizationManager resource binding — that the correct DataSource backs the read-only snapshot transaction in each case (qualifier picks the right one; no qualifier + single PTM uses it; no qualifier + ambiguous PTMs runs without a transaction rather than picking arbitrarily)
  • ./gradlew :okapi-spring-boot:ktlintCheck clean
  • ./gradlew :okapi-spring-boot:test green, including existing OutboxAutoConfiguration transaction-manager-resolution tests (unaffected by the extraction)

Copilot AI review requested due to automatic review settings July 28, 2026 07:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes Spring context startup failures in OkapiMicrometerAutoConfiguration.micrometerOutboxMetrics() when multiple PlatformTransactionManager beans are present by honoring okapi.transaction-manager-qualifier and avoiding ambiguous provider lookups.

Changes:

  • Extracted qualifier-based PTM resolution into OutboxAutoConfiguration.resolvePlatformTransactionManagerByQualifier(...) and reused it from the required-PTM resolver.
  • Updated OkapiMicrometerAutoConfiguration.micrometerOutboxMetrics() to (a) resolve the qualifier explicitly when configured, otherwise (b) use ObjectProvider.getIfUnique() so ambiguity results in “no PTM” rather than a startup crash.
  • Added a dedicated regression test suite covering multiple-PTM, qualifier, bad qualifier, and no-PTM scenarios (including verification of which DataSource is bound during the snapshot transaction).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
okapi-spring-boot/src/test/kotlin/com/softwaremill/okapi/springboot/OkapiMicrometerAutoConfigurationTest.kt Adds regression and behavior tests for PTM selection logic and startup stability under multiple PTMs.
okapi-spring-boot/src/main/kotlin/com/softwaremill/okapi/springboot/OutboxAutoConfiguration.kt Extracts and reuses qualifier-based PTM lookup with Okapi-specific error context.
okapi-spring-boot/src/main/kotlin/com/softwaremill/okapi/springboot/OkapiMicrometerAutoConfiguration.kt Updates Micrometer metrics auto-config to honor qualifier and avoid ambiguous PTM resolution crashes.
Comments suppressed due to low confidence (1)

okapi-spring-boot/src/main/kotlin/com/softwaremill/okapi/springboot/OutboxAutoConfiguration.kt:313

  • Similarly, this message suggests that removing okapi.transaction-manager-qualifier will reliably fall back to auto-resolution. For the outbox scheduler path, auto-resolution can still fail when multiple PTMs exist without a unique/@primary candidate. Consider clarifying that the fallback may still require disambiguation.
                    "okapi.transaction-manager-qualifier='$qualifier' — bean named '$qualifier' exists " +
                        "but is of type '${e.actualType.name}', not a PlatformTransactionManager. Check " +
                        "the property value (likely a typo into a DataSource or other bean name) or " +
                        "remove it to fall back to auto-resolution.",

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Rafał Wokacz <rafal.wokacz@gmail.com>
Copilot AI review requested due to automatic review settings July 28, 2026 08:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@rawo
rawo merged commit 0c41041 into main Jul 28, 2026
9 checks passed
@rawo
rawo deleted the bugfix/issue-80 branch July 28, 2026 08:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OkapiMicrometerAutoConfiguration should reuse transaciton init function OutboxAutoConfiguration.resolvePlatformTransactionManager()

2 participants