From d69e43b43303c67f0f7c1a3a482e182adbe0218a Mon Sep 17 00:00:00 2001 From: Artem Bilan Date: Wed, 21 Dec 2016 15:13:59 -0500 Subject: [PATCH 1/2] Refactor Spring Integration metrics support Update Spring Integration metrics support since Spring Integration `4.3.6`+ no longer needs `spring-integration-jmx` enable `MessageChannel`, `MessageHandler` and `MessageSource` metrics. - Add `IntegrationManagementConfiguration` conditional auto-configuration to provide `@EnableIntegrationManagement` when JMX is `enabled` or there is no `IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME` bean. By default this bean doesn't exist and you explicitly should declare it (e.g. via `@EnableIntegrationManagement`) if you would like to collect metrics. At the same time Spring Integration enables it when JMX management is present (that is a purpose of that new `IntegrationManagementConfiguration`) - Change `SpringIntegrationMetricReader` to read metrics from the `IntegrationManagementConfigurer`, not `IntegrationMBeanExporter` - Change `PublicMetricsAutoConfiguration` to register `IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME` bean if not present. Since we are here in `actuator`, therefore we are interested in the metrics for SI as well. - Since we don't need JMX for the metrics any more, remove SI-JMX dependency from the `spring-boot-starter-integration`. - Remove `IntegrationManagementConfiguration` modification from the `integrationMbeanExporter()`, since that looks like mutation of an external object, when end-user would prefer their own options. Therefore we don't need `ObjectProvider`, too - Add missed `MessageSourceMetrics` gathering for the `SpringIntegrationMetricReader` Closes gh-7722 --- spring-boot-actuator/pom.xml | 10 +-- .../PublicMetricsAutoConfiguration.java | 23 +++++-- .../SpringIntegrationMetricReader.java | 69 +++++++++++-------- ...ringIntegrationMetricReaderNoJmxTests.java | 61 ++++++++++++++++ .../SpringIntegrationMetricReaderTests.java | 7 +- .../IntegrationAutoConfiguration.java | 34 ++++----- .../IntegrationAutoConfigurationTests.java | 3 + .../spring-boot-starter-integration/pom.xml | 4 -- .../main/resources/META-INF/spring.provides | 2 +- 9 files changed, 151 insertions(+), 62 deletions(-) create mode 100644 spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderNoJmxTests.java diff --git a/spring-boot-actuator/pom.xml b/spring-boot-actuator/pom.xml index 75fa518e090..fd1b4292448 100644 --- a/spring-boot-actuator/pom.xml +++ b/spring-boot-actuator/pom.xml @@ -193,11 +193,6 @@ - - org.springframework.integration - spring-integration-jmx - true - org.springframework.integration spring-integration-core @@ -373,5 +368,10 @@ snakeyaml test + + org.springframework.integration + spring-integration-jmx + test + diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfiguration.java index 2aa3aa126c0..387103fa146 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfiguration.java @@ -46,13 +46,15 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnJava; import org.springframework.boot.autoconfigure.condition.ConditionalOnJava.JavaVersion; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.condition.SearchStrategy; import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvider; import org.springframework.cache.CacheManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.integration.monitor.IntegrationMBeanExporter; +import org.springframework.integration.config.EnableIntegrationManagement; +import org.springframework.integration.support.management.IntegrationManagementConfigurer; import org.springframework.lang.UsesJava7; /** @@ -61,6 +63,7 @@ import org.springframework.lang.UsesJava7; * @author Stephane Nicoll * @author Phillip Webb * @author Johannes Edmeier + * @author Artem Bilan * @since 1.2.0 */ @Configuration @@ -139,18 +142,28 @@ public class PublicMetricsAutoConfiguration { } @Configuration - @ConditionalOnClass(IntegrationMBeanExporter.class) - @ConditionalOnBean(IntegrationMBeanExporter.class) + @ConditionalOnClass(EnableIntegrationManagement.class) @ConditionalOnJava(JavaVersion.SEVEN) @UsesJava7 static class IntegrationMetricsConfiguration { + @Bean(name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME) + @ConditionalOnMissingBean(value = IntegrationManagementConfigurer.class, + name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME, + search = SearchStrategy.CURRENT) + public IntegrationManagementConfigurer managementConfigurer() { + IntegrationManagementConfigurer configurer = new IntegrationManagementConfigurer(); + configurer.setDefaultCountsEnabled(true); + configurer.setDefaultStatsEnabled(true); + return configurer; + } + @Bean @ConditionalOnMissingBean(name = "springIntegrationPublicMetrics") public MetricReaderPublicMetrics springIntegrationPublicMetrics( - IntegrationMBeanExporter exporter) { + IntegrationManagementConfigurer managementConfigurer) { return new MetricReaderPublicMetrics( - new SpringIntegrationMetricReader(exporter)); + new SpringIntegrationMetricReader(managementConfigurer)); } } diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReader.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReader.java index 459a67bafa1..aa1ca45f07b 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReader.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReader.java @@ -22,24 +22,29 @@ import java.util.List; import org.springframework.boot.actuate.metrics.Metric; import org.springframework.boot.actuate.metrics.reader.MetricReader; -import org.springframework.integration.monitor.IntegrationMBeanExporter; +import org.springframework.integration.support.management.IntegrationManagementConfigurer; +import org.springframework.integration.support.management.MessageChannelMetrics; +import org.springframework.integration.support.management.MessageHandlerMetrics; +import org.springframework.integration.support.management.MessageSourceMetrics; +import org.springframework.integration.support.management.PollableChannelManagement; import org.springframework.integration.support.management.Statistics; import org.springframework.lang.UsesJava7; /** * A {@link MetricReader} for Spring Integration metrics (as provided by - * spring-integration-jmx). + * {@link IntegrationManagementConfigurer}). * * @author Dave Syer + * @author Artem Bilan * @since 1.3.0 */ @UsesJava7 public class SpringIntegrationMetricReader implements MetricReader { - private final IntegrationMBeanExporter exporter; + private final IntegrationManagementConfigurer managementConfigurer; - public SpringIntegrationMetricReader(IntegrationMBeanExporter exporter) { - this.exporter = exporter; + public SpringIntegrationMetricReader(IntegrationManagementConfigurer managementConfigurer) { + this.managementConfigurer = managementConfigurer; } @Override @@ -49,31 +54,40 @@ public class SpringIntegrationMetricReader implements MetricReader { @Override public Iterable> findAll() { - IntegrationMBeanExporter exporter = this.exporter; List> metrics = new ArrayList>(); - for (String name : exporter.getChannelNames()) { + + for (String name : this.managementConfigurer.getChannelNames()) { + MessageChannelMetrics channelMetrics = this.managementConfigurer.getChannelMetrics(name); String prefix = "integration.channel." + name; - metrics.addAll(getStatistics(prefix + ".errorRate", - exporter.getChannelErrorRate(name))); - metrics.add(new Metric(prefix + ".sendCount", - exporter.getChannelSendCountLong(name))); - metrics.addAll(getStatistics(prefix + ".sendRate", - exporter.getChannelSendRate(name))); - metrics.add(new Metric(prefix + ".receiveCount", - exporter.getChannelReceiveCountLong(name))); + metrics.addAll(getStatistics(prefix + ".errorRate", channelMetrics.getErrorRate())); + metrics.add(new Metric(prefix + ".sendCount", channelMetrics.getSendCountLong())); + metrics.addAll(getStatistics(prefix + ".sendRate", channelMetrics.getSendRate())); + if (channelMetrics instanceof PollableChannelManagement) { + metrics.add(new Metric(prefix + ".receiveCount", + ((PollableChannelManagement) channelMetrics).getReceiveCountLong())); + } + } + + for (String name : this.managementConfigurer.getHandlerNames()) { + MessageHandlerMetrics handlerMetrics = this.managementConfigurer.getHandlerMetrics(name); + String prefix = "integration.handler." + name; + metrics.addAll(getStatistics(prefix + ".duration", handlerMetrics.getDuration())); + metrics.add(new Metric(prefix + ".activeCount", handlerMetrics.getActiveCountLong())); } - for (String name : exporter.getHandlerNames()) { - metrics.addAll(getStatistics("integration.handler." + name + ".duration", - exporter.getHandlerDuration(name))); + + for (String name : this.managementConfigurer.getSourceNames()) { + MessageSourceMetrics sourceMetrics = this.managementConfigurer.getSourceMetrics(name); + String prefix = "integration.source." + name; + metrics.add(new Metric(prefix + ".messageCount", sourceMetrics.getMessageCountLong())); } - metrics.add(new Metric("integration.activeHandlerCount", - exporter.getActiveHandlerCount())); + metrics.add(new Metric("integration.handlerCount", - exporter.getHandlerCount())); + this.managementConfigurer.getHandlerNames().length)); metrics.add(new Metric("integration.channelCount", - exporter.getChannelCount())); - metrics.add(new Metric("integration.queuedMessageCount", - exporter.getQueuedMessageCount())); + this.managementConfigurer.getChannelNames().length)); + metrics.add(new Metric("integration.sourceCount", + this.managementConfigurer.getSourceNames().length)); + return metrics; } @@ -91,9 +105,10 @@ public class SpringIntegrationMetricReader implements MetricReader { @Override public long count() { - int totalChannelCount = this.exporter.getChannelCount() * 11; - int totalHandlerCount = this.exporter.getHandlerCount() * 5; - return totalChannelCount + totalHandlerCount + 4; + int totalChannelCount = this.managementConfigurer.getChannelNames().length; + int totalHandlerCount = this.managementConfigurer.getHandlerNames().length; + int totalSourceCount = this.managementConfigurer.getSourceNames().length; + return totalChannelCount + totalHandlerCount + totalSourceCount; } } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderNoJmxTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderNoJmxTests.java new file mode 100644 index 00000000000..69aa6ad3fa5 --- /dev/null +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderNoJmxTests.java @@ -0,0 +1,61 @@ +/* + * Copyright 2012-2016 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.actuate.metrics.integration; + + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.boot.actuate.autoconfigure.PublicMetricsAutoConfiguration; +import org.springframework.boot.actuate.endpoint.MetricReaderPublicMetrics; +import org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.junit4.SpringRunner; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link SpringIntegrationMetricReader}. + * + * @author Artem Bilan + */ +@RunWith(SpringRunner.class) +@SpringBootTest("spring.jmx.enabled=false") +@DirtiesContext +public class SpringIntegrationMetricReaderNoJmxTests { + + @Autowired + @Qualifier("springIntegrationPublicMetrics") + private MetricReaderPublicMetrics integrationMetricReader; + + @Test + public void test() { + assertThat(this.integrationMetricReader.metrics().size() > 0).isTrue(); + } + + @Configuration + @Import({IntegrationAutoConfiguration.class, PublicMetricsAutoConfiguration.class}) + protected static class TestConfiguration { + + } + +} diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderTests.java index 9f4ba580ac5..8353e77061b 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderTests.java @@ -26,7 +26,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.integration.monitor.IntegrationMBeanExporter; +import org.springframework.integration.support.management.IntegrationManagementConfigurer; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.junit4.SpringRunner; @@ -36,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat; * Tests for {@link SpringIntegrationMetricReader}. * * @author Dave Syer + * @author Artem Bilan */ @RunWith(SpringRunner.class) @SpringBootTest("spring.jmx.enabled=true") @@ -55,8 +56,8 @@ public class SpringIntegrationMetricReaderTests { protected static class TestConfiguration { @Bean - public SpringIntegrationMetricReader reader(IntegrationMBeanExporter exporter) { - return new SpringIntegrationMetricReader(exporter); + public SpringIntegrationMetricReader reader(IntegrationManagementConfigurer managementConfigurer) { + return new SpringIntegrationMetricReader(managementConfigurer); } } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java index 1f280dc9cf6..7900d7144fe 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java @@ -21,8 +21,6 @@ import javax.management.MBeanServer; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -35,6 +33,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import org.springframework.integration.config.EnableIntegration; +import org.springframework.integration.config.EnableIntegrationManagement; import org.springframework.integration.jmx.config.EnableIntegrationMBeanExport; import org.springframework.integration.monitor.IntegrationMBeanExporter; import org.springframework.integration.support.management.IntegrationManagementConfigurer; @@ -67,17 +66,10 @@ public class IntegrationAutoConfiguration { protected static class IntegrationJmxConfiguration implements EnvironmentAware, BeanFactoryAware { - private final IntegrationManagementConfigurer configurer; - private BeanFactory beanFactory; private RelaxedPropertyResolver propertyResolver; - protected IntegrationJmxConfiguration( - @Qualifier(IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME) ObjectProvider configurerProvider) { - this.configurer = configurerProvider.getIfAvailable(); - } - @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; @@ -100,17 +92,25 @@ public class IntegrationAutoConfiguration { if (StringUtils.hasLength(server)) { exporter.setServer(this.beanFactory.getBean(server, MBeanServer.class)); } - if (this.configurer != null) { - if (this.configurer.getDefaultCountsEnabled() == null) { - this.configurer.setDefaultCountsEnabled(true); - } - if (this.configurer.getDefaultStatsEnabled() == null) { - this.configurer.setDefaultStatsEnabled(true); - } - } return exporter; } } + @Configuration + @ConditionalOnClass({EnableIntegrationManagement.class, EnableIntegrationMBeanExport.class}) + @ConditionalOnMissingBean(value = IntegrationManagementConfigurer.class, + name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME, + search = SearchStrategy.CURRENT) + @ConditionalOnProperty(prefix = "spring.jmx", name = "enabled", havingValue = "true", matchIfMissing = true) + protected static class IntegrationManagementConfiguration { + + @Configuration + @EnableIntegrationManagement(defaultCountsEnabled = "true", defaultStatsEnabled = "true") + protected static class EnableIntegrationManagementConfiguration { + + } + + } + } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java index c5932505bbc..027fff7c402 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java @@ -31,6 +31,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.integration.support.channel.HeaderChannelRegistry; +import org.springframework.integration.support.management.IntegrationManagementConfigurer; import org.springframework.jmx.export.MBeanExporter; import org.springframework.test.context.support.TestPropertySourceUtils; @@ -86,12 +87,14 @@ public class IntegrationAutoConfigurationTests { MBeanServer mBeanServer = this.context.getBean(MBeanServer.class); assertDomains(mBeanServer, true, "org.springframework.integration", "org.springframework.integration.monitor"); + assertThat(this.context.getBean(IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME)).isNotNull(); } @Test public void disableJmxIntegration() { load("spring.jmx.enabled=false"); assertThat(this.context.getBeansOfType(MBeanServer.class)).hasSize(0); + assertThat(this.context.getBeansOfType(IntegrationManagementConfigurer.class)).isEmpty(); } @Test diff --git a/spring-boot-starters/spring-boot-starter-integration/pom.xml b/spring-boot-starters/spring-boot-starter-integration/pom.xml index 5a2a1219b33..18871ee4fad 100644 --- a/spring-boot-starters/spring-boot-starter-integration/pom.xml +++ b/spring-boot-starters/spring-boot-starter-integration/pom.xml @@ -34,9 +34,5 @@ org.springframework.integration spring-integration-java-dsl - - org.springframework.integration - spring-integration-jmx - diff --git a/spring-boot-starters/spring-boot-starter-integration/src/main/resources/META-INF/spring.provides b/spring-boot-starters/spring-boot-starter-integration/src/main/resources/META-INF/spring.provides index 66fb5df913c..63514baf3be 100644 --- a/spring-boot-starters/spring-boot-starter-integration/src/main/resources/META-INF/spring.provides +++ b/spring-boot-starters/spring-boot-starter-integration/src/main/resources/META-INF/spring.provides @@ -1 +1 @@ -provides: spring-integration-core,spring-integration-java-dsl,spring-integration-jmx \ No newline at end of file +provides: spring-integration-core,spring-integration-java-dsl From b87e02dde0573e1b5d6c98a3aa3b002486af0113 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Wed, 21 Dec 2016 15:34:46 -0800 Subject: [PATCH 2/2] Polish Spring Integration metrics support See gh-7722 --- spring-boot-actuator/pom.xml | 10 +- .../PublicMetricsAutoConfiguration.java | 4 +- .../SpringIntegrationMetricReader.java | 101 +++++++++++------- .../PublicMetricsAutoConfigurationTests.java | 2 +- ...ringIntegrationMetricReaderNoJmxTests.java | 3 +- .../SpringIntegrationMetricReaderTests.java | 3 +- .../IntegrationAutoConfiguration.java | 7 +- .../IntegrationAutoConfigurationTests.java | 7 +- 8 files changed, 78 insertions(+), 59 deletions(-) diff --git a/spring-boot-actuator/pom.xml b/spring-boot-actuator/pom.xml index fd1b4292448..bcb23ce3136 100644 --- a/spring-boot-actuator/pom.xml +++ b/spring-boot-actuator/pom.xml @@ -358,6 +358,11 @@ spring-data-rest-webmvc test + + org.springframework.integration + spring-integration-jmx + test + org.springframework.security spring-security-test @@ -368,10 +373,5 @@ snakeyaml test - - org.springframework.integration - spring-integration-jmx - test - diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfiguration.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfiguration.java index 387103fa146..27526cc4ad3 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfiguration.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfiguration.java @@ -148,9 +148,7 @@ public class PublicMetricsAutoConfiguration { static class IntegrationMetricsConfiguration { @Bean(name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME) - @ConditionalOnMissingBean(value = IntegrationManagementConfigurer.class, - name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME, - search = SearchStrategy.CURRENT) + @ConditionalOnMissingBean(value = IntegrationManagementConfigurer.class, name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME, search = SearchStrategy.CURRENT) public IntegrationManagementConfigurer managementConfigurer() { IntegrationManagementConfigurer configurer = new IntegrationManagementConfigurer(); configurer.setDefaultCountsEnabled(true); diff --git a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReader.java b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReader.java index aa1ca45f07b..9ce87767301 100644 --- a/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReader.java +++ b/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReader.java @@ -41,10 +41,10 @@ import org.springframework.lang.UsesJava7; @UsesJava7 public class SpringIntegrationMetricReader implements MetricReader { - private final IntegrationManagementConfigurer managementConfigurer; + private final IntegrationManagementConfigurer configurer; - public SpringIntegrationMetricReader(IntegrationManagementConfigurer managementConfigurer) { - this.managementConfigurer = managementConfigurer; + public SpringIntegrationMetricReader(IntegrationManagementConfigurer configurer) { + this.configurer = configurer; } @Override @@ -54,60 +54,79 @@ public class SpringIntegrationMetricReader implements MetricReader { @Override public Iterable> findAll() { - List> metrics = new ArrayList>(); + List> result = new ArrayList>(); + String[] channelNames = this.configurer.getChannelNames(); + String[] handlerNames = this.configurer.getHandlerNames(); + String[] sourceNames = this.configurer.getSourceNames(); + addChannelMetrics(result, channelNames); + addHandlerMetrics(result, handlerNames); + addSourceMetrics(result, sourceNames); + result.add(new Metric("integration.handlerCount", handlerNames.length)); + result.add(new Metric("integration.channelCount", channelNames.length)); + result.add(new Metric("integration.sourceCount", sourceNames.length)); + return result; + } - for (String name : this.managementConfigurer.getChannelNames()) { - MessageChannelMetrics channelMetrics = this.managementConfigurer.getChannelMetrics(name); - String prefix = "integration.channel." + name; - metrics.addAll(getStatistics(prefix + ".errorRate", channelMetrics.getErrorRate())); - metrics.add(new Metric(prefix + ".sendCount", channelMetrics.getSendCountLong())); - metrics.addAll(getStatistics(prefix + ".sendRate", channelMetrics.getSendRate())); - if (channelMetrics instanceof PollableChannelManagement) { - metrics.add(new Metric(prefix + ".receiveCount", - ((PollableChannelManagement) channelMetrics).getReceiveCountLong())); - } + private void addChannelMetrics(List> result, String[] names) { + for (String name : names) { + addChannelMetrics(result, name, this.configurer.getChannelMetrics(name)); } + } - for (String name : this.managementConfigurer.getHandlerNames()) { - MessageHandlerMetrics handlerMetrics = this.managementConfigurer.getHandlerMetrics(name); - String prefix = "integration.handler." + name; - metrics.addAll(getStatistics(prefix + ".duration", handlerMetrics.getDuration())); - metrics.add(new Metric(prefix + ".activeCount", handlerMetrics.getActiveCountLong())); + private void addChannelMetrics(List> result, String name, + MessageChannelMetrics metrics) { + String prefix = "integration.channel." + name; + result.addAll(getStatistics(prefix + ".errorRate", metrics.getErrorRate())); + result.add(new Metric(prefix + ".sendCount", metrics.getSendCountLong())); + result.addAll(getStatistics(prefix + ".sendRate", metrics.getSendRate())); + if (metrics instanceof PollableChannelManagement) { + result.add(new Metric(prefix + ".receiveCount", + ((PollableChannelManagement) metrics).getReceiveCountLong())); } + } - for (String name : this.managementConfigurer.getSourceNames()) { - MessageSourceMetrics sourceMetrics = this.managementConfigurer.getSourceMetrics(name); - String prefix = "integration.source." + name; - metrics.add(new Metric(prefix + ".messageCount", sourceMetrics.getMessageCountLong())); + private void addHandlerMetrics(List> result, String[] names) { + for (String name : names) { + addHandlerMetrics(result, name, this.configurer.getHandlerMetrics(name)); } + } - metrics.add(new Metric("integration.handlerCount", - this.managementConfigurer.getHandlerNames().length)); - metrics.add(new Metric("integration.channelCount", - this.managementConfigurer.getChannelNames().length)); - metrics.add(new Metric("integration.sourceCount", - this.managementConfigurer.getSourceNames().length)); + private void addHandlerMetrics(List> result, String name, + MessageHandlerMetrics metrics) { + String prefix = "integration.handler." + name; + result.addAll(getStatistics(prefix + ".duration", metrics.getDuration())); + long activeCount = metrics.getActiveCountLong(); + result.add(new Metric(prefix + ".activeCount", activeCount)); + } - return metrics; + private void addSourceMetrics(List> result, String[] names) { + for (String name : names) { + addSourceMetrics(result, name, this.configurer.getSourceMetrics(name)); + } + } + + private void addSourceMetrics(List> result, String name, + MessageSourceMetrics sourceMetrics) { + String prefix = "integration.source." + name; + result.add(new Metric(prefix + ".messageCount", + sourceMetrics.getMessageCountLong())); } - private Collection> getStatistics(String name, - Statistics statistic) { + private Collection> getStatistics(String name, Statistics stats) { List> metrics = new ArrayList>(); - metrics.add(new Metric(name + ".mean", statistic.getMean())); - metrics.add(new Metric(name + ".max", statistic.getMax())); - metrics.add(new Metric(name + ".min", statistic.getMin())); - metrics.add( - new Metric(name + ".stdev", statistic.getStandardDeviation())); - metrics.add(new Metric(name + ".count", statistic.getCountLong())); + metrics.add(new Metric(name + ".mean", stats.getMean())); + metrics.add(new Metric(name + ".max", stats.getMax())); + metrics.add(new Metric(name + ".min", stats.getMin())); + metrics.add(new Metric(name + ".stdev", stats.getStandardDeviation())); + metrics.add(new Metric(name + ".count", stats.getCountLong())); return metrics; } @Override public long count() { - int totalChannelCount = this.managementConfigurer.getChannelNames().length; - int totalHandlerCount = this.managementConfigurer.getHandlerNames().length; - int totalSourceCount = this.managementConfigurer.getSourceNames().length; + int totalChannelCount = this.configurer.getChannelNames().length; + int totalHandlerCount = this.configurer.getHandlerNames().length; + int totalSourceCount = this.configurer.getSourceNames().length; return totalChannelCount + totalHandlerCount + totalSourceCount; } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfigurationTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfigurationTests.java index 3027b7759f0..27c2f4dd14c 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfigurationTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/autoconfigure/PublicMetricsAutoConfigurationTests.java @@ -92,7 +92,7 @@ public class PublicMetricsAutoConfigurationTests { public void metricReaderPublicMetrics() throws Exception { load(); assertThat(this.context.getBeansOfType(MetricReaderPublicMetrics.class)) - .hasSize(1); + .hasSize(2); } @Test diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderNoJmxTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderNoJmxTests.java index 69aa6ad3fa5..18efb7f3597 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderNoJmxTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderNoJmxTests.java @@ -16,7 +16,6 @@ package org.springframework.boot.actuate.metrics.integration; - import org.junit.Test; import org.junit.runner.RunWith; @@ -53,7 +52,7 @@ public class SpringIntegrationMetricReaderNoJmxTests { } @Configuration - @Import({IntegrationAutoConfiguration.class, PublicMetricsAutoConfiguration.class}) + @Import({ IntegrationAutoConfiguration.class, PublicMetricsAutoConfiguration.class }) protected static class TestConfiguration { } diff --git a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderTests.java b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderTests.java index 8353e77061b..f8a01b0903d 100644 --- a/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderTests.java +++ b/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/metrics/integration/SpringIntegrationMetricReaderTests.java @@ -56,7 +56,8 @@ public class SpringIntegrationMetricReaderTests { protected static class TestConfiguration { @Bean - public SpringIntegrationMetricReader reader(IntegrationManagementConfigurer managementConfigurer) { + public SpringIntegrationMetricReader reader( + IntegrationManagementConfigurer managementConfigurer) { return new SpringIntegrationMetricReader(managementConfigurer); } diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java index 7900d7144fe..e5e61e58d71 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfiguration.java @@ -98,10 +98,9 @@ public class IntegrationAutoConfiguration { } @Configuration - @ConditionalOnClass({EnableIntegrationManagement.class, EnableIntegrationMBeanExport.class}) - @ConditionalOnMissingBean(value = IntegrationManagementConfigurer.class, - name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME, - search = SearchStrategy.CURRENT) + @ConditionalOnClass({ EnableIntegrationManagement.class, + EnableIntegrationMBeanExport.class }) + @ConditionalOnMissingBean(value = IntegrationManagementConfigurer.class, name = IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME, search = SearchStrategy.CURRENT) @ConditionalOnProperty(prefix = "spring.jmx", name = "enabled", havingValue = "true", matchIfMissing = true) protected static class IntegrationManagementConfiguration { diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java index 027fff7c402..c42df154aed 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/integration/IntegrationAutoConfigurationTests.java @@ -87,14 +87,17 @@ public class IntegrationAutoConfigurationTests { MBeanServer mBeanServer = this.context.getBean(MBeanServer.class); assertDomains(mBeanServer, true, "org.springframework.integration", "org.springframework.integration.monitor"); - assertThat(this.context.getBean(IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME)).isNotNull(); + Object bean = this.context + .getBean(IntegrationManagementConfigurer.MANAGEMENT_CONFIGURER_NAME); + assertThat(bean).isNotNull(); } @Test public void disableJmxIntegration() { load("spring.jmx.enabled=false"); assertThat(this.context.getBeansOfType(MBeanServer.class)).hasSize(0); - assertThat(this.context.getBeansOfType(IntegrationManagementConfigurer.class)).isEmpty(); + assertThat(this.context.getBeansOfType(IntegrationManagementConfigurer.class)) + .isEmpty(); } @Test