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:
committed by
Gary Russell
parent
aeb43f3069
commit
281d8d5bf6
@@ -19,10 +19,7 @@ package org.springframework.integration.config;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy;
|
||||
@@ -328,17 +325,15 @@ class DefaultConfiguringBeanFactoryPostProcessor
|
||||
if (!this.beanFactory.containsBean(IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME)) {
|
||||
ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver(this.classLoader);
|
||||
try {
|
||||
Resource[] defaultResources =
|
||||
resourceResolver.getResources("classpath*:META-INF/spring.integration.default.properties");
|
||||
Resource[] userResources =
|
||||
Resource[] resources =
|
||||
resourceResolver.getResources("classpath*:META-INF/spring.integration.properties");
|
||||
|
||||
List<Resource> resources = new LinkedList<>(Arrays.asList(defaultResources));
|
||||
resources.addAll(Arrays.asList(userResources));
|
||||
|
||||
// TODO Revise in favor of 'IntegrationProperties' instance in the next 6.0 version
|
||||
BeanDefinitionBuilder integrationPropertiesBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(PropertiesFactoryBean.class)
|
||||
.addPropertyValue("locations", resources);
|
||||
.addPropertyValue("properties", IntegrationProperties.defaults())
|
||||
.addPropertyValue("locations", resources)
|
||||
.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
|
||||
this.registry.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME,
|
||||
integrationPropertiesBuilder.getBeanDefinition());
|
||||
|
||||
@@ -18,7 +18,12 @@ package org.springframework.integration.context;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanNotOfRequiredTypeException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
@@ -110,6 +115,8 @@ public abstract class IntegrationContextUtils {
|
||||
|
||||
public static final String LIST_MESSAGE_HANDLER_FACTORY_BEAN_NAME = "integrationListMessageHandlerMethodFactory";
|
||||
|
||||
private static final Log LOGGER = LogFactory.getLog(IntegrationContextUtils.class);
|
||||
|
||||
/**
|
||||
* @param beanFactory BeanFactory for lookup, must not be null.
|
||||
* @return The {@link MetadataStore} bean whose name is "metadataStore".
|
||||
@@ -173,15 +180,15 @@ public abstract class IntegrationContextUtils {
|
||||
return beanFactory.getBean(beanName, type);
|
||||
}
|
||||
|
||||
// TODO Revise in favor of 'IntegrationProperties' instance in the next 6.0 version
|
||||
/**
|
||||
* @param beanFactory The bean factory.
|
||||
* @return the global {@link IntegrationContextUtils#INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME}
|
||||
* bean from provided {@code #beanFactory}, which represents the merged
|
||||
* properties values from all 'META-INF/spring.integration.default.properties'
|
||||
* and 'META-INF/spring.integration.properties'.
|
||||
* Or user-defined {@link Properties} bean.
|
||||
* properties values from all 'META-INF/spring.integration.properties'.
|
||||
* Or user-defined {@link IntegrationProperties} bean.
|
||||
* May return only {@link IntegrationProperties#defaults()} if there is no
|
||||
* {@link IntegrationContextUtils#INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME} bean within
|
||||
* {@link IntegrationContextUtils#INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME} bean in the
|
||||
* provided {@code #beanFactory} or provided {@code #beanFactory} is null.
|
||||
*/
|
||||
public static Properties getIntegrationProperties(BeanFactory beanFactory) {
|
||||
@@ -191,8 +198,7 @@ public abstract class IntegrationContextUtils {
|
||||
if (properties == null) {
|
||||
Properties propertiesToRegister = new Properties();
|
||||
propertiesToRegister.putAll(IntegrationProperties.defaults());
|
||||
Properties userProperties =
|
||||
getBeanOfType(beanFactory, INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME, Properties.class);
|
||||
Properties userProperties = obtainUserProperties(beanFactory);
|
||||
if (userProperties != null) {
|
||||
propertiesToRegister.putAll(userProperties);
|
||||
}
|
||||
@@ -215,6 +221,32 @@ public abstract class IntegrationContextUtils {
|
||||
return properties;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Properties obtainUserProperties(BeanFactory beanFactory) {
|
||||
Object userProperties = getBeanOfType(beanFactory, INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME, Object.class);
|
||||
if (userProperties instanceof Properties) {
|
||||
if (BeanDefinition.ROLE_INFRASTRUCTURE !=
|
||||
((BeanDefinitionRegistry) beanFactory)
|
||||
.getBeanDefinition(INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME)
|
||||
.getRole()) {
|
||||
|
||||
LOGGER.warn("The 'integrationGlobalProperties' bean must be declared as an instance of " +
|
||||
"'org.springframework.integration.context.IntegrationProperties'. " +
|
||||
"A 'java.util.Properties' support as a bean is deprecated for " +
|
||||
"'integrationGlobalProperties' since version 5.5.");
|
||||
}
|
||||
return (Properties) userProperties;
|
||||
}
|
||||
else if (userProperties instanceof IntegrationProperties) {
|
||||
return ((IntegrationProperties) userProperties).toProperties();
|
||||
}
|
||||
else if (userProperties != null) {
|
||||
throw new BeanNotOfRequiredTypeException(INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME,
|
||||
IntegrationProperties.class, userProperties.getClass());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link BeanDefinition} with the given name,
|
||||
* obtained from the given {@link BeanFactory} or one of its parents.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2020 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.
|
||||
@@ -294,12 +294,14 @@ public abstract class IntegrationObjectSupport implements BeanNameAware, NamedCo
|
||||
/**
|
||||
* @see IntegrationContextUtils#getIntegrationProperties(BeanFactory)
|
||||
* @return The global integration properties.
|
||||
* @deprecated since version 5.5 in favor of {@link #getIntegrationProperty(String, Class)};
|
||||
* will be replaced with {@link IntegrationProperties} variant in the next major version.
|
||||
*/
|
||||
@Deprecated
|
||||
protected Properties getIntegrationProperties() {
|
||||
return this.integrationProperties;
|
||||
}
|
||||
|
||||
|
||||
protected MessageBuilderFactory getMessageBuilderFactory() {
|
||||
if (this.messageBuilderFactory == null) {
|
||||
this.messageBuilderFactory = new DefaultMessageBuilderFactory();
|
||||
|
||||
@@ -16,17 +16,27 @@
|
||||
|
||||
package org.springframework.integration.context;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.factory.config.PropertiesFactoryBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
import org.springframework.core.io.support.ResourcePatternResolver;
|
||||
import org.springframework.integration.util.JavaUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Utility class to encapsulate infrastructure Integration properties constants and
|
||||
* their default values from resources 'META-INF/spring.integration.default.properties'.
|
||||
* Utility class to encapsulate infrastructure Integration properties constants and their default values.
|
||||
* The default values can be overridden by the {@code META-INF/spring.integration.properties} with this entries
|
||||
* (includes their default values):
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li> {@code spring.integration.channels.autoCreate=true}
|
||||
* <li> {@code spring.integration.channels.maxUnicastSubscribers=0x7fffffff}
|
||||
* <li> {@code spring.integration.channels.maxBroadcastSubscribers=0x7fffffff}
|
||||
* <li> {@code spring.integration.taskScheduler.poolSize=10}
|
||||
* <li> {@code spring.integration.messagingTemplate.throwExceptionOnLateReply=false}
|
||||
* <li> {@code spring.integration.readOnly.headers=}
|
||||
* <li> {@code spring.integration.endpoints.noAutoStartup=}
|
||||
* <li> {@code spring.integration.channels.error.requireSubscribers=true}
|
||||
* <li> {@code spring.integration.channels.error.ignoreFailures=true}
|
||||
* </ul>
|
||||
*
|
||||
* @author Artem Bilan
|
||||
*
|
||||
@@ -98,26 +108,228 @@ public final class IntegrationProperties {
|
||||
|
||||
private static final Properties DEFAULTS;
|
||||
|
||||
static {
|
||||
String resourcePattern = "classpath*:META-INF/spring.integration.default.properties";
|
||||
try {
|
||||
ResourcePatternResolver resourceResolver =
|
||||
new PathMatchingResourcePatternResolver(IntegrationProperties.class.getClassLoader());
|
||||
Resource[] defaultResources = resourceResolver.getResources(resourcePattern);
|
||||
private boolean channelsAutoCreate = true;
|
||||
|
||||
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
|
||||
propertiesFactoryBean.setLocations(defaultResources);
|
||||
propertiesFactoryBean.afterPropertiesSet();
|
||||
DEFAULTS = propertiesFactoryBean.getObject();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new IllegalStateException("Can't load '" + resourcePattern + "' resources.", e);
|
||||
}
|
||||
private int channelsMaxUnicastSubscribers = Integer.MAX_VALUE;
|
||||
|
||||
private int channelsMaxBroadcastSubscribers = Integer.MAX_VALUE;
|
||||
|
||||
private boolean errorChannelRequireSubscribers = true;
|
||||
|
||||
private boolean errorChannelIgnoreFailures = true;
|
||||
|
||||
private int taskSchedulerPoolSize = 10;
|
||||
|
||||
private boolean messagingTemplateThrowExceptionOnLateReply = false;
|
||||
|
||||
private String[] readOnlyHeaders = { };
|
||||
|
||||
private String[] noAutoStartupEndpoints = { };
|
||||
|
||||
static {
|
||||
DEFAULTS = new IntegrationProperties().toProperties();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link Properties} with default values for Integration properties
|
||||
* from resources 'META-INF/spring.integration.default.properties'.
|
||||
* Configure a value for {@link #CHANNELS_AUTOCREATE} option.
|
||||
* @param channelsAutoCreate the value for {@link #CHANNELS_AUTOCREATE} option.
|
||||
*/
|
||||
public void setChannelsAutoCreate(boolean channelsAutoCreate) {
|
||||
this.channelsAutoCreate = channelsAutoCreate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of {@link #CHANNELS_AUTOCREATE} option.
|
||||
* @return the value of {@link #CHANNELS_AUTOCREATE} option.
|
||||
*/
|
||||
public boolean isChannelsAutoCreate() {
|
||||
return this.channelsAutoCreate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a value for {@link #CHANNELS_MAX_UNICAST_SUBSCRIBERS} option.
|
||||
* @param channelsMaxUnicastSubscribers the value for {@link #CHANNELS_MAX_UNICAST_SUBSCRIBERS} option.
|
||||
*/
|
||||
public void setChannelsMaxUnicastSubscribers(int channelsMaxUnicastSubscribers) {
|
||||
this.channelsMaxUnicastSubscribers = channelsMaxUnicastSubscribers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of {@link #CHANNELS_MAX_UNICAST_SUBSCRIBERS} option.
|
||||
* @return the value of {@link #CHANNELS_MAX_UNICAST_SUBSCRIBERS} option.
|
||||
*/
|
||||
public int getChannelsMaxUnicastSubscribers() {
|
||||
return this.channelsMaxUnicastSubscribers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a value for {@link #CHANNELS_MAX_BROADCAST_SUBSCRIBERS} option.
|
||||
* @param channelsMaxBroadcastSubscribers the value for {@link #CHANNELS_MAX_BROADCAST_SUBSCRIBERS} option.
|
||||
*/
|
||||
public void setChannelsMaxBroadcastSubscribers(int channelsMaxBroadcastSubscribers) {
|
||||
this.channelsMaxBroadcastSubscribers = channelsMaxBroadcastSubscribers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of {@link #CHANNELS_MAX_BROADCAST_SUBSCRIBERS} option.
|
||||
* @return the value of {@link #CHANNELS_MAX_BROADCAST_SUBSCRIBERS} option.
|
||||
*/
|
||||
public int getChannelsMaxBroadcastSubscribers() {
|
||||
return this.channelsMaxBroadcastSubscribers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a value for {@link #ERROR_CHANNEL_REQUIRE_SUBSCRIBERS} option.
|
||||
* @param errorChannelRequireSubscribers the value for {@link #ERROR_CHANNEL_REQUIRE_SUBSCRIBERS} option.
|
||||
*/
|
||||
public void setErrorChannelRequireSubscribers(boolean errorChannelRequireSubscribers) {
|
||||
this.errorChannelRequireSubscribers = errorChannelRequireSubscribers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of {@link #ERROR_CHANNEL_REQUIRE_SUBSCRIBERS} option.
|
||||
* @return the value of {@link #ERROR_CHANNEL_REQUIRE_SUBSCRIBERS} option.
|
||||
*/
|
||||
public boolean isErrorChannelRequireSubscribers() {
|
||||
return this.errorChannelRequireSubscribers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a value for {@link #ERROR_CHANNEL_IGNORE_FAILURES} option.
|
||||
* @param errorChannelIgnoreFailures the value for {@link #ERROR_CHANNEL_IGNORE_FAILURES} option.
|
||||
*/
|
||||
public void setErrorChannelIgnoreFailures(boolean errorChannelIgnoreFailures) {
|
||||
this.errorChannelIgnoreFailures = errorChannelIgnoreFailures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of {@link #ERROR_CHANNEL_IGNORE_FAILURES} option.
|
||||
* @return the value of {@link #ERROR_CHANNEL_IGNORE_FAILURES} option.
|
||||
*/
|
||||
public boolean isErrorChannelIgnoreFailures() {
|
||||
return this.errorChannelIgnoreFailures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a value for {@link #TASK_SCHEDULER_POOL_SIZE} option.
|
||||
* @param taskSchedulerPoolSize the value for {@link #TASK_SCHEDULER_POOL_SIZE} option.
|
||||
*/
|
||||
public void setTaskSchedulerPoolSize(int taskSchedulerPoolSize) {
|
||||
this.taskSchedulerPoolSize = taskSchedulerPoolSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of {@link #TASK_SCHEDULER_POOL_SIZE} option.
|
||||
* @return the value of {@link #TASK_SCHEDULER_POOL_SIZE} option.
|
||||
*/
|
||||
public int getTaskSchedulerPoolSize() {
|
||||
return this.taskSchedulerPoolSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a value for {@link #THROW_EXCEPTION_ON_LATE_REPLY} option.
|
||||
* @param messagingTemplateThrowExceptionOnLateReply the value for {@link #THROW_EXCEPTION_ON_LATE_REPLY} option.
|
||||
*/
|
||||
public void setMessagingTemplateThrowExceptionOnLateReply(boolean messagingTemplateThrowExceptionOnLateReply) {
|
||||
this.messagingTemplateThrowExceptionOnLateReply = messagingTemplateThrowExceptionOnLateReply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of {@link #THROW_EXCEPTION_ON_LATE_REPLY} option.
|
||||
* @return the value of {@link #THROW_EXCEPTION_ON_LATE_REPLY} option.
|
||||
*/
|
||||
public boolean isMessagingTemplateThrowExceptionOnLateReply() {
|
||||
return this.messagingTemplateThrowExceptionOnLateReply;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a value for {@link #READ_ONLY_HEADERS} option.
|
||||
* @param readOnlyHeaders the value for {@link #READ_ONLY_HEADERS} option.
|
||||
*/
|
||||
public void setReadOnlyHeaders(String... readOnlyHeaders) {
|
||||
this.readOnlyHeaders = readOnlyHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of {@link #READ_ONLY_HEADERS} option.
|
||||
* @return the value of {@link #READ_ONLY_HEADERS} option.
|
||||
*/
|
||||
public String[] getReadOnlyHeaders() {
|
||||
return this.readOnlyHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a value for {@link #ENDPOINTS_NO_AUTO_STARTUP} option.
|
||||
* @param noAutoStartupEndpoints the value for {@link #ENDPOINTS_NO_AUTO_STARTUP} option.
|
||||
*/
|
||||
public void setNoAutoStartupEndpoints(String... noAutoStartupEndpoints) {
|
||||
this.noAutoStartupEndpoints = noAutoStartupEndpoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of {@link #ENDPOINTS_NO_AUTO_STARTUP} option.
|
||||
* @return the value of {@link #ENDPOINTS_NO_AUTO_STARTUP} option.
|
||||
*/
|
||||
public String[] getNoAutoStartupEndpoints() {
|
||||
return this.noAutoStartupEndpoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represent the current instance as a {@link Properties}.
|
||||
* @return the {@link Properties} representation.
|
||||
* @since 5.5
|
||||
*/
|
||||
public Properties toProperties() {
|
||||
Properties properties = new Properties();
|
||||
|
||||
properties.setProperty(CHANNELS_AUTOCREATE, "" + this.channelsAutoCreate);
|
||||
properties.setProperty(CHANNELS_MAX_UNICAST_SUBSCRIBERS, "" + this.channelsMaxUnicastSubscribers);
|
||||
properties.setProperty(CHANNELS_MAX_BROADCAST_SUBSCRIBERS, "" + this.channelsMaxBroadcastSubscribers);
|
||||
properties.setProperty(ERROR_CHANNEL_REQUIRE_SUBSCRIBERS, "" + this.errorChannelRequireSubscribers);
|
||||
properties.setProperty(ERROR_CHANNEL_IGNORE_FAILURES, "" + this.errorChannelIgnoreFailures);
|
||||
properties.setProperty(TASK_SCHEDULER_POOL_SIZE, "" + this.taskSchedulerPoolSize);
|
||||
properties.setProperty(THROW_EXCEPTION_ON_LATE_REPLY, "" + this.messagingTemplateThrowExceptionOnLateReply);
|
||||
properties.setProperty(READ_ONLY_HEADERS, StringUtils.arrayToCommaDelimitedString(this.readOnlyHeaders));
|
||||
properties.setProperty(ENDPOINTS_NO_AUTO_STARTUP,
|
||||
StringUtils.arrayToCommaDelimitedString(this.noAutoStartupEndpoints));
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a provided {@link Properties} and build an {@link IntegrationProperties} instance.
|
||||
* @return {@link IntegrationProperties} based on the provided {@link Properties}.
|
||||
* @since 5.5
|
||||
*/
|
||||
public static IntegrationProperties parse(Properties properties) {
|
||||
IntegrationProperties integrationProperties = new IntegrationProperties();
|
||||
JavaUtils.INSTANCE
|
||||
.acceptIfHasText(properties.getProperty(CHANNELS_AUTOCREATE),
|
||||
(value) -> integrationProperties.setChannelsAutoCreate(Boolean.parseBoolean(value)))
|
||||
.acceptIfHasText(properties.getProperty(CHANNELS_MAX_UNICAST_SUBSCRIBERS),
|
||||
(value) -> integrationProperties.setChannelsMaxUnicastSubscribers(Integer.parseInt(value)))
|
||||
.acceptIfHasText(properties.getProperty(CHANNELS_MAX_BROADCAST_SUBSCRIBERS),
|
||||
(value) -> integrationProperties.setChannelsMaxBroadcastSubscribers(Integer.parseInt(value)))
|
||||
.acceptIfHasText(properties.getProperty(ERROR_CHANNEL_REQUIRE_SUBSCRIBERS),
|
||||
(value) -> integrationProperties.setErrorChannelRequireSubscribers(Boolean.parseBoolean(value)))
|
||||
.acceptIfHasText(properties.getProperty(ERROR_CHANNEL_IGNORE_FAILURES),
|
||||
(value) -> integrationProperties.setErrorChannelIgnoreFailures(Boolean.parseBoolean(value)))
|
||||
.acceptIfHasText(properties.getProperty(TASK_SCHEDULER_POOL_SIZE),
|
||||
(value) -> integrationProperties.setTaskSchedulerPoolSize(Integer.parseInt(value)))
|
||||
.acceptIfHasText(properties.getProperty(THROW_EXCEPTION_ON_LATE_REPLY),
|
||||
(value) -> integrationProperties.setMessagingTemplateThrowExceptionOnLateReply(
|
||||
Boolean.parseBoolean(value)))
|
||||
.acceptIfHasText(properties.getProperty(READ_ONLY_HEADERS),
|
||||
(value) -> integrationProperties.setReadOnlyHeaders(
|
||||
StringUtils.commaDelimitedListToStringArray(value)))
|
||||
.acceptIfHasText(properties.getProperty(ENDPOINTS_NO_AUTO_STARTUP),
|
||||
(value) -> integrationProperties.setNoAutoStartupEndpoints(
|
||||
StringUtils.commaDelimitedListToStringArray(value)));
|
||||
return integrationProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link Properties} with default values for Integration properties.
|
||||
*/
|
||||
public static Properties defaults() {
|
||||
return DEFAULTS;
|
||||
@@ -126,7 +338,6 @@ public final class IntegrationProperties {
|
||||
/**
|
||||
* Build the bean property definition expression to resolve the value
|
||||
* from Integration properties within the bean building phase.
|
||||
*
|
||||
* @param key the Integration property key.
|
||||
* @return the bean property definition expression.
|
||||
* @throws IllegalArgumentException if provided {@code key} isn't an Integration property.
|
||||
@@ -142,7 +353,4 @@ public final class IntegrationProperties {
|
||||
}
|
||||
}
|
||||
|
||||
private IntegrationProperties() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"/>
|
||||
|
||||
|
||||
@@ -154,8 +154,7 @@ The next section describes what happens if exceptions occur within the asynchron
|
||||
|
||||
Certain global framework properties can be overridden by providing a properties file on the classpath.
|
||||
|
||||
The default properties can be found in `/META-INF/spring.integration.default.properties` in the `spring-integration-core` jar.
|
||||
You can see them on GitHub https://github.com/spring-projects/spring-integration/blob/master/spring-integration-core/src/main/resources/META-INF/spring.integration.default.properties[here].
|
||||
The default properties can be found in `org.springframework.integration.context.IntegrationProperties` class.
|
||||
The following listing shows the default values:
|
||||
|
||||
====
|
||||
@@ -205,7 +204,7 @@ See <<./error-handling.adoc#error-handling,Error Handling>> for more information
|
||||
Since version 5.5.
|
||||
====
|
||||
|
||||
These properties can be overridden by adding a `/META-INF/spring.integration.properties` file to the classpath.
|
||||
These properties can be overridden by adding a `/META-INF/spring.integration.properties` file to the classpath or an `IntegrationContextUtils.INTEGRATION_GLOBAL_PROPERTIES_BEAN_NAME` bean for the `org.springframework.integration.context.IntegrationProperties` instance.
|
||||
You need not provide all the properties -- only those that you want to override.
|
||||
|
||||
Starting with version 5.1, all the merged global properties are printed in the logs after application context startup when a `DEBUG` logic level is turned on for the `org.springframework.integration` category.
|
||||
|
||||
@@ -21,6 +21,7 @@ If you are interested in more details, see the Issue Tracker tickets that were r
|
||||
All the persistent `MessageGroupStore` implementation provide a `streamMessagesForGroup(Object groupId)` contract based on the target database streaming API.
|
||||
See <<./message-store.adoc#message-store,Message Store>> for more information.
|
||||
|
||||
The `integrationGlobalProperties` bean (if declared) must be now an instance of `org.springframework.integration.context.IntegrationProperties` instead of `java.util.Properties`, which support is deprecated for backward compatibility.
|
||||
The `spring.integration.channels.error.requireSubscribers=true` global property is added to indicate that the global default `errorChannel` must be configured with the `requireSubscribers` option (or not).
|
||||
The `spring.integration.channels.error.ignoreFailures=true` global property is added to indicate that the global default `errorChannel` must ignore (or not) dispatching errors and pass the message to the next handler.
|
||||
See <<./configuration.adoc#global-properties,Global Properties>> for more information.
|
||||
|
||||
Reference in New Issue
Block a user