Deprecate Properties as bean for int global props

Having a bean as a `java.util.Properties` is not confusing
and may lead to some conflicts in the real application.
Plus it is not so easy to configure: need to know all
the possible integration properties - bad end-user experience

* Make an `IntegrationProperties` as a public POJO
for easy configuration of global properties
* Deprecate a presence of the `java.util.Properties`
* Leave framework-created `integrationGlobalProperties` as
a `Properties` instance for backward compatibility
* Fix tests to expose an `IntegrationProperties` bean instead
of deprecated `Properties`
* Fix docs according the change and current recommendations
This commit is contained in:
Artem Bilan
2021-02-17 13:36:16 -05:00
committed by Gary Russell
parent aeb43f3069
commit 281d8d5bf6
10 changed files with 314 additions and 85 deletions

View File

@@ -2,20 +2,18 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:int="http://www.springframework.org/schema/integration"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<util:properties id="integrationGlobalProperties">
<prop key="spring.integration.channels.maxUnicastSubscribers">456</prop>
<prop key="spring.integration.channels.maxBroadcastSubscribers">789</prop>
</util:properties>
<bean id="integrationGlobalProperties" class="org.springframework.integration.context.IntegrationProperties">
<property name="channelsMaxUnicastSubscribers" value="456"/>
<property name="channelsMaxBroadcastSubscribers" value="789"/>
</bean>
<import resource="DispatcherMaxSubscribersDefaultConfigurationTests-context.xml" />
<import resource="DispatcherMaxSubscribersDefaultConfigurationTests-context.xml"/>
<int:channel id="oneSub">
<int:dispatcher max-subscribers="1" />
<int:dispatcher max-subscribers="1"/>
</int:channel>
</beans>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2013-2019 the original author or authors.
* Copyright 2013-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,24 +20,21 @@ import static org.assertj.core.api.Assertions.assertThat;
import java.util.Properties;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
/**
* @author Artem Bilan
*
* @since 3.0
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringJUnitConfig
public class IntegrationContextTests {
@Autowired
@@ -56,6 +53,7 @@ public class IntegrationContextTests {
private ThreadPoolTaskScheduler taskScheduler;
@Test
@SuppressWarnings("deprecation")
public void testIntegrationContextComponents() {
assertThat(this.integrationProperties.get(IntegrationProperties.THROW_EXCEPTION_ON_LATE_REPLY))
.isEqualTo("true");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2021 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
package org.springframework.integration.gateway;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -29,15 +30,13 @@ import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
@@ -86,8 +85,7 @@ import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import org.springframework.util.concurrent.ListenableFuture;
import org.springframework.util.concurrent.ListenableFutureCallback;
@@ -97,8 +95,7 @@ import org.springframework.util.concurrent.ListenableFutureCallback;
* @author Gary Russell
* @author Artem Bilan
*/
@ContextConfiguration(classes = GatewayInterfaceTests.TestConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
@SpringJUnitConfig(classes = GatewayInterfaceTests.TestConfig.class)
@DirtiesContext
@ActiveProfiles("gatewayTest")
public class GatewayInterfaceTests {
@@ -236,7 +233,7 @@ public class GatewayInterfaceTests {
}
@Test
public void testWithServiceUnAnnotatedMethodGlobalHeaderDoesntOverride() throws Exception {
public void testWithServiceUnAnnotatedMethodGlobalHeaderDoesNotOverride() throws Exception {
ConfigurableApplicationContext ac =
new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", getClass());
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
@@ -344,9 +341,9 @@ public class GatewayInterfaceTests {
ac.close();
}
@Test(expected = IllegalArgumentException.class)
@Test
public void testWithServiceAsNotAnInterface() {
new GatewayProxyFactoryBean(NotAnInterface.class);
assertThatIllegalArgumentException().isThrownBy(() -> new GatewayProxyFactoryBean(NotAnInterface.class));
}
@Test
@@ -420,7 +417,7 @@ public class GatewayInterfaceTests {
ListenableFuture<Thread> result2 = this.execGateway.test2(Thread.currentThread());
final CountDownLatch latch = new CountDownLatch(1);
final AtomicReference<Thread> thread = new AtomicReference<>();
result2.addCallback(new ListenableFutureCallback<Thread>() {
result2.addCallback(new ListenableFutureCallback<>() {
@Override
public void onSuccess(Thread result) {
@@ -431,6 +428,7 @@ public class GatewayInterfaceTests {
@Override
public void onFailure(Throwable t) {
}
});
assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(result2.get().getName()).startsWith("exec-");
@@ -594,9 +592,9 @@ public class GatewayInterfaceTests {
public static class TestConfig {
@Bean(name = IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME)
public static Properties integrationProperties() {
Properties properties = new Properties();
properties.setProperty(IntegrationProperties.READ_ONLY_HEADERS, IGNORE_HEADER);
public static IntegrationProperties integrationProperties() {
IntegrationProperties properties = new IntegrationProperties();
properties.setReadOnlyHeaders(IGNORE_HEADER);
return properties;
}

View File

@@ -2,14 +2,12 @@
<beans:beans xmlns="http://www.springframework.org/schema/integration"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd
http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd">
<util:properties id="integrationGlobalProperties">
<beans:prop key="spring.integration.readOnly.headers">contentType,foo</beans:prop>
</util:properties>
<beans:bean id="integrationGlobalProperties" class="org.springframework.integration.context.IntegrationProperties">
<beans:property name="readOnlyHeaders" value="contentType,foo"/>
</beans:bean>
<object-to-json-transformer id="defaultTransformer" input-channel="defaultObjectMapperInput"/>