diff --git a/sdk/resourcemanager/azure-resourcemanager-storage/src/main/java/com/azure/resourcemanager/storage/fluent/models/FileShareProperties.java b/sdk/resourcemanager/azure-resourcemanager-storage/src/main/java/com/azure/resourcemanager/storage/fluent/models/FileShareProperties.java index ca22c18e1fca..3f2c389b6d13 100644 --- a/sdk/resourcemanager/azure-resourcemanager-storage/src/main/java/com/azure/resourcemanager/storage/fluent/models/FileShareProperties.java +++ b/sdk/resourcemanager/azure-resourcemanager-storage/src/main/java/com/azure/resourcemanager/storage/fluent/models/FileShareProperties.java @@ -6,6 +6,7 @@ import com.azure.core.annotation.Fluent; import com.azure.core.util.CoreUtils; +import com.azure.core.util.DateTimeRfc1123; import com.azure.json.JsonReader; import com.azure.json.JsonSerializable; import com.azure.json.JsonToken; @@ -76,19 +77,19 @@ public final class FileShareProperties implements JsonSerializable CoreUtils.parseBestOffsetDateTime(nonNullReader.getString())); + deserializedFileShareProperties.nextAllowedQuotaDowngradeTime + = reader.getNullable(nonNullReader -> new DateTimeRfc1123(nonNullReader.getString())); } else if ("nextAllowedProvisionedIopsDowngradeTime".equals(fieldName)) { - deserializedFileShareProperties.nextAllowedProvisionedIopsDowngradeTime = reader - .getNullable(nonNullReader -> CoreUtils.parseBestOffsetDateTime(nonNullReader.getString())); + deserializedFileShareProperties.nextAllowedProvisionedIopsDowngradeTime + = reader.getNullable(nonNullReader -> new DateTimeRfc1123(nonNullReader.getString())); } else if ("nextAllowedProvisionedBandwidthDowngradeTime".equals(fieldName)) { - deserializedFileShareProperties.nextAllowedProvisionedBandwidthDowngradeTime = reader - .getNullable(nonNullReader -> CoreUtils.parseBestOffsetDateTime(nonNullReader.getString())); + deserializedFileShareProperties.nextAllowedProvisionedBandwidthDowngradeTime + = reader.getNullable(nonNullReader -> new DateTimeRfc1123(nonNullReader.getString())); } else if ("enabledProtocols".equals(fieldName)) { deserializedFileShareProperties.enabledProtocols = EnabledProtocols.fromString(reader.getString()); } else if ("rootSquash".equals(fieldName)) { diff --git a/sdk/spring/CHANGELOG.md b/sdk/spring/CHANGELOG.md index 5889a1874d0d..3f3091847302 100644 --- a/sdk/spring/CHANGELOG.md +++ b/sdk/spring/CHANGELOG.md @@ -1,4 +1,10 @@ # Release History +## 5.21.0-beta.1 (Unreleased) +### Spring Cloud Azure Autoconfigure +This section includes changes in `spring-cloud-azure-autoconfigure` module. + +#### Bugs Fixed +- Custom `ObjectMapper` bean does not work for received messages. [#37796](https://github.com/Azure/azure-sdk-for-java/issues/37796). ## 5.20.0 (2025-02-12) - 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.) diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/messaging/AzureMessagingListenerAutoConfiguration.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/messaging/AzureMessagingListenerAutoConfiguration.java index e341f523ffea..ae45faee7838 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/messaging/AzureMessagingListenerAutoConfiguration.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/messaging/AzureMessagingListenerAutoConfiguration.java @@ -3,8 +3,12 @@ package com.azure.spring.cloud.autoconfigure.implementation.messaging; +import com.azure.messaging.eventhubs.EventData; +import com.azure.messaging.servicebus.ServiceBusMessage; +import com.azure.messaging.servicebus.ServiceBusReceivedMessage; import com.azure.spring.cloud.autoconfigure.implementation.eventhubs.AzureEventHubsMessagingAutoConfiguration; import com.azure.spring.cloud.autoconfigure.implementation.servicebus.AzureServiceBusMessagingAutoConfiguration; +import com.azure.spring.messaging.converter.AzureMessageConverter; import com.azure.spring.messaging.eventhubs.core.EventHubsProcessorFactory; import com.azure.spring.messaging.eventhubs.core.listener.EventHubsMessageListenerContainer; import com.azure.spring.messaging.eventhubs.implementation.core.config.EventHubsMessageListenerContainerFactory; @@ -14,6 +18,7 @@ import com.azure.spring.messaging.servicebus.core.ServiceBusProcessorFactory; import com.azure.spring.messaging.servicebus.core.listener.ServiceBusMessageListenerContainer; import com.azure.spring.messaging.servicebus.implementation.core.config.ServiceBusMessageListenerContainerFactory; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.condition.AnyNestedCondition; @@ -44,8 +49,11 @@ static class EventHubsConfiguration { @Bean(name = "azureEventHubsListenerContainerFactory") @ConditionalOnMissingBean(name = "azureEventHubsListenerContainerFactory") public MessageListenerContainerFactory azureEventHubsListenerContainerFactory( - EventHubsProcessorFactory eventHubsProcessorFactory) { - return new EventHubsMessageListenerContainerFactory(eventHubsProcessorFactory); + EventHubsProcessorFactory eventHubsProcessorFactory, + ObjectProvider> messageConverterProvider) { + EventHubsMessageListenerContainerFactory containerFactory = new EventHubsMessageListenerContainerFactory(eventHubsProcessorFactory); + messageConverterProvider.ifAvailable(containerFactory::setMessageConverter); + return containerFactory; } } @@ -56,8 +64,11 @@ static class ServiceBusConfiguration { @Bean(name = "azureServiceBusListenerContainerFactory") @ConditionalOnMissingBean(name = "azureServiceBusListenerContainerFactory") public MessageListenerContainerFactory azureServiceBusListenerContainerFactory( - ServiceBusProcessorFactory serviceBusProcessorFactory) { - return new ServiceBusMessageListenerContainerFactory(serviceBusProcessorFactory); + ServiceBusProcessorFactory serviceBusProcessorFactory, + ObjectProvider> messageConverterProvider) { + ServiceBusMessageListenerContainerFactory containerFactory = new ServiceBusMessageListenerContainerFactory(serviceBusProcessorFactory); + messageConverterProvider.ifAvailable(containerFactory::setMessageConverter); + return containerFactory; } } diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfiguration.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfiguration.java index 43c1be1b0ac2..74dd6b36c3d7 100644 --- a/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfiguration.java +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/main/java/com/azure/spring/cloud/autoconfigure/implementation/servicebus/AzureServiceBusMessagingAutoConfiguration.java @@ -5,6 +5,8 @@ import com.azure.core.credential.TokenCredential; import com.azure.messaging.servicebus.ServiceBusClientBuilder; +import com.azure.messaging.servicebus.ServiceBusMessage; +import com.azure.messaging.servicebus.ServiceBusReceivedMessage; import com.azure.spring.cloud.autoconfigure.implementation.condition.ConditionalOnAnyProperty; import com.azure.spring.cloud.autoconfigure.implementation.servicebus.properties.AzureServiceBusProperties; import com.azure.spring.cloud.core.customizer.AzureServiceClientBuilderCustomizer; @@ -13,6 +15,7 @@ import com.azure.spring.cloud.core.service.AzureServiceType; import com.azure.spring.messaging.ConsumerIdentifier; import com.azure.spring.messaging.PropertiesSupplier; +import com.azure.spring.messaging.converter.AzureMessageConverter; import com.azure.spring.messaging.implementation.converter.ObjectMapperHolder; import com.azure.spring.messaging.servicebus.core.DefaultServiceBusNamespaceProcessorFactory; import com.azure.spring.messaging.servicebus.core.DefaultServiceBusNamespaceProducerFactory; @@ -137,9 +140,9 @@ ServiceBusMessageConverter serviceBusMessageConverter(ObjectMapper objectMapper) @Bean @ConditionalOnMissingBean @ConditionalOnBean(ServiceBusProducerFactory.class) - ServiceBusTemplate serviceBusTemplate(ServiceBusProducerFactory senderClientfactory, - ServiceBusMessageConverter messageConverter) { - ServiceBusTemplate serviceBusTemplate = new ServiceBusTemplate(senderClientfactory); + ServiceBusTemplate serviceBusTemplate(ServiceBusProducerFactory senderClientFactory, + AzureMessageConverter messageConverter) { + ServiceBusTemplate serviceBusTemplate = new ServiceBusTemplate(senderClientFactory); serviceBusTemplate.setMessageConverter(messageConverter); return serviceBusTemplate; } diff --git a/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/messaging/AzureMessagingListenerAutoConfigurationTests.java b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/messaging/AzureMessagingListenerAutoConfigurationTests.java new file mode 100644 index 000000000000..7ee4b88d0039 --- /dev/null +++ b/sdk/spring/spring-cloud-azure-autoconfigure/src/test/java/com/azure/spring/cloud/autoconfigure/implementation/messaging/AzureMessagingListenerAutoConfigurationTests.java @@ -0,0 +1,82 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package com.azure.spring.cloud.autoconfigure.implementation.messaging; + +import com.azure.spring.cloud.autoconfigure.implementation.eventhubs.AzureEventHubsMessagingAutoConfiguration; +import com.azure.spring.cloud.autoconfigure.implementation.servicebus.AzureServiceBusMessagingAutoConfiguration; +import com.azure.spring.messaging.eventhubs.core.EventHubsProcessorFactory; +import com.azure.spring.messaging.eventhubs.core.listener.EventHubsMessageListenerContainer; +import com.azure.spring.messaging.eventhubs.implementation.core.config.EventHubsMessageListenerContainerFactory; +import com.azure.spring.messaging.eventhubs.implementation.support.converter.EventHubsMessageConverter; +import com.azure.spring.messaging.implementation.annotation.EnableAzureMessaging; +import com.azure.spring.messaging.servicebus.core.ServiceBusProcessorFactory; +import com.azure.spring.messaging.servicebus.core.listener.ServiceBusMessageListenerContainer; +import com.azure.spring.messaging.servicebus.implementation.core.config.ServiceBusMessageListenerContainerFactory; +import com.azure.spring.messaging.servicebus.implementation.support.converter.ServiceBusMessageConverter; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.FilteredClassLoader; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.mockito.Mockito.mock; + +public class AzureMessagingListenerAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withConfiguration(AutoConfigurations.of( + AzureEventHubsMessagingAutoConfiguration.class, + AzureServiceBusMessagingAutoConfiguration.class, + AzureMessagingListenerAutoConfiguration.class)); + + @Test + void withoutEnableAzureMessagingShouldNotConfigure() { + this.contextRunner + .withClassLoader(new FilteredClassLoader(EnableAzureMessaging.class)) + .run(context -> { + assertThat(context).doesNotHaveBean(AzureMessagingListenerAutoConfiguration.EventHubsConfiguration.class); + assertThat(context).doesNotHaveBean(AzureMessagingListenerAutoConfiguration.ServiceBusConfiguration.class); + }); + } + + @Test + void withoutEventHubsMessageListenerContainerShouldNotConfigure() { + this.contextRunner + .withClassLoader(new FilteredClassLoader(EventHubsMessageListenerContainer.class)) + .run(context -> { + assertThat(context).doesNotHaveBean(AzureMessagingListenerAutoConfiguration.EventHubsConfiguration.class); + }); + } + + @Test + void withoutServiceBusMessageListenerContainerShouldNotConfigure() { + this.contextRunner + .withClassLoader(new FilteredClassLoader(ServiceBusMessageListenerContainer.class)) + .run(context -> { + assertThat(context).doesNotHaveBean(AzureMessagingListenerAutoConfiguration.ServiceBusConfiguration.class); + }); + } + + @Test + void configureContainerFactories() { + this.contextRunner + .withBean(EventHubsMessageConverter.class, () -> mock(EventHubsMessageConverter.class)) + .withBean(EventHubsProcessorFactory.class, () -> mock(EventHubsProcessorFactory.class)) + .withBean(ServiceBusMessageConverter.class, () -> mock(ServiceBusMessageConverter.class)) + .withBean(ServiceBusProcessorFactory.class, () -> mock(ServiceBusProcessorFactory.class)) + .run(context -> { + assertThat(context).hasBean("azureEventHubsListenerContainerFactory"); + assertThat(context).hasBean("azureServiceBusListenerContainerFactory"); + + EventHubsMessageConverter eventHubsMessageConverter = context.getBean(EventHubsMessageConverter.class); + EventHubsMessageListenerContainerFactory eventHubsContainerFactory = (EventHubsMessageListenerContainerFactory) context.getBean("azureEventHubsListenerContainerFactory"); + assertSame(eventHubsMessageConverter, eventHubsContainerFactory.getMessageConverter()); + + ServiceBusMessageConverter messageConverter = context.getBean(ServiceBusMessageConverter.class); + ServiceBusMessageListenerContainerFactory serviceBusContainerFactory = (ServiceBusMessageListenerContainerFactory) context.getBean("azureServiceBusListenerContainerFactory"); + assertSame(messageConverter, serviceBusContainerFactory.getMessageConverter()); + }); + } +} diff --git a/sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/annotation/AzureListenerAnnotationBeanPostProcessorAdapter.java b/sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/annotation/AzureListenerAnnotationBeanPostProcessorAdapter.java index 713c4bf4eaed..2ccd3f16deff 100644 --- a/sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/annotation/AzureListenerAnnotationBeanPostProcessorAdapter.java +++ b/sdk/spring/spring-messaging-azure/src/main/java/com/azure/spring/messaging/implementation/annotation/AzureListenerAnnotationBeanPostProcessorAdapter.java @@ -45,7 +45,7 @@ /** * Bean post-processor that registers methods annotated with {@link T} - * to be invoked by a Azure message listener container created under the cover + * to be invoked by an Azure message listener container created under the cover * by a {@link MessageListenerContainerFactory} * according to the attributes of the annotation. *