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 : exporter.getHandlerNames()) { - metrics.addAll(getStatistics("integration.handler." + name + ".duration", - exporter.getHandlerDuration(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())); } - metrics.add(new Metric("integration.activeHandlerCount", - exporter.getActiveHandlerCount())); + + 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.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