Skip to content

Commit

Permalink
Fix compatibility for Spring Boot 3.4.x (#43098)
Browse files Browse the repository at this point in the history
  • Loading branch information
moarychan authored Nov 28, 2024
1 parent fce8b13 commit bd8f221
Show file tree
Hide file tree
Showing 11 changed files with 83 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ public class AzureSpringBootVersionVerifier {
static final String SPRINGBOOT_CONDITIONAL_CLASS_NAME_OF_3_1 = "org.springframework.boot.autoconfigure.validation.ValidationConfigurationCustomizer.ValidationConfigurationCustomizer,setIgnoreRegistrationFailure,";
static final String SPRINGBOOT_CONDITIONAL_CLASS_NAME_OF_3_2 = "org.springframework.boot.autoconfigure.web.client.RestClientSsl";
static final String SPRINGBOOT_CONDITIONAL_CLASS_NAME_OF_3_3 = "org.springframework.boot.autoconfigure.ldap.PropertiesLdapConnectionDetails";
static final String SPRINGBOOT_CONDITIONAL_CLASS_NAME_OF_3_4 = "org.springframework.boot.autoconfigure.http.client.HttpClientProperties";
/**
* Versions supported by Spring Cloud Azure, for present is [3.0, 3.1, 3.2, 3.3]. Update this value if needed.
* Versions supported by Spring Cloud Azure, for present is [3.0, 3.1, 3.2, 3.3, 3.4]. Update this value if needed.
*/
private final Map<String, String> supportedVersions = new HashMap<>();

Expand All @@ -49,6 +50,7 @@ private void initDefaultSupportedBootVersionCheckMeta() {
supportedVersions.put("3.1", SPRINGBOOT_CONDITIONAL_CLASS_NAME_OF_3_1);
supportedVersions.put("3.2", SPRINGBOOT_CONDITIONAL_CLASS_NAME_OF_3_2);
supportedVersions.put("3.3", SPRINGBOOT_CONDITIONAL_CLASS_NAME_OF_3_3);
supportedVersions.put("3.4", SPRINGBOOT_CONDITIONAL_CLASS_NAME_OF_3_4);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class AzureCompatibilityVerifierProperties {
/**
* Comma-delimited list of Spring Boot versions that are compatible with current Spring Cloud Azure's version.
*/
private List<String> compatibleBootVersions = Arrays.asList("3.0.x", "3.1.x", "3.2.x", "3.3.x");
private List<String> compatibleBootVersions = Arrays.asList("3.0.x", "3.1.x", "3.2.x", "3.3.x", "3.4.x");

public boolean isEnabled() {
return this.enabled;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -141,6 +142,30 @@ protected void clearAzureProperties(Map<String, String> properties) {
.forEach(properties::remove);
}

@SuppressWarnings("unchecked")
protected Map<String, Object> invokeBuildKafkaProperties(KafkaProperties kafkaProperties, String buildMethodName) {
try {
try {
Method buildPropertiesMethod = KafkaProperties.class.getDeclaredMethod(buildMethodName,
Class.forName("org.springframework.boot.ssl.SslBundles"));
//noinspection unchecked
return (Map<String, Object>) buildPropertiesMethod.invoke(kafkaProperties, (Object) null);
} catch (NoSuchMethodException | ClassNotFoundException ignored) {

}
// The following logic is to be compatible with Spring Boot 3.0 and 3.1.
try {
//noinspection unchecked
return (Map<String, Object>) KafkaProperties.class.getDeclaredMethod(buildMethodName).invoke(kafkaProperties);
} catch (NoSuchMethodException ignored) {

}
} catch (InvocationTargetException | IllegalAccessException ignored) {

}
throw new IllegalStateException("Failed to call " + buildMethodName + " method of KafkaProperties.");
}

/**
* This method executes two operations:
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.kafka.KafkaProperties;
import org.springframework.cloud.stream.binder.kafka.properties.KafkaBinderConfigurationProperties;

import java.util.HashMap;
Expand Down Expand Up @@ -72,10 +73,10 @@ private Map<String, Object> mergeNonAdminProperties(Map<String, Object> mergedPr
return merged;
}

@SuppressWarnings("removal")
private Map<String, Object> mergeAdminProperties(KafkaBinderConfigurationProperties properties) {
Map<String, Object> adminProperties = properties.getKafkaProperties().buildAdminProperties();
normalalizeBootPropsWithBinder(adminProperties, properties.getKafkaProperties(), properties);
KafkaProperties kafkaProperties = properties.getKafkaProperties();
final Map<String, Object> adminProperties = invokeBuildKafkaProperties(kafkaProperties, "buildAdminProperties");
normalalizeBootPropsWithBinder(adminProperties, kafkaProperties, properties);
AzureKafkaPropertiesUtils.AzureKafkaPasswordlessPropertiesMapping.getPropertyKeys()
.forEach(k -> PROPERTY_MAPPER.from(properties.getConfiguration().get(k)).to(v -> adminProperties.put(k, v)));
return adminProperties;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,29 @@ class KafkaPropertiesBeanPostProcessor extends AbstractKafkaPropertiesBeanPostPr
super(azureGlobalProperties);
}

@SuppressWarnings("removal")
@Override
protected Map<String, Object> getMergedProducerProperties(KafkaProperties properties) {
return properties.buildProducerProperties();
return invokeBuildKafkaProperties(properties, "buildProducerProperties");
}

@Override
protected Map<String, String> getRawProducerProperties(KafkaProperties properties) {
return properties.getProducer().getProperties();
}

@SuppressWarnings("removal")
@Override
protected Map<String, Object> getMergedConsumerProperties(KafkaProperties properties) {
return properties.buildConsumerProperties();
return invokeBuildKafkaProperties(properties, "buildConsumerProperties");
}

@Override
protected Map<String, String> getRawConsumerProperties(KafkaProperties properties) {
return properties.getConsumer().getProperties();
}

@SuppressWarnings("removal")
@Override
protected Map<String, Object> getMergedAdminProperties(KafkaProperties properties) {
return properties.buildAdminProperties();
return invokeBuildKafkaProperties(properties, "buildAdminProperties");

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.Map;

import static com.azure.spring.cloud.autoconfigure.implementation.eventhubs.kafka.AzureEventHubsKafkaAutoConfigurationTests.CONNECTION_STRING_FORMAT;
import static com.azure.spring.cloud.autoconfigure.implementation.util.TestCompatibilityUtils.invokeBuildKafkaProperties;
import static org.apache.kafka.clients.CommonClientConfigs.SECURITY_PROTOCOL_CONFIG;
import static org.apache.kafka.clients.consumer.ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG;
import static org.apache.kafka.common.config.SaslConfigs.SASL_MECHANISM;
Expand All @@ -40,7 +41,6 @@ class AzureEventHubsKafkaConfigurationTests {
KafkaAutoConfiguration.class, AzureKafkaSpringCloudStreamConfiguration.class, KafkaBinderConfiguration.class));


@SuppressWarnings("removal")
@Test
void shouldConfigureSaslPlainWhenGivenConnectionString() {
contextRunner
Expand All @@ -55,7 +55,7 @@ void shouldConfigureSaslPlainWhenGivenConnectionString() {
assertThat(context).hasSingleBean(KafkaBinderConfigurationProperties.class);

KafkaProperties kafkaProperties = context.getBean(KafkaProperties.class);
assertSaslPlainConfigured(kafkaProperties.buildProducerProperties());
assertSaslPlainConfigured(invokeBuildKafkaProperties(kafkaProperties, "buildProducerProperties"));
DefaultKafkaConsumerFactory<?, ?> consumerFactory = (DefaultKafkaConsumerFactory<?, ?>) context.getBean(ConsumerFactory.class);
assertSaslPlainConfigured(consumerFactory.getConfigurationProperties());
DefaultKafkaProducerFactory<?, ?> producerFactory = (DefaultKafkaProducerFactory<?, ?>) context.getBean(ProducerFactory.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.util.HashMap;
import java.util.Map;

import static com.azure.spring.cloud.autoconfigure.implementation.util.TestCompatibilityUtils.invokeBuildKafkaProperties;
import static org.apache.kafka.clients.CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG;
import static org.apache.kafka.common.config.SaslConfigs.SASL_JAAS_CONFIG;
import static org.assertj.core.api.Assertions.assertThat;
Expand Down Expand Up @@ -148,7 +149,6 @@ void testBindKafkaBinderProperties() {
});
}

@SuppressWarnings("removal")
@Test
void testNotBindBinderPropertiesOnBoot() {
getContextRunnerWithEventHubsURL()
Expand All @@ -160,11 +160,11 @@ void testNotBindBinderPropertiesOnBoot() {
.run(context -> {
KafkaProperties kafkaProperties = context.getBean(KafkaProperties.class);
assertFalse(kafkaProperties.getProperties().containsKey("azure.credential.client-id"));
assertFalse(kafkaProperties.buildConsumerProperties().containsKey("azure.credential.client-id"));
assertFalse(invokeBuildKafkaProperties(kafkaProperties, "buildConsumerProperties").containsKey("azure.credential.client-id"));
assertFalse(kafkaProperties.getProducer().getProperties().get(SASL_JAAS_CONFIG).contains("azure.credential.client-id"));
assertFalse(kafkaProperties.buildProducerProperties().containsKey("azure.credential.client-id"));
assertFalse(invokeBuildKafkaProperties(kafkaProperties, "buildProducerProperties").containsKey("azure.credential.client-id"));
assertFalse(kafkaProperties.getConsumer().getProperties().get(SASL_JAAS_CONFIG).contains("azure.credential.client-id"));
assertFalse(kafkaProperties.buildAdminProperties().containsKey("azure.credential.client-id"));
assertFalse(invokeBuildKafkaProperties(kafkaProperties, "buildAdminProperties").containsKey("azure.credential.client-id"));
assertFalse(kafkaProperties.getAdmin().getProperties().get(SASL_JAAS_CONFIG).contains("azure.credential.client-id"));
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.spring.cloud.autoconfigure.implementation.util;

import org.springframework.boot.autoconfigure.kafka.KafkaProperties;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

public class TestCompatibilityUtils {

@SuppressWarnings("unchecked")
public static Map<String, Object> invokeBuildKafkaProperties(KafkaProperties kafkaProperties, String buildMethodName) {
try {
try {
Method buildPropertiesMethod = KafkaProperties.class.getDeclaredMethod(buildMethodName,
Class.forName("org.springframework.boot.ssl.SslBundles"));
//noinspection unchecked
return (Map<String, Object>) buildPropertiesMethod.invoke(kafkaProperties, (Object) null);
} catch (NoSuchMethodException | ClassNotFoundException ignored) {

}
// The following logic is to be compatible with Spring Boot 3.0 and 3.1.
try {
//noinspection unchecked
return (Map<String, Object>) KafkaProperties.class.getDeclaredMethod(buildMethodName).invoke(kafkaProperties);
} catch (NoSuchMethodException ignored) {

}
} catch (InvocationTargetException | IllegalAccessException ignored) {

}
throw new IllegalStateException("Failed to call " + buildMethodName + " method of KafkaProperties.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public class DefaultMessageHandler extends AbstractMessageProducingHandler {
private final SendOperation sendOperation;
private boolean sync = false;

@SuppressWarnings("deprecation")
@SuppressWarnings({"deprecation", "removal"})
private ListenableFutureCallback<Void> sendCallback;
private EvaluationContext evaluationContext;
private Expression sendTimeoutExpression = new ValueExpression<>(DEFAULT_SEND_TIMEOUT);
Expand Down Expand Up @@ -263,7 +263,7 @@ private Map<String, Object> buildPropertiesMap() {
*
* @param callback the call back
*/
@SuppressWarnings("deprecation")
@SuppressWarnings({"deprecation", "removal"})
public void setSendCallback(ListenableFutureCallback<Void> callback) {
this.sendCallback = callback;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
*
*/
@SuppressWarnings("deprecation")
@SuppressWarnings({"deprecation", "removal"})
public class InstrumentationSendCallback implements ListenableFutureCallback<Void> {

private final InstrumentationManager instrumentationManager;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void testSend() {
}

@Test
@SuppressWarnings("deprecation")
@SuppressWarnings({"deprecation", "removal"})
public void testSendCallback() {
ListenableFutureCallback<Void> callbackSpy = spy(new ListenableFutureCallback<Void>() {
@Override
Expand Down

0 comments on commit bd8f221

Please sign in to comment.