INT-4333: Don't Override Explicit Management Props

JIRA: https://jira.spring.io/browse/INT-4333

If the user has explicitly set management properties in a bean definition,
the configurer should not override those settings with defaults.
This commit is contained in:
Gary Russell
2017-09-01 12:29:12 -04:00
committed by Artem Bilan
parent 3a2be8e9e0
commit cfab1fb1a4
12 changed files with 151 additions and 16 deletions

View File

@@ -68,6 +68,8 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
private final Comparator<Object> orderComparator = new OrderComparator();
private final ManagementOverrides managementOverrides = new ManagementOverrides();
private volatile boolean shouldTrack = false;
private volatile Class<?>[] datatypes = new Class<?>[0];
@@ -101,8 +103,10 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
@Override
public void setCountsEnabled(boolean countsEnabled) {
this.countsEnabled = countsEnabled;
this.managementOverrides.countsConfigured = true;
if (!countsEnabled) {
this.statsEnabled = false;
this.managementOverrides.statsConfigured = true;
}
}
@@ -115,9 +119,11 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
public void setStatsEnabled(boolean statsEnabled) {
if (statsEnabled) {
this.countsEnabled = true;
this.managementOverrides.countsConfigured = true;
}
this.statsEnabled = statsEnabled;
this.channelMetrics.setFullStatsEnabled(statsEnabled);
this.managementOverrides.statsConfigured = true;
}
@Override
@@ -133,6 +139,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
@Override
public void setLoggingEnabled(boolean loggingEnabled) {
this.loggingEnabled = loggingEnabled;
this.managementOverrides.loggingConfigured = true;
}
protected AbstractMessageChannelMetrics getMetrics() {
@@ -143,6 +150,7 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
public void configureMetrics(AbstractMessageChannelMetrics metrics) {
Assert.notNull(metrics, "'metrics' must not be null");
this.channelMetrics = metrics;
this.managementOverrides.metricsConfigured = true;
}
/**
@@ -323,6 +331,11 @@ public abstract class AbstractMessageChannel extends IntegrationObjectSupport
return this.channelMetrics.getErrorRate();
}
@Override
public ManagementOverrides getOverrides() {
return this.managementOverrides;
}
@Override
protected void onInit() throws Exception {
super.onInit();

View File

@@ -45,7 +45,9 @@ import org.springframework.util.StringUtils;
public class NullChannel implements PollableChannel, MessageChannelMetrics,
ConfigurableMetricsAware<AbstractMessageChannelMetrics>, BeanNameAware, NamedComponent {
private final Log logger = LogFactory.getLog(this.getClass());
private final Log logger = LogFactory.getLog(getClass());
private final ManagementOverrides managementOverrides = new ManagementOverrides();
private volatile AbstractMessageChannelMetrics channelMetrics = new DefaultMessageChannelMetrics("nullChannel");
@@ -71,6 +73,7 @@ public class NullChannel implements PollableChannel, MessageChannelMetrics,
@Override
public void setLoggingEnabled(boolean loggingEnabled) {
this.loggingEnabled = loggingEnabled;
this.managementOverrides.loggingConfigured = true;
}
@Override
@@ -87,6 +90,7 @@ public class NullChannel implements PollableChannel, MessageChannelMetrics,
public void configureMetrics(AbstractMessageChannelMetrics metrics) {
Assert.notNull(metrics, "'metrics' must not be null");
this.channelMetrics = metrics;
this.managementOverrides.metricsConfigured = true;
}
@Override
@@ -97,8 +101,10 @@ public class NullChannel implements PollableChannel, MessageChannelMetrics,
@Override
public void setCountsEnabled(boolean countsEnabled) {
this.countsEnabled = countsEnabled;
this.managementOverrides.countsConfigured = true;
if (!countsEnabled) {
this.statsEnabled = false;
this.managementOverrides.statsConfigured = true;
}
}
@@ -111,9 +117,11 @@ public class NullChannel implements PollableChannel, MessageChannelMetrics,
public void setStatsEnabled(boolean statsEnabled) {
if (statsEnabled) {
this.countsEnabled = true;
this.managementOverrides.countsConfigured = true;
}
this.statsEnabled = statsEnabled;
this.channelMetrics.setFullStatsEnabled(statsEnabled);
this.managementOverrides.statsConfigured = true;
}
@Override
@@ -196,6 +204,11 @@ public class NullChannel implements PollableChannel, MessageChannelMetrics,
return this.channelMetrics.getErrorRate();
}
@Override
public ManagementOverrides getOverrides() {
return this.managementOverrides;
}
@Override
public boolean send(Message<?> message) {
if (this.loggingEnabled && this.logger.isDebugEnabled()) {

View File

@@ -153,6 +153,7 @@ public final class IntegrationFlows {
* Provides {@link Supplier} as source of messages to the integration flow which will
* be triggered by the application context's default poller (which must be declared).
* @param messageSource the {@link Supplier} to populate.
* @param <T> the supplier type.
* @return new {@link IntegrationFlowBuilder}.
* @see Supplier
*/
@@ -166,10 +167,12 @@ public final class IntegrationFlows {
* @param messageSource the {@link Supplier} to populate.
* @param endpointConfigurer the {@link Consumer} to provide more options for the
* {@link org.springframework.integration.config.SourcePollingChannelAdapterFactoryBean}.
* @param <T> the supplier type.
* @return new {@link IntegrationFlowBuilder}.
* @see Supplier
*/
public static <T> IntegrationFlowBuilder from(Supplier<T> messageSource, Consumer<SourcePollingChannelAdapterSpec> endpointConfigurer) {
public static <T> IntegrationFlowBuilder from(Supplier<T> messageSource,
Consumer<SourcePollingChannelAdapterSpec> endpointConfigurer) {
return from(messageSource, "get", endpointConfigurer);
}

View File

@@ -45,6 +45,8 @@ public abstract class AbstractMessageSource<T> extends AbstractExpressionEvaluat
private final AtomicLong messageCount = new AtomicLong();
private final ManagementOverrides managementOverrides = new ManagementOverrides();
private volatile Map<String, Expression> headerExpressions = Collections.emptyMap();
private volatile String beanName;
@@ -100,6 +102,7 @@ public abstract class AbstractMessageSource<T> extends AbstractExpressionEvaluat
@Override
public void setCountsEnabled(boolean countsEnabled) {
this.countsEnabled = countsEnabled;
this.managementOverrides.countsConfigured = true;
}
@Override
@@ -110,6 +113,7 @@ public abstract class AbstractMessageSource<T> extends AbstractExpressionEvaluat
@Override
public void setLoggingEnabled(boolean loggingEnabled) {
this.loggingEnabled = loggingEnabled;
this.managementOverrides.loggingConfigured = true;
}
@Override
@@ -127,6 +131,11 @@ public abstract class AbstractMessageSource<T> extends AbstractExpressionEvaluat
return this.messageCount.get();
}
@Override
public ManagementOverrides getOverrides() {
return this.managementOverrides;
}
@Override
public final Message<T> receive() {
return buildMessage(doReceive());

View File

@@ -87,6 +87,8 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint
private final AtomicLong messageCount = new AtomicLong();
private final ManagementOverrides managementOverrides = new ManagementOverrides();
private ErrorMessageStrategy errorMessageStrategy = new DefaultErrorMessageStrategy();
private volatile MessageChannel requestChannel;
@@ -291,6 +293,7 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint
@Override
public void setLoggingEnabled(boolean enabled) {
this.loggingEnabled = enabled;
this.managementOverrides.loggingConfigured = true;
}
@Override
@@ -301,6 +304,7 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint
@Override
public void setCountsEnabled(boolean countsEnabled) {
this.countsEnabled = countsEnabled;
this.managementOverrides.countsConfigured = true;
}
@Override
@@ -319,6 +323,11 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint
this.errorMessageStrategy = errorMessageStrategy;
}
@Override
public ManagementOverrides getOverrides() {
return this.managementOverrides;
}
@Override
protected void onInit() throws Exception {
Assert.state(!(this.requestChannelName != null && this.requestChannel != null),

View File

@@ -53,6 +53,8 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport im
MessageHandlerMetrics, ConfigurableMetricsAware<AbstractMessageHandlerMetrics>, TrackableComponent, Orderable,
CoreSubscriber<Message<?>> {
private final ManagementOverrides managementOverrides = new ManagementOverrides();
private volatile boolean shouldTrack = false;
private volatile int order = Ordered.LOWEST_PRECEDENCE;
@@ -77,6 +79,7 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport im
@Override
public void setLoggingEnabled(boolean loggingEnabled) {
this.loggingEnabled = loggingEnabled;
this.managementOverrides.loggingConfigured = true;
}
@Override
@@ -103,6 +106,12 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport im
public void configureMetrics(AbstractMessageHandlerMetrics metrics) {
Assert.notNull(metrics, "'metrics' must not be null");
this.handlerMetrics = metrics;
this.managementOverrides.metricsConfigured = true;
}
@Override
public ManagementOverrides getOverrides() {
return this.managementOverrides;
}
@Override
@@ -232,11 +241,13 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport im
public void setStatsEnabled(boolean statsEnabled) {
if (statsEnabled) {
this.countsEnabled = true;
this.managementOverrides.countsConfigured = true;
}
this.statsEnabled = statsEnabled;
if (this.handlerMetrics != null) {
this.handlerMetrics.setFullStatsEnabled(statsEnabled);
}
this.managementOverrides.statsConfigured = true;
}
@Override
@@ -247,8 +258,10 @@ public abstract class AbstractMessageHandler extends IntegrationObjectSupport im
@Override
public void setCountsEnabled(boolean countsEnabled) {
this.countsEnabled = countsEnabled;
this.managementOverrides.countsConfigured = true;
if (!countsEnabled) {
this.statsEnabled = false;
this.managementOverrides.statsConfigured = true;
}
}

View File

@@ -43,4 +43,30 @@ public interface IntegrationManagement {
@ManagedAttribute
boolean isCountsEnabled();
/**
* Return the overrides.
* @return the overrides.
* @since 5.0
*/
ManagementOverrides getOverrides();
/**
* Toggles to inform the management configurer to not set these properties since
* the user has manually configured them in a bean definition. If true, the
* corresponding property will not be set by the configurer.
*
* @since 5.0
*/
class ManagementOverrides {
public boolean loggingConfigured;
public boolean countsConfigured;
public boolean statsConfigured;
public boolean metricsConfigured;
}
}

View File

@@ -29,6 +29,7 @@ import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.integration.support.management.IntegrationManagement.ManagementOverrides;
import org.springframework.util.Assert;
import org.springframework.util.PatternMatchUtils;
import org.springframework.util.StringUtils;
@@ -206,7 +207,9 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
Map<String, IntegrationManagement> managed = this.applicationContext.getBeansOfType(IntegrationManagement.class);
for (Entry<String, IntegrationManagement> entry : managed.entrySet()) {
IntegrationManagement bean = entry.getValue();
bean.setLoggingEnabled(this.defaultLoggingEnabled);
if (!bean.getOverrides().loggingConfigured) {
bean.setLoggingEnabled(this.defaultLoggingEnabled);
}
if (bean instanceof MessageChannelMetrics) {
configureChannelMetrics(entry.getKey(), (MessageChannelMetrics) bean);
}
@@ -223,12 +226,15 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
private void configureChannelMetrics(String name, MessageChannelMetrics bean) {
AbstractMessageChannelMetrics metrics = this.metricsFactory.createChannelMetrics(name);
Assert.state(metrics != null, "'metrics' must not be null");
ManagementOverrides overrides = bean.getOverrides();
Boolean enabled = smartMatch(this.enabledCountsPatterns, name);
if (enabled != null) {
bean.setCountsEnabled(enabled);
}
else {
bean.setCountsEnabled(this.defaultCountsEnabled);
if (!overrides.countsConfigured) {
bean.setCountsEnabled(this.defaultCountsEnabled);
}
}
enabled = smartMatch(this.enabledStatsPatterns, name);
if (enabled != null) {
@@ -236,10 +242,12 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
metrics.setFullStatsEnabled(enabled);
}
else {
bean.setStatsEnabled(this.defaultStatsEnabled);
metrics.setFullStatsEnabled(this.defaultStatsEnabled);
if (!overrides.statsConfigured) {
bean.setStatsEnabled(this.defaultStatsEnabled);
metrics.setFullStatsEnabled(this.defaultStatsEnabled);
}
}
if (bean instanceof ConfigurableMetricsAware) {
if (bean instanceof ConfigurableMetricsAware && !overrides.metricsConfigured) {
((ConfigurableMetricsAware<AbstractMessageChannelMetrics>) bean).configureMetrics(metrics);
}
this.channelsByName.put(name, bean);
@@ -249,12 +257,15 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
private void configureHandlerMetrics(String name, MessageHandlerMetrics bean) {
AbstractMessageHandlerMetrics metrics = this.metricsFactory.createHandlerMetrics(name);
Assert.state(metrics != null, "'metrics' must not be null");
ManagementOverrides overrides = bean.getOverrides();
Boolean enabled = smartMatch(this.enabledCountsPatterns, name);
if (enabled != null) {
bean.setCountsEnabled(enabled);
}
else {
bean.setCountsEnabled(this.defaultCountsEnabled);
if (!overrides.countsConfigured) {
bean.setCountsEnabled(this.defaultCountsEnabled);
}
}
enabled = smartMatch(this.enabledStatsPatterns, name);
if (enabled != null) {
@@ -262,10 +273,12 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
metrics.setFullStatsEnabled(enabled);
}
else {
bean.setStatsEnabled(this.defaultStatsEnabled);
metrics.setFullStatsEnabled(this.defaultStatsEnabled);
if (!overrides.statsConfigured) {
bean.setStatsEnabled(this.defaultStatsEnabled);
metrics.setFullStatsEnabled(this.defaultStatsEnabled);
}
}
if (bean instanceof ConfigurableMetricsAware) {
if (bean instanceof ConfigurableMetricsAware && !overrides.metricsConfigured) {
((ConfigurableMetricsAware<AbstractMessageHandlerMetrics>) bean).configureMetrics(metrics);
}
@@ -278,7 +291,9 @@ public class IntegrationManagementConfigurer implements SmartInitializingSinglet
bean.setCountsEnabled(enabled);
}
else {
bean.setCountsEnabled(this.defaultCountsEnabled);
if (!bean.getOverrides().countsConfigured) {
bean.setCountsEnabled(this.defaultCountsEnabled);
}
}
this.sourcesByName.put(bean.getManagedName() != null ? bean.getManagedName() : name, bean);
}

View File

@@ -182,4 +182,9 @@ public class LifecycleMessageHandlerMetrics implements MessageHandlerMetrics, Li
this.delegate.setManagedType(source);
}
@Override
public ManagementOverrides getOverrides() {
return this.delegate.getOverrides();
}
}

View File

@@ -119,4 +119,9 @@ public class LifecycleMessageSourceMetrics implements MessageSourceMetrics, Life
this.delegate.setManagedType(source);
}
@Override
public ManagementOverrides getOverrides() {
return this.delegate.getOverrides();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2016 the original author or authors.
* Copyright 2015-2017 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.
@@ -50,7 +50,7 @@ import org.springframework.messaging.MessageChannel;
public class IntegrationManagementConfigurerTests {
@Test
public void testLogging() {
public void testDefaults() {
DirectChannel channel = new DirectChannel();
AbstractMessageHandler handler = new RecipientListRouter();
AbstractMessageSource<?> source = new AbstractMessageSource<Object>() {
@@ -68,6 +68,8 @@ public class IntegrationManagementConfigurerTests {
assertTrue(channel.isLoggingEnabled());
assertTrue(handler.isLoggingEnabled());
assertTrue(source.isLoggingEnabled());
channel.setCountsEnabled(true);
channel.setStatsEnabled(true);
ApplicationContext ctx = mock(ApplicationContext.class);
Map<String, IntegrationManagement> beans = new HashMap<String, IntegrationManagement>();
beans.put("foo", channel);
@@ -82,6 +84,8 @@ public class IntegrationManagementConfigurerTests {
assertFalse(channel.isLoggingEnabled());
assertFalse(handler.isLoggingEnabled());
assertFalse(source.isLoggingEnabled());
assertTrue(channel.isCountsEnabled());
assertTrue(channel.isStatsEnabled());
}
@Test
@@ -93,6 +97,8 @@ public class IntegrationManagementConfigurerTests {
assertTrue(channel.isStatsEnabled());
assertThat(TestUtils.getPropertyValue(channel, "channelMetrics"),
instanceOf(DefaultMessageChannelMetrics.class));
channel = ctx.getBean("loggingOffChannel", AbstractMessageChannel.class);
assertFalse(channel.isLoggingEnabled());
ctx.close();
}
@@ -106,6 +112,12 @@ public class IntegrationManagementConfigurerTests {
return new DirectChannel();
}
@Bean
public MessageChannel loggingOffChannel() {
DirectChannel directChannel = new DirectChannel();
directChannel.setLoggingEnabled(false);
return directChannel;
}
}
}