Skip to content

Fix sub-level event-hub-name override for Spring Event Hubs starter#49076

Open
j7nw4r wants to merge 4 commits intomainfrom
fix/43593
Open

Fix sub-level event-hub-name override for Spring Event Hubs starter#49076
j7nw4r wants to merge 4 commits intomainfrom
fix/43593

Conversation

@j7nw4r
Copy link
Copy Markdown
Member

@j7nw4r j7nw4r commented May 6, 2026

Fixes #43593.

Problem

When using spring-cloud-azure-starter-eventhubs with both base-level and sub-level event-hub-name configured:

spring:
  cloud:
    azure:
      eventhubs:
        namespace: evhns-sample
        event-hub-name: bbbb
        consumer:
          consumer-group: $Default
          event-hub-name: aaaa
        producer:
          event-hub-name: aaaa

the injected EventHubProducerClient / EventHubConsumerClient connect to bbbb instead of the override aaaa.

Root cause

The property merge in AzureEventHubsProperties.build{Consumer,Producer}Properties() is correct (sub-level wins). The defect is in the autoconfiguration path selection:

AzureEventHubs{Consumer,Producer}ClientConfiguration only switches to the Dedicated (per-section builder) inner configuration when connection-string or namespace is set under the sub-prefix. With only event-hub-name overridden, it falls through to the Shared configuration, which reuses the parent EventHubClientBuilder already pinned to bbbb. EventHubClientBuilder is per-hub, so the shared path cannot represent a different hub.

Fix

Add "event-hub-name" to the @ConditionalOnMissingProperty / @ConditionalOnAnyProperty name arrays in both consumer and producer client configurations. Any sub-level event-hub-name override now routes to the Dedicated path, which already calls build{Consumer,Producer}Properties() with the correct precedence — no merge-logic changes required.

Tests

  • Added consumerEventHubNameOverrideShouldConfigureDedicated and producerEventHubNameOverrideShouldConfigureDedicated reproducing the issue scenario and asserting the merged properties resolve to the override and to the parent namespace.
  • Pruned the obsolete sub-scenarios in eventHubNameAndConsumerGroupProvidedShouldConfigure / eventHubNameProvidedShouldConfigure that were asserting the old (buggy) behavior of no inner config being created when only consumer.event-hub-name / producer.event-hub-name was set.
  • All 100 EventHub-related tests in spring-cloud-azure-autoconfigure pass locally.

How to verify

mvn -f sdk/spring/spring-cloud-azure-autoconfigure/pom.xml `
    -Dtest='AzureEventHubsConsumerClientConfigurationTests,AzureEventHubsProducerClientConfigurationTests,AzureEventHubsAutoConfigurationTests' `
    -DfailIfNoTests=false test

Johnathan Walker and others added 3 commits March 30, 2026 16:05
Added EventContextTest.updateCheckpointAsyncSetsOffsetString() which verifies
that offsetString is populated on the Checkpoint passed to the store. This test
fails without the fix (offsetString is null) and passes with it.

Fix: added setOffsetString(eventData.getOffsetString()) in
EventContext.updateCheckpointAsync(), matching the pattern already used in
EventBatchContext.

Fixes #46752

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
BlobCheckpointStore.updateCheckpoint() now falls back to the deprecated
Checkpoint.getOffset() (Long) when getOffsetString() is null/empty, so
callers that build Checkpoint instances using the legacy long offset still
have the offset persisted to blob metadata. The validation guard was
broadened to accept offsetString-only checkpoints.

Added regression tests covering: offset fallback, offsetString preference,
both populated, offsetString-only, and sequenceNumber-only.

Also added a CHANGELOG entry to azure-messaging-eventhubs for the
EventContext.updateCheckpointAsync() offsetString fix from the prior commit.

Refs #46752

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When spring.cloud.azure.eventhubs.consumer.event-hub-name or producer.event-hub-name
is configured, the autoconfiguration now selects the dedicated client builder
path instead of reusing the parent EventHubClientBuilder, ensuring the override
actually takes effect.

Fixes #43593

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added azure-spring All azure-spring related issues Event Hubs labels May 6, 2026
@j7nw4r j7nw4r marked this pull request as ready for review May 6, 2026 18:35
Copilot AI review requested due to automatic review settings May 6, 2026 18:35
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates Azure Spring Event Hubs autoconfiguration so that sub-level event-hub-name overrides (under spring.cloud.azure.eventhubs.consumer / .producer) correctly trigger the dedicated builder path, ensuring producer/consumer clients connect to the overridden hub rather than the base hub. It also includes a separate checkpointing fix in the Event Hubs libraries to ensure offsetString is propagated and persisted correctly.

