Skip to content

Commit d9608ef

Browse files
authored
Bugfixes - Custom ObjectMapper bean does not work for received messages (Azure#44350)
1 parent 1dd6454 commit d9608ef

File tree

5 files changed

+110
-8
lines changed

5 files changed

+110
-8
lines changed

sdk/spring/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
11
# Release History
2+
## 5.21.0-beta.1 (Unreleased)
3+
### Spring Cloud Azure Autoconfigure
4+
This section includes changes in `spring-cloud-azure-autoconfigure` module.
5+
6+
#### Bugs Fixed
7+
- Custom `ObjectMapper` bean does not work for received messages. [#37796](https://github.com/Azure/azure-sdk-for-java/issues/37796).
28

39
## 5.20.0 (2025-02-12)
410
- This release is compatible with Spring Boot 3.4.0-3.4.2, 3.3.0-3.3.6, 3.2.0-3.2.12, 3.1.0-3.1.12, 3.0.0-3.0.13. (Note: 3.4.x (x>2), 3.3.y (y>6) and 3.2.z (z>12) should be supported, but they aren't tested with this release.)

sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/messaging/AzureMessagingListenerAutoConfiguration.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33

44
package com.azure.spring.cloud.autoconfigure.implementation.messaging;
55

6+
import com.azure.messaging.eventhubs.EventData;
7+
import com.azure.messaging.servicebus.ServiceBusMessage;
8+
import com.azure.messaging.servicebus.ServiceBusReceivedMessage;
69
import com.azure.spring.cloud.autoconfigure.implementation.eventhubs.AzureEventHubsMessagingAutoConfiguration;
710
import com.azure.spring.cloud.autoconfigure.implementation.servicebus.AzureServiceBusMessagingAutoConfiguration;
11+
import com.azure.spring.messaging.converter.AzureMessageConverter;
812
import com.azure.spring.messaging.eventhubs.core.EventHubsProcessorFactory;
913
import com.azure.spring.messaging.eventhubs.core.listener.EventHubsMessageListenerContainer;
1014
import com.azure.spring.messaging.eventhubs.implementation.core.config.EventHubsMessageListenerContainerFactory;
@@ -14,6 +18,7 @@
1418
import com.azure.spring.messaging.servicebus.core.ServiceBusProcessorFactory;
1519
import com.azure.spring.messaging.servicebus.core.listener.ServiceBusMessageListenerContainer;
1620
import com.azure.spring.messaging.servicebus.implementation.core.config.ServiceBusMessageListenerContainerFactory;
21+
import org.springframework.beans.factory.ObjectProvider;
1722
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
1823
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
1924
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
@@ -44,8 +49,11 @@ static class EventHubsConfiguration {
4449
@Bean(name = "azureEventHubsListenerContainerFactory")
4550
@ConditionalOnMissingBean(name = "azureEventHubsListenerContainerFactory")
4651
public MessageListenerContainerFactory<? extends MessageListenerContainer> azureEventHubsListenerContainerFactory(
47-
EventHubsProcessorFactory eventHubsProcessorFactory) {
48-
return new EventHubsMessageListenerContainerFactory(eventHubsProcessorFactory);
52+
EventHubsProcessorFactory eventHubsProcessorFactory,
53+
ObjectProvider<AzureMessageConverter<EventData, EventData>> messageConverterProvider) {
54+
EventHubsMessageListenerContainerFactory containerFactory = new EventHubsMessageListenerContainerFactory(eventHubsProcessorFactory);
55+
messageConverterProvider.ifAvailable(containerFactory::setMessageConverter);
56+
return containerFactory;
4957
}
5058

5159
}
@@ -56,8 +64,11 @@ static class ServiceBusConfiguration {
5664
@Bean(name = "azureServiceBusListenerContainerFactory")
5765
@ConditionalOnMissingBean(name = "azureServiceBusListenerContainerFactory")
5866
public MessageListenerContainerFactory<? extends MessageListenerContainer> azureServiceBusListenerContainerFactory(
59-
ServiceBusProcessorFactory serviceBusProcessorFactory) {
60-
return new ServiceBusMessageListenerContainerFactory(serviceBusProcessorFactory);
67+
ServiceBusProcessorFactory serviceBusProcessorFactory,
68+
ObjectProvider<AzureMessageConverter<ServiceBusReceivedMessage, ServiceBusMessage>> messageConverterProvider) {
69+
ServiceBusMessageListenerContainerFactory containerFactory = new ServiceBusMessageListenerContainerFactory(serviceBusProcessorFactory);
70+
messageConverterProvider.ifAvailable(containerFactory::setMessageConverter);
71+
return containerFactory;
6172
}
6273
}
6374

sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfiguration.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
import com.azure.core.credential.TokenCredential;
77
import com.azure.messaging.servicebus.ServiceBusClientBuilder;
8+
import com.azure.messaging.servicebus.ServiceBusMessage;
9+
import com.azure.messaging.servicebus.ServiceBusReceivedMessage;
810
import com.azure.spring.cloud.autoconfigure.implementation.condition.ConditionalOnAnyProperty;
911
import com.azure.spring.cloud.autoconfigure.implementation.servicebus.properties.AzureServiceBusProperties;
1012
import com.azure.spring.cloud.core.customizer.AzureServiceClientBuilderCustomizer;
@@ -13,6 +15,7 @@
1315
import com.azure.spring.cloud.core.service.AzureServiceType;
1416
import com.azure.spring.messaging.ConsumerIdentifier;
1517
import com.azure.spring.messaging.PropertiesSupplier;
18+
import com.azure.spring.messaging.converter.AzureMessageConverter;
1619
import com.azure.spring.messaging.implementation.converter.ObjectMapperHolder;
1720
import com.azure.spring.messaging.servicebus.core.DefaultServiceBusNamespaceProcessorFactory;
1821
import com.azure.spring.messaging.servicebus.core.DefaultServiceBusNamespaceProducerFactory;
@@ -137,9 +140,9 @@ ServiceBusMessageConverter serviceBusMessageConverter(ObjectMapper objectMapper)
137140
@Bean
138141
@ConditionalOnMissingBean
139142
@ConditionalOnBean(ServiceBusProducerFactory.class)
140-
ServiceBusTemplate serviceBusTemplate(ServiceBusProducerFactory senderClientfactory,
141-
ServiceBusMessageConverter messageConverter) {
142-
ServiceBusTemplate serviceBusTemplate = new ServiceBusTemplate(senderClientfactory);
143+
ServiceBusTemplate serviceBusTemplate(ServiceBusProducerFactory senderClientFactory,
144+
AzureMessageConverter<ServiceBusReceivedMessage, ServiceBusMessage> messageConverter) {
145+
ServiceBusTemplate serviceBusTemplate = new ServiceBusTemplate(senderClientFactory);
143146
serviceBusTemplate.setMessageConverter(messageConverter);
144147
return serviceBusTemplate;
145148
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
package com.azure.spring.cloud.autoconfigure.implementation.messaging;
5+
6+
import com.azure.spring.cloud.autoconfigure.implementation.eventhubs.AzureEventHubsMessagingAutoConfiguration;
7+
import com.azure.spring.cloud.autoconfigure.implementation.servicebus.AzureServiceBusMessagingAutoConfiguration;
8+
import com.azure.spring.messaging.eventhubs.core.EventHubsProcessorFactory;
9+
import com.azure.spring.messaging.eventhubs.core.listener.EventHubsMessageListenerContainer;
10+
import com.azure.spring.messaging.eventhubs.implementation.core.config.EventHubsMessageListenerContainerFactory;
11+
import com.azure.spring.messaging.eventhubs.implementation.support.converter.EventHubsMessageConverter;
12+
import com.azure.spring.messaging.implementation.annotation.EnableAzureMessaging;
13+
import com.azure.spring.messaging.servicebus.core.ServiceBusProcessorFactory;
14+
import com.azure.spring.messaging.servicebus.core.listener.ServiceBusMessageListenerContainer;
15+
import com.azure.spring.messaging.servicebus.implementation.core.config.ServiceBusMessageListenerContainerFactory;
16+
import com.azure.spring.messaging.servicebus.implementation.support.converter.ServiceBusMessageConverter;
17+
import org.junit.jupiter.api.Test;
18+
import org.springframework.boot.autoconfigure.AutoConfigurations;
19+
import org.springframework.boot.test.context.FilteredClassLoader;
20+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
21+
22+
import static org.assertj.core.api.Assertions.assertThat;
23+
import static org.junit.jupiter.api.Assertions.assertSame;
24+
import static org.mockito.Mockito.mock;
25+
26+
public class AzureMessagingListenerAutoConfigurationTests {
27+
28+
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
29+
.withConfiguration(AutoConfigurations.of(
30+
AzureEventHubsMessagingAutoConfiguration.class,
31+
AzureServiceBusMessagingAutoConfiguration.class,
32+
AzureMessagingListenerAutoConfiguration.class));
33+
34+
@Test
35+
void withoutEnableAzureMessagingShouldNotConfigure() {
36+
this.contextRunner
37+
.withClassLoader(new FilteredClassLoader(EnableAzureMessaging.class))
38+
.run(context -> {
39+
assertThat(context).doesNotHaveBean(AzureMessagingListenerAutoConfiguration.EventHubsConfiguration.class);
40+
assertThat(context).doesNotHaveBean(AzureMessagingListenerAutoConfiguration.ServiceBusConfiguration.class);
41+
});
42+
}
43+
44+
@Test
45+
void withoutEventHubsMessageListenerContainerShouldNotConfigure() {
46+
this.contextRunner
47+
.withClassLoader(new FilteredClassLoader(EventHubsMessageListenerContainer.class))
48+
.run(context -> {
49+
assertThat(context).doesNotHaveBean(AzureMessagingListenerAutoConfiguration.EventHubsConfiguration.class);
50+
});
51+
}
52+
53+
@Test
54+
void withoutServiceBusMessageListenerContainerShouldNotConfigure() {
55+
this.contextRunner
56+
.withClassLoader(new FilteredClassLoader(ServiceBusMessageListenerContainer.class))
57+
.run(context -> {
58+
assertThat(context).doesNotHaveBean(AzureMessagingListenerAutoConfiguration.ServiceBusConfiguration.class);
59+
});
60+
}
61+
62+
@Test
63+
void configureContainerFactories() {
64+
this.contextRunner
65+
.withBean(EventHubsMessageConverter.class, () -> mock(EventHubsMessageConverter.class))
66+
.withBean(EventHubsProcessorFactory.class, () -> mock(EventHubsProcessorFactory.class))
67+
.withBean(ServiceBusMessageConverter.class, () -> mock(ServiceBusMessageConverter.class))
68+
.withBean(ServiceBusProcessorFactory.class, () -> mock(ServiceBusProcessorFactory.class))
69+
.run(context -> {
70+
assertThat(context).hasBean("azureEventHubsListenerContainerFactory");
71+
assertThat(context).hasBean("azureServiceBusListenerContainerFactory");
72+
73+
EventHubsMessageConverter eventHubsMessageConverter = context.getBean(EventHubsMessageConverter.class);
74+
EventHubsMessageListenerContainerFactory eventHubsContainerFactory = (EventHubsMessageListenerContainerFactory) context.getBean("azureEventHubsListenerContainerFactory");
75+
assertSame(eventHubsMessageConverter, eventHubsContainerFactory.getMessageConverter());
76+
77+
ServiceBusMessageConverter messageConverter = context.getBean(ServiceBusMessageConverter.class);
78+
ServiceBusMessageListenerContainerFactory serviceBusContainerFactory = (ServiceBusMessageListenerContainerFactory) context.getBean("azureServiceBusListenerContainerFactory");
79+
assertSame(messageConverter, serviceBusContainerFactory.getMessageConverter());
80+
});
81+
}
82+
}

sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/annotation/AzureListenerAnnotationBeanPostProcessorAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
/**
4747
* Bean post-processor that registers methods annotated with {@link T}
48-
* to be invoked by a Azure message listener container created under the cover
48+
* to be invoked by an Azure message listener container created under the cover
4949
* by a {@link MessageListenerContainerFactory}
5050
* according to the attributes of the annotation.
5151
*

0 commit comments

Comments
 (0)