INT-3458: Compatibility with Spring Framework 4.1
JIRA: https://jira.spring.io/browse/INT-3458 * Change Spring AMQP to `1.3.5.RELEASE` * `HttpRequestHandlingEndpointSupport`: remove `MappingJacksonHttpMessageConverter` registration * `IntegrationRequestMappingHandlerMapping`: add 'fake' `name()` attribute to the inline `RequestMapping` annotation * `StoredProcJmxManagedBeanTests`: remove `context.stop();` code, Since `MBeanExporter` deregister MBeans on `stop()` now * `StoredProcPollingChannelAdapterParserTests`: change deprecated `ParameterizedSingleColumnRowMapper` to the `SingleColumnRowMapper` * `Jms`: comment out the reflection code to check the value for the `recoveryInterval`, because it is removed already in favor of `backOff` * `NotificationListeningMessageProducer`: move the start-up listener registration to the `onApplicationEvent`, because `MBeanExporter` moved `registerBeans()` to the `start()` now. The same `phase` might cause the issue, that MBeans aren't registered yet for `NotificationListeningMessageProducer` * `JpaOutboundGatewayTests`: change `@TransactionConfiguration` to the `@Transactional`. Don't know why the first doesn't work now. **Cherry-pick to 4.0.x** INT-3458: Addressing PR comments `NotificationListeningMessageProducer`: defer listener registration until `onApplicationEvent()`
This commit is contained in:
committed by
Gary Russell
parent
5aee3c85ba
commit
c92d7a5da9
@@ -22,6 +22,7 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.management.InstanceNotFoundException;
|
||||
import javax.management.ListenerNotFoundException;
|
||||
@@ -35,6 +36,8 @@ import javax.management.ObjectName;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.integration.endpoint.MessageProducerSupport;
|
||||
import org.springframework.integration.support.AbstractIntegrationMessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
@@ -47,12 +50,16 @@ import org.springframework.util.ObjectUtils;
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
* @since 2.0
|
||||
*/
|
||||
public class NotificationListeningMessageProducer extends MessageProducerSupport implements NotificationListener {
|
||||
public class NotificationListeningMessageProducer extends MessageProducerSupport
|
||||
implements NotificationListener, ApplicationListener<ContextRefreshedEvent> {
|
||||
|
||||
private final Log logger = LogFactory.getLog(this.getClass());
|
||||
|
||||
private final AtomicBoolean listenerRegisteredOnStartup = new AtomicBoolean();
|
||||
|
||||
private volatile MBeanServerConnection server;
|
||||
|
||||
private volatile ObjectName[] objectNames;
|
||||
@@ -128,11 +135,26 @@ public class NotificationListeningMessageProducer extends MessageProducerSupport
|
||||
return "jmx:notification-listening-channel-adapter";
|
||||
}
|
||||
|
||||
/**
|
||||
* The {@link NotificationListener} might not be registered on {@link #start()}
|
||||
* because the {@code MBeanExporter} might not been started yet.
|
||||
* @param event the ContextRefreshedEvent event
|
||||
*/
|
||||
@Override
|
||||
public void onApplicationEvent(ContextRefreshedEvent event) {
|
||||
if (!this.listenerRegisteredOnStartup.getAndSet(true) && isAutoStartup()) {
|
||||
doStart();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the notification listener with the specified ObjectNames.
|
||||
*/
|
||||
@Override
|
||||
protected void doStart() {
|
||||
if (!this.listenerRegisteredOnStartup.get()) {
|
||||
return;
|
||||
}
|
||||
logger.debug("Registering to receive notifications");
|
||||
try {
|
||||
Assert.notNull(this.server, "MBeanServer is required.");
|
||||
@@ -201,4 +223,5 @@ public class NotificationListeningMessageProducer extends MessageProducerSupport
|
||||
}
|
||||
return objectNames;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,8 +32,11 @@ import javax.management.ObjectName;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.jmx.export.MBeanExporter;
|
||||
import org.springframework.jmx.export.notification.NotificationPublisher;
|
||||
@@ -44,6 +47,7 @@ import org.springframework.messaging.Message;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Artem Bilan
|
||||
* @since 2.0
|
||||
*/
|
||||
public class NotificationListeningMessageProducerTests {
|
||||
@@ -83,6 +87,7 @@ public class NotificationListeningMessageProducerTests {
|
||||
adapter.setBeanFactory(mock(BeanFactory.class));
|
||||
adapter.afterPropertiesSet();
|
||||
adapter.start();
|
||||
adapter.onApplicationEvent(new ContextRefreshedEvent(Mockito.mock(ApplicationContext.class)));
|
||||
this.numberHolder.publish("foo");
|
||||
Message<?> message = outputChannel.receive(0);
|
||||
assertNotNull(message);
|
||||
@@ -100,11 +105,12 @@ public class NotificationListeningMessageProducerTests {
|
||||
adapter.setServer(this.server);
|
||||
adapter.setObjectName(this.objectName);
|
||||
adapter.setOutputChannel(outputChannel);
|
||||
Integer handback = new Integer(123);
|
||||
Integer handback = 123;
|
||||
adapter.setHandback(handback);
|
||||
adapter.setBeanFactory(mock(BeanFactory.class));
|
||||
adapter.afterPropertiesSet();
|
||||
adapter.start();
|
||||
adapter.onApplicationEvent(new ContextRefreshedEvent(Mockito.mock(ApplicationContext.class)));
|
||||
this.numberHolder.publish("foo");
|
||||
Message<?> message = outputChannel.receive(0);
|
||||
assertNotNull(message);
|
||||
@@ -132,6 +138,7 @@ public class NotificationListeningMessageProducerTests {
|
||||
adapter.setBeanFactory(mock(BeanFactory.class));
|
||||
adapter.afterPropertiesSet();
|
||||
adapter.start();
|
||||
adapter.onApplicationEvent(new ContextRefreshedEvent(Mockito.mock(ApplicationContext.class)));
|
||||
this.numberHolder.publish("bad");
|
||||
Message<?> message = outputChannel.receive(0);
|
||||
assertNull(message);
|
||||
|
||||
@@ -45,7 +45,8 @@
|
||||
|
||||
<jmx:notification-listening-channel-adapter id="multiAdapter"
|
||||
channel="multiChannel"
|
||||
object-name="#{patterns}"/>
|
||||
object-name="#{patterns}"
|
||||
auto-startup="false"/>
|
||||
|
||||
<util:list id="patterns">
|
||||
<value>org.springframework.integration.jmx.config:type=*,name=testPublisher</value>
|
||||
|
||||
@@ -66,8 +66,12 @@ public class NotificationListeningChannelAdapterParserTests {
|
||||
@Autowired @Qualifier("autoChannel.adapter")
|
||||
private NotificationListeningMessageProducer autoChannelAdapter;
|
||||
|
||||
@Autowired @Qualifier("multiAdapter")
|
||||
private NotificationListeningMessageProducer multiAdapter;
|
||||
|
||||
@Test
|
||||
public void receiveNotification() throws Exception {
|
||||
this.multiAdapter.start();
|
||||
assertNull(channel.receive(0));
|
||||
testPublisher.send("ABC");
|
||||
verifyReceipt(channel, "testPublisher");
|
||||
|
||||
Reference in New Issue
Block a user