diff --git a/spring-integration-core/src/main/java/org/springframework/integration/channel/NullChannel.java b/spring-integration-core/src/main/java/org/springframework/integration/channel/NullChannel.java index 69c8c4c838..a0b3da8784 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/channel/NullChannel.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/channel/NullChannel.java @@ -225,4 +225,9 @@ public class NullChannel implements PollableChannel, MessageChannelMetrics, return this.receive(); } + @Override + public String toString() { + return (this.beanName != null) ? this.beanName : super.toString(); + } + } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/gateway/MessagingGatewaySupport.java b/spring-integration-core/src/main/java/org/springframework/integration/gateway/MessagingGatewaySupport.java index 4fc2f91db0..f1ec9e3966 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/gateway/MessagingGatewaySupport.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/gateway/MessagingGatewaySupport.java @@ -30,6 +30,7 @@ import org.springframework.integration.mapping.OutboundMessageMapper; import org.springframework.integration.support.DefaultMessageBuilderFactory; import org.springframework.integration.support.MessageBuilderFactory; import org.springframework.integration.support.converter.SimpleMessageConverter; +import org.springframework.integration.support.management.IntegrationManagedResource; import org.springframework.integration.support.management.MessageSourceMetrics; import org.springframework.integration.support.management.TrackableComponent; import org.springframework.messaging.Message; @@ -50,6 +51,7 @@ import org.springframework.util.Assert; * @author Gary Russell * @author Artem Bilan */ +@IntegrationManagedResource public abstract class MessagingGatewaySupport extends AbstractEndpoint implements TrackableComponent, MessageSourceMetrics { @@ -313,7 +315,7 @@ public abstract class MessagingGatewaySupport extends AbstractEndpoint } } - protected MessageChannel getRequestChannel() { + public MessageChannel getRequestChannel() { if (this.requestChannelName != null) { synchronized (this) { if (this.requestChannelName != null) { diff --git a/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/IntegrationMBeanExporter.java b/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/IntegrationMBeanExporter.java index d71534df41..e66cc26c66 100644 --- a/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/IntegrationMBeanExporter.java +++ b/spring-integration-jmx/src/main/java/org/springframework/integration/monitor/IntegrationMBeanExporter.java @@ -50,6 +50,7 @@ import org.springframework.integration.context.IntegrationContextUtils; import org.springframework.integration.context.OrderlyShutdownCapable; import org.springframework.integration.core.MessageProducer; import org.springframework.integration.endpoint.AbstractEndpoint; +import org.springframework.integration.gateway.MessagingGatewaySupport; import org.springframework.integration.handler.AbstractMessageProducingHandler; import org.springframework.integration.history.MessageHistoryConfigurer; import org.springframework.integration.support.context.NamedComponent; @@ -981,12 +982,18 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati for (String beanName : names) { endpoint = this.applicationContext.getBean(beanName); Object field = null; - try { - field = extractTarget(getField(endpoint, "source")); + if (monitor instanceof MessagingGatewaySupport && endpoint == monitor) { + field = monitor; } - catch (Exception e) { - logger.trace("Could not get source from bean = " + beanName); + else { + try { + field = extractTarget(getField(endpoint, "source")); + } + catch (Exception e) { + logger.trace("Could not get source from bean = " + beanName); + } } + if (field == monitor) { name = beanName; endpointName = beanName; @@ -1010,12 +1017,20 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati } } } - Object field = getField(target, "outputChannel"); - if (field != null) { - if (!anonymousSourceCounters.containsKey(field)) { - anonymousSourceCounters.put(field, new AtomicLong()); + + Object outputChannel = null; + if (target instanceof MessagingGatewaySupport) { + outputChannel = ((MessagingGatewaySupport) target).getRequestChannel(); + } + else { + outputChannel = getField(target, "outputChannel"); + } + + if (outputChannel != null) { + if (!anonymousSourceCounters.containsKey(outputChannel)) { + anonymousSourceCounters.put(outputChannel, new AtomicLong()); } - AtomicLong count = anonymousSourceCounters.get(field); + AtomicLong count = anonymousSourceCounters.get(outputChannel); long total = count.incrementAndGet(); String suffix = ""; /* @@ -1024,7 +1039,7 @@ public class IntegrationMBeanExporter extends MBeanExporter implements Applicati if (total > 1) { suffix = "#" + total; } - name = field + suffix; + name = outputChannel + suffix; source = "anonymous"; } } diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanRegistrationTests-context.xml b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanRegistrationTests-context.xml index a15390b76b..51d9fb4308 100644 --- a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanRegistrationTests-context.xml +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanRegistrationTests-context.xml @@ -15,20 +15,23 @@ - + - + - + - + + + diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanRegistrationTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanRegistrationTests.java index 6e96f6c148..03878df368 100644 --- a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanRegistrationTests.java +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/config/MBeanRegistrationTests.java @@ -30,6 +30,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.integration.gateway.MessagingGatewaySupport; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @@ -62,6 +63,8 @@ public class MBeanRegistrationTests { // System.err.println(Arrays.asList(server.getMBeanInfo(server.queryNames(new ObjectName("*:type=*Handler,*"), null).iterator().next()).getAttributes())); Set names = server.queryNames(new ObjectName("test.MBeanRegistration:type=IntegrationMBeanExporter,name=integrationMbeanExporter,*"), null); assertEquals(1, names.size()); + names = server.queryNames(new ObjectName("test.MBeanRegistration:*,name=org.springframework.integration.MyGateway"), null); + assertEquals(server.toString(), 1, names.size()); } @Test @@ -83,4 +86,8 @@ public class MBeanRegistrationTests { } } + public static class MyMessagingGateway extends MessagingGatewaySupport { + + } + } diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/configuration/EnableMBeanExportTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/configuration/EnableMBeanExportTests.java index cbddcbd07d..0710f37d5a 100644 --- a/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/configuration/EnableMBeanExportTests.java +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/jmx/configuration/EnableMBeanExportTests.java @@ -133,7 +133,9 @@ public class EnableMBeanExportTests { @Bean public MBeanServerFactoryBean mbeanServer() { - return new MBeanServerFactoryBean(); + MBeanServerFactoryBean mBeanServerFactoryBean = new MBeanServerFactoryBean(); + mBeanServerFactoryBean.setLocateExistingServerIfPossible(true); + return mBeanServerFactoryBean; } @Bean diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/IdempotentReceiverIntegrationTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/IdempotentReceiverIntegrationTests.java index fd2f59583b..2d2aeb7e7c 100644 --- a/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/IdempotentReceiverIntegrationTests.java +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/IdempotentReceiverIntegrationTests.java @@ -28,7 +28,6 @@ import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicInteger; import org.aopalliance.aop.Advice; @@ -76,6 +75,7 @@ import com.hazelcast.core.HazelcastInstance; /** * @author Artem Bilan + * @author Gary Russell * @since 4.1 */ @ContextConfiguration @@ -185,7 +185,9 @@ public class IdempotentReceiverIntegrationTests { @Bean public static MBeanServerFactoryBean mBeanServer() { - return new MBeanServerFactoryBean(); + MBeanServerFactoryBean mBeanServerFactoryBean = new MBeanServerFactoryBean(); + mBeanServerFactoryBean.setLocateExistingServerIfPossible(true); + return mBeanServerFactoryBean; } @Bean diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/MessagingGatewaySupportRegistrationTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/MessagingGatewaySupportRegistrationTests.java new file mode 100644 index 0000000000..4cd14c8dce --- /dev/null +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/MessagingGatewaySupportRegistrationTests.java @@ -0,0 +1,112 @@ +/* + * Copyright 2015 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.integration.monitor; + +import static org.junit.Assert.assertEquals; + +import java.util.Set; + +import javax.management.MBeanServer; +import javax.management.ObjectName; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.integration.channel.NullChannel; +import org.springframework.integration.config.EnableIntegration; +import org.springframework.integration.gateway.MessagingGatewaySupport; +import org.springframework.integration.jmx.config.EnableIntegrationMBeanExport; +import org.springframework.jmx.support.MBeanServerFactoryBean; +import org.springframework.messaging.MessageChannel; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * @author Artem Bilan + * @author Gary Russell + * @since 4.2.1 + */ +@ContextConfiguration +@RunWith(SpringJUnit4ClassRunner.class) +@DirtiesContext +public class MessagingGatewaySupportRegistrationTests { + + @Autowired + private MBeanServer server; + + @Test + public void testHandlerMBeanRegistration() throws Exception { + Set names = this.server + .queryNames(new ObjectName("org.springframework.integration:*,name=testGateway"), null); + assertEquals(1, names.size()); + names = this.server.queryNames(new ObjectName("org.springframework.integration:*,type=MessageSource,name=foo"), + null); + assertEquals(1, names.size()); + names = this.server.queryNames(new ObjectName("org.springframework.integration:*,name=foo#2"), null); + assertEquals(1, names.size()); + } + + @Configuration + @EnableIntegration + // TODO INT-3869 + @EnableIntegrationMBeanExport(server = "server") + public static class ContextConfiguration { + + @Bean + public MessagingGatewaySupport testGateway() { + return new MessagingGatewaySupport() { + + }; + } + + @Bean + public MessageChannel foo() { + return new NullChannel(); + } + + @Bean(name = "org.springframework.integration.foo1") + public MessagingGatewaySupport anonymous1() { + MessagingGatewaySupport messagingGatewaySupport = new MessagingGatewaySupport() { + + }; + messagingGatewaySupport.setRequestChannel(foo()); + return messagingGatewaySupport; + } + + @Bean(name = "org.springframework.integration.foo2") + public MessagingGatewaySupport anonymous2() { + MessagingGatewaySupport messagingGatewaySupport = new MessagingGatewaySupport() { + + }; + messagingGatewaySupport.setRequestChannelName("foo"); + return messagingGatewaySupport; + } + + @Bean + public MBeanServerFactoryBean server() { + MBeanServerFactoryBean fb = new MBeanServerFactoryBean(); + fb.setLocateExistingServerIfPossible(true); + return fb; + } + + } + +} diff --git a/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/ScatterGatherHandlerIntegrationTests.java b/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/ScatterGatherHandlerIntegrationTests.java index 3cb22e8e52..d87319d233 100644 --- a/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/ScatterGatherHandlerIntegrationTests.java +++ b/spring-integration-jmx/src/test/java/org/springframework/integration/monitor/ScatterGatherHandlerIntegrationTests.java @@ -128,7 +128,9 @@ public class ScatterGatherHandlerIntegrationTests { @Bean public static MBeanServerFactoryBean mBeanServer() { - return new MBeanServerFactoryBean(); + MBeanServerFactoryBean mBeanServerFactoryBean = new MBeanServerFactoryBean(); + mBeanServerFactoryBean.setLocateExistingServerIfPossible(true); + return mBeanServerFactoryBean; } @Bean