Changes:

  • Spring autoconfigure: route to dedicated consumer/producer configuration when sub-level event-hub-name is set, and add regression tests for the override scenario.
  • Event Hubs client: propagate EventData.offsetString into Checkpoint in EventContext.updateCheckpointAsync() (with a regression unit test).
  • Blob checkpoint store: prefer Checkpoint.offsetString, and fall back to deprecated Checkpoint.offset when offsetString is missing (with expanded unit coverage + changelog updates).

Reviewed changes

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

Show a summary per file
File Description
sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/eventhubs/AzureEventHubsProducerClientConfiguration.java Ensures sub-level producer event-hub-name triggers the dedicated configuration path.
sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/eventhubs/AzureEventHubsConsumerClientConfiguration.java Ensures sub-level consumer event-hub-name triggers the dedicated configuration path.
sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/eventhubs/AzureEventHubsProducerClientConfigurationTests.java Adds a regression test asserting dedicated config is used when producer event-hub-name overrides the base value.
sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/eventhubs/AzureEventHubsConsumerClientConfigurationTests.java Adds a regression test asserting dedicated config is used when consumer event-hub-name overrides the base value.
sdk/spring/spring-cloud-azure-autoconfigure/CHANGELOG.md Documents the Spring Event Hubs override bug fix (#43593).
sdk/eventhubs/azure-messaging-eventhubs/src/main/java/com/azure/messaging/eventhubs/models/EventContext.java Propagates EventData.offsetString into the checkpoint built by updateCheckpointAsync().
sdk/eventhubs/azure-messaging-eventhubs/src/test/java/com/azure/messaging/eventhubs/models/EventContextTest.java Adds a regression test verifying offsetString is set on the checkpoint passed to CheckpointStore.
sdk/eventhubs/azure-messaging-eventhubs/CHANGELOG.md Documents the EventContext.updateCheckpointAsync() checkpointing fix (#46752).
sdk/eventhubs/azure-messaging-eventhubs-checkpointstore-blob/src/main/java/com/azure/messaging/eventhubs/checkpointstore/blob/BlobCheckpointStore.java Updates validation and persistence to prefer offsetString and fall back to deprecated offset.
sdk/eventhubs/azure-messaging-eventhubs-checkpointstore-blob/src/test/java/com/azure/messaging/eventhubs/checkpointstore/blob/BlobCheckpointStoreTests.java Adds unit tests covering fallback/preference/validation behaviors for offsetString vs offset.
sdk/eventhubs/azure-messaging-eventhubs-checkpointstore-blob/CHANGELOG.md Documents the Blob checkpoint store fallback fix (#46752).

Comment on lines +11 to +15
- Fixed `EventContext.updateCheckpointAsync()` so that the `offsetString` from the received `EventData` is propagated
to the `Checkpoint` passed to the `CheckpointStore`. Previously only the deprecated `offset` (Long) was set, which
caused checkpoint stores that read `offsetString` (such as `BlobCheckpointStore`) to persist a `null` offset, breaking
partition switch-over and consumer-group lag monitoring.
([#46752](https://github.com/Azure/azure-sdk-for-java/issues/46752))
}

/**
* Tests that an offsetString-only checkpoint is accepted by the validation guard (preserving previous behavior).
Comment on lines 244 to 252
@Override
public Mono<Void> updateCheckpoint(Checkpoint checkpoint) {
if (checkpoint == null || (checkpoint.getSequenceNumber() == null && checkpoint.getOffset() == null)) {
if (checkpoint == null
|| (checkpoint.getSequenceNumber() == null
&& checkpoint.getOffset() == null
&& CoreUtils.isNullOrEmpty(checkpoint.getOffsetString()))) {
throw LOGGER.logExceptionAsWarning(Exceptions.propagate(new IllegalStateException(
"Both sequence number and offset cannot be null when updating a checkpoint")));
"At least one of sequence number, offset, or offsetString must be provided when updating a checkpoint")));
}
Comment thread sdk/spring/spring-cloud-azure-autoconfigure/CHANGELOG.md Outdated
@rujche rujche moved this from Todo to In Progress in Spring Cloud Azure May 7, 2026
@rujche rujche added this to the 2026-06 milestone May 7, 2026
@rujche
Copy link
Copy Markdown
Member

rujche commented May 7, 2026

/azp run java - spring - tests

@azure-pipelines
Copy link
Copy Markdown

Azure Pipelines successfully started running 1 pipeline(s).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

azure-spring All azure-spring related issues Event Hubs

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

[BUG] The base level event-hub-name property should be overridden when sub-level event-hub-name property configured

3 participants