Refactored PollingDispatcher into separate ChannelPoller and SourcePoller implementations with an AbstractPoller base class.

This commit is contained in:
Mark Fisher
2008-09-07 15:23:17 +00:00
parent f0079d97f2
commit 15f9875b5b
25 changed files with 625 additions and 601 deletions

View File

@@ -34,13 +34,14 @@ import org.springframework.integration.channel.PublishSubscribeChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.endpoint.AbstractInOutEndpoint;
import org.springframework.integration.endpoint.InboundChannelAdapter;
import org.springframework.integration.endpoint.SourcePoller;
import org.springframework.integration.message.ErrorMessage;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageBuilder;
import org.springframework.integration.message.MessagingException;
import org.springframework.integration.message.PollableSource;
import org.springframework.integration.message.StringMessage;
import org.springframework.integration.scheduling.PollingSchedule;
/**
* @author Mark Fisher
@@ -189,20 +190,23 @@ public class DefaultMessageBusTests {
@Test
public void testErrorChannelWithFailedDispatch() throws InterruptedException {
MessageBus bus = new DefaultMessageBus();
QueueChannel errorChannel = new QueueChannel();
errorChannel.setBeanName("errorChannel");
bus.registerChannel(errorChannel);
CountDownLatch latch = new CountDownLatch(1);
InboundChannelAdapter channelAdapter = new InboundChannelAdapter();
channelAdapter.setSource(new FailingSource(latch));
SourcePoller poller = new SourcePoller(new FailingSource(latch), new PollingSchedule(1000));
channelAdapter.setSource(poller);
channelAdapter.setBeanName("testChannel");
bus.registerEndpoint(channelAdapter);
bus.start();
latch.await(2000, TimeUnit.MILLISECONDS);
Message<?> message = ((PollableChannel) bus.getErrorChannel()).receive(5000);
Message<?> message = errorChannel.receive(5000);
bus.stop();
assertNotNull("message should not be null", message);
assertTrue(message instanceof ErrorMessage);
Throwable exception = ((ErrorMessage) message).getPayload();
assertTrue(exception instanceof MessagingException);
assertEquals("intentional test failure", exception.getCause().getMessage());
assertEquals("intentional test failure", exception.getMessage());
}
@Test(expected = BeanCreationException.class)

View File

@@ -77,7 +77,7 @@ public class BroadcastingDispatcherTests {
dispatcher.subscribe(targetMock1);
expect(targetMock1.send(messageMock)).andReturn(true);
replay(globalMocks);
dispatcher.send(messageMock);
dispatcher.dispatch(messageMock);
verify(globalMocks);
}
@@ -86,7 +86,7 @@ public class BroadcastingDispatcherTests {
dispatcher.subscribe(targetMock1);
expect(targetMock1.send(messageMock)).andReturn(true);
replay(globalMocks);
dispatcher.send(messageMock);
dispatcher.dispatch(messageMock);
verify(globalMocks);
}
@@ -100,7 +100,7 @@ public class BroadcastingDispatcherTests {
expect(targetMock2.send(messageMock)).andReturn(true);
expect(targetMock3.send(messageMock)).andReturn(true);
replay(globalMocks);
dispatcher.send(messageMock);
dispatcher.dispatch(messageMock);
verify(globalMocks);
}
@@ -113,7 +113,7 @@ public class BroadcastingDispatcherTests {
expect(targetMock2.send(messageMock)).andReturn(true);
expect(targetMock3.send(messageMock)).andReturn(true);
replay(globalMocks);
dispatcher.send(messageMock);
dispatcher.dispatch(messageMock);
verify(globalMocks);
}
@@ -127,7 +127,7 @@ public class BroadcastingDispatcherTests {
expect(targetMock2.send(messageMock)).andReturn(true);
expect(targetMock3.send(messageMock)).andReturn(true);
replay(globalMocks);
dispatcher.send(messageMock);
dispatcher.dispatch(messageMock);
verify(globalMocks);
}
@@ -141,7 +141,7 @@ public class BroadcastingDispatcherTests {
expect(targetMock1.send(messageMock)).andReturn(true);
expect(targetMock3.send(messageMock)).andReturn(true);
replay(globalMocks);
dispatcher.send(messageMock);
dispatcher.dispatch(messageMock);
verify(globalMocks);
}
@@ -155,7 +155,7 @@ public class BroadcastingDispatcherTests {
expect(targetMock1.send(messageMock)).andReturn(true);
expect(targetMock2.send(messageMock)).andReturn(true);
replay(globalMocks);
dispatcher.send(messageMock);
dispatcher.dispatch(messageMock);
verify(globalMocks);
}
@@ -167,7 +167,7 @@ public class BroadcastingDispatcherTests {
dispatcher.subscribe(targetMock3);
partialFailingExecutorMock(false, false, false);
replay(globalMocks);
dispatcher.send(messageMock);
dispatcher.dispatch(messageMock);
verify(globalMocks);
}
@@ -178,7 +178,7 @@ public class BroadcastingDispatcherTests {
dispatcher.subscribe(targetMock1);
expect(targetMock1.send(messageMock)).andReturn(true);
replay(globalMocks);
dispatcher.send(messageMock);
dispatcher.dispatch(messageMock);
verify(globalMocks);
}
@@ -191,7 +191,7 @@ public class BroadcastingDispatcherTests {
expect(targetMock1.send(messageMock)).andReturn(true);
expect(targetMock3.send(messageMock)).andReturn(true);
replay(globalMocks);
dispatcher.send(messageMock);
dispatcher.dispatch(messageMock);
verify(globalMocks);
}
@@ -204,9 +204,9 @@ public class BroadcastingDispatcherTests {
expect(targetMock2.send(messageMock)).andReturn(true);
expect(targetMock3.send(messageMock)).andReturn(true).times(2);
replay(globalMocks);
dispatcher.send(messageMock);
dispatcher.dispatch(messageMock);
dispatcher.unsubscribe(targetMock2);
dispatcher.send(messageMock);
dispatcher.dispatch(messageMock);
verify(globalMocks);
}
@@ -218,7 +218,7 @@ public class BroadcastingDispatcherTests {
MessageEndpoint target2 = new MessageStoringTestEndpoint(messages);
dispatcher.subscribe(target1);
dispatcher.subscribe(target2);
dispatcher.send(new StringMessage("test"));
dispatcher.dispatch(new StringMessage("test"));
assertEquals(2, messages.size());
assertEquals(0, (int) messages.get(0).getHeaders().getSequenceNumber());
assertEquals(0, (int) messages.get(0).getHeaders().getSequenceSize());
@@ -237,7 +237,7 @@ public class BroadcastingDispatcherTests {
dispatcher.subscribe(target1);
dispatcher.subscribe(target2);
dispatcher.subscribe(target3);
dispatcher.send(new StringMessage("test"));
dispatcher.dispatch(new StringMessage("test"));
assertEquals(3, messages.size());
assertEquals(1, (int) messages.get(0).getHeaders().getSequenceNumber());
assertEquals(3, (int) messages.get(0).getHeaders().getSequenceSize());

View File

@@ -1,128 +0,0 @@
/*
* Copyright 2002-2008 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.dispatcher;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;
import org.junit.Before;
import org.junit.Test;
import org.springframework.integration.dispatcher.MessageDispatcher;
import org.springframework.integration.dispatcher.PollingDispatcher;
import org.springframework.integration.message.BlockingSource;
import org.springframework.integration.message.Message;
import org.springframework.integration.scheduling.Schedule;
/**
* @author Iwein Fuld
*/
@SuppressWarnings("unchecked")
public class PollingDispatcherTests {
private PollingDispatcher pollingDispatcher;
private Schedule scheduleMock = createMock(Schedule.class);
private MessageDispatcher dispatcherMock = createMock(MessageDispatcher.class);
private BlockingSource sourceMock = createMock(BlockingSource.class);
private Message messageMock = createMock(Message.class);
private Object[] globalMocks = new Object[] { scheduleMock, dispatcherMock, sourceMock, messageMock };
@Before
public void init() {
pollingDispatcher = new PollingDispatcher(sourceMock, scheduleMock, dispatcherMock);
pollingDispatcher.setReceiveTimeout(-1);
reset(globalMocks);
}
@Test
public void singleMessage() {
expect(sourceMock.receive()).andReturn(messageMock);
expect(dispatcherMock.send(messageMock)).andReturn(true);
replay(globalMocks);
pollingDispatcher.setMaxMessagesPerPoll(1);
pollingDispatcher.run();
verify(globalMocks);
}
@Test
public void multipleMessages() {
expect(sourceMock.receive()).andReturn(messageMock).times(5);
expect(dispatcherMock.send(messageMock)).andReturn(true).times(5);
replay(globalMocks);
pollingDispatcher.setMaxMessagesPerPoll(5);
pollingDispatcher.run();
verify(globalMocks);
}
@Test
public void multipleMessages_underrun() {
expect(sourceMock.receive()).andReturn(messageMock).times(5);
expect(sourceMock.receive()).andReturn(null);
expect(dispatcherMock.send(messageMock)).andReturn(true).times(5);
replay(globalMocks);
pollingDispatcher.setMaxMessagesPerPoll(6);
pollingDispatcher.run();
verify(globalMocks);
}
@Test
public void droppedMessage() {
expect(sourceMock.receive()).andReturn(messageMock);
expect(dispatcherMock.send(messageMock)).andReturn(false);
replay(globalMocks);
pollingDispatcher.run();
verify(globalMocks);
}
@Test
public void droppedMessage_onePerPoll() {
expect(sourceMock.receive()).andReturn(messageMock).times(1);
expect(dispatcherMock.send(messageMock)).andReturn(false).anyTimes();
replay(globalMocks);
pollingDispatcher.setMaxMessagesPerPoll(10);
pollingDispatcher.run();
verify(globalMocks);
}
@Test
public void blockingSourceTimedOut() {
pollingDispatcher = new PollingDispatcher(sourceMock, scheduleMock, dispatcherMock);
// we don't need to await the timeout, returning null suffices
expect(sourceMock.receive(1)).andReturn(null);
replay(globalMocks);
pollingDispatcher.setReceiveTimeout(1);
pollingDispatcher.run();
verify(globalMocks);
}
@Test
public void blockingSourceNotTimedOut() {
pollingDispatcher = new PollingDispatcher(sourceMock, scheduleMock, dispatcherMock);
expect(sourceMock.receive(1)).andReturn(messageMock);
expect(dispatcherMock.send(messageMock)).andReturn(false);
replay(globalMocks);
pollingDispatcher.setReceiveTimeout(1);
pollingDispatcher.run();
verify(globalMocks);
}
}

View File

@@ -47,7 +47,7 @@ public class SimpleDispatcherTests {
SimpleDispatcher dispatcher = new SimpleDispatcher();
final CountDownLatch latch = new CountDownLatch(1);
dispatcher.subscribe(createEndpoint(TestHandlers.countDownHandler(latch)));
dispatcher.send(new StringMessage("test"));
dispatcher.dispatch(new StringMessage("test"));
latch.await(500, TimeUnit.MILLISECONDS);
assertEquals(0, latch.getCount());
}
@@ -60,7 +60,7 @@ public class SimpleDispatcherTests {
final AtomicInteger counter2 = new AtomicInteger();
dispatcher.subscribe(createEndpoint(TestHandlers.countingCountDownHandler(counter1, latch)));
dispatcher.subscribe(createEndpoint(TestHandlers.countingCountDownHandler(counter2, latch)));
dispatcher.send(new StringMessage("test"));
dispatcher.dispatch(new StringMessage("test"));
latch.await(500, TimeUnit.MILLISECONDS);
assertEquals(0, latch.getCount());
assertEquals("only 1 handler should have received the message", 1, counter1.get() + counter2.get());
@@ -73,7 +73,7 @@ public class SimpleDispatcherTests {
MessageEndpoint target = new CountingTestEndpoint(counter, false);
dispatcher.subscribe(target);
dispatcher.subscribe(target);
dispatcher.send(new StringMessage("test"));
dispatcher.dispatch(new StringMessage("test"));
assertEquals("target should not have duplicate subscriptions", 1, counter.get());
}
@@ -88,7 +88,7 @@ public class SimpleDispatcherTests {
dispatcher.subscribe(target2);
dispatcher.subscribe(target3);
dispatcher.unsubscribe(target2);
dispatcher.send(new StringMessage("test"));
dispatcher.dispatch(new StringMessage("test"));
assertEquals(2, counter.get());
}
@@ -102,13 +102,13 @@ public class SimpleDispatcherTests {
dispatcher.subscribe(target1);
dispatcher.subscribe(target2);
dispatcher.subscribe(target3);
dispatcher.send(new StringMessage("test1"));
dispatcher.dispatch(new StringMessage("test1"));
assertEquals(3, counter.get());
dispatcher.unsubscribe(target2);
dispatcher.send(new StringMessage("test2"));
dispatcher.dispatch(new StringMessage("test2"));
assertEquals(5, counter.get());
dispatcher.unsubscribe(target1);
dispatcher.send(new StringMessage("test3"));
dispatcher.dispatch(new StringMessage("test3"));
assertEquals(6, counter.get());
}
@@ -118,10 +118,10 @@ public class SimpleDispatcherTests {
final AtomicInteger counter = new AtomicInteger();
MessageEndpoint target = new CountingTestEndpoint(counter, false);
dispatcher.subscribe(target);
dispatcher.send(new StringMessage("test1"));
dispatcher.dispatch(new StringMessage("test1"));
assertEquals(1, counter.get());
dispatcher.unsubscribe(target);
dispatcher.send(new StringMessage("test2"));
dispatcher.dispatch(new StringMessage("test2"));
}
@Test
@@ -141,7 +141,7 @@ public class SimpleDispatcherTests {
dispatcher.subscribe(endpoint1);
dispatcher.subscribe(endpoint2);
dispatcher.subscribe(endpoint3);
dispatcher.send(new StringMessage("test"));
dispatcher.dispatch(new StringMessage("test"));
assertEquals(0, latch.getCount());
assertEquals("selectors should have been invoked one time each", 3, selectorCounter.get());
assertEquals("handler with rejecting selector should not have received the message", 0, counter1.get());
@@ -168,7 +168,7 @@ public class SimpleDispatcherTests {
dispatcher.subscribe(endpoint3);
boolean exceptionThrown = false;
try {
dispatcher.send(new StringMessage("test"));
dispatcher.dispatch(new StringMessage("test"));
}
catch (MessageRejectedException e) {
exceptionThrown = true;
@@ -190,7 +190,7 @@ public class SimpleDispatcherTests {
dispatcher.subscribe(target1);
dispatcher.subscribe(target2);
dispatcher.subscribe(target3);
assertTrue(dispatcher.send(new StringMessage("test")));
assertTrue(dispatcher.dispatch(new StringMessage("test")));
assertEquals("only the first target should have been invoked", 1, counter.get());
}
@@ -204,7 +204,7 @@ public class SimpleDispatcherTests {
dispatcher.subscribe(target1);
dispatcher.subscribe(target2);
dispatcher.subscribe(target3);
assertTrue(dispatcher.send(new StringMessage("test")));
assertTrue(dispatcher.dispatch(new StringMessage("test")));
assertEquals("first two targets should have been invoked", 2, counter.get());
}
@@ -218,7 +218,7 @@ public class SimpleDispatcherTests {
dispatcher.subscribe(target1);
dispatcher.subscribe(target2);
dispatcher.subscribe(target3);
assertFalse(dispatcher.send(new StringMessage("test")));
assertFalse(dispatcher.dispatch(new StringMessage("test")));
assertEquals("each target should have been invoked", 3, counter.get());
}

View File

@@ -0,0 +1,131 @@
/*
* Copyright 2002-2008 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.endpoint;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;
import org.junit.Before;
import org.junit.Test;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.endpoint.ChannelPoller;
import org.springframework.integration.endpoint.MessageEndpoint;
import org.springframework.integration.message.Message;
import org.springframework.integration.scheduling.Schedule;
/**
* @author Iwein Fuld
*/
@SuppressWarnings("unchecked")
public class ChannelPollerTests {
private ChannelPoller poller;
private Schedule scheduleMock = createMock(Schedule.class);
private PollableChannel channelMock = createMock(PollableChannel.class);
private MessageEndpoint endpointMock = createMock(MessageEndpoint.class);
private Message messageMock = createMock(Message.class);
private Object[] globalMocks = new Object[] { scheduleMock, channelMock, endpointMock, messageMock };
@Before
public void init() {
poller = new ChannelPoller(channelMock, scheduleMock);
poller.subscribe(endpointMock);
poller.setReceiveTimeout(-1);
reset(globalMocks);
}
@Test
public void singleMessage() {
expect(channelMock.receive()).andReturn(messageMock);
expect(endpointMock.send(messageMock)).andReturn(true);
replay(globalMocks);
poller.setMaxMessagesPerPoll(1);
poller.run();
verify(globalMocks);
}
@Test
public void multipleMessages() {
expect(channelMock.receive()).andReturn(messageMock).times(5);
expect(endpointMock.send(messageMock)).andReturn(true).times(5);
replay(globalMocks);
poller.setMaxMessagesPerPoll(5);
poller.run();
verify(globalMocks);
}
@Test
public void multipleMessages_underrun() {
expect(channelMock.receive()).andReturn(messageMock).times(5);
expect(channelMock.receive()).andReturn(null);
expect(endpointMock.send(messageMock)).andReturn(true).times(5);
replay(globalMocks);
poller.setMaxMessagesPerPoll(6);
poller.run();
verify(globalMocks);
}
@Test
public void droppedMessage() {
expect(channelMock.receive()).andReturn(messageMock);
expect(endpointMock.send(messageMock)).andReturn(false);
replay(globalMocks);
poller.run();
verify(globalMocks);
}
@Test
public void droppedMessage_onePerPoll() {
expect(channelMock.receive()).andReturn(messageMock).times(1);
expect(endpointMock.send(messageMock)).andReturn(false).anyTimes();
replay(globalMocks);
poller.setMaxMessagesPerPoll(10);
poller.run();
verify(globalMocks);
}
@Test
public void blockingSourceTimedOut() {
poller = new ChannelPoller(channelMock, scheduleMock);
poller.subscribe(endpointMock);
// we don't need to await the timeout, returning null suffices
expect(channelMock.receive(1)).andReturn(null);
replay(globalMocks);
poller.setReceiveTimeout(1);
poller.run();
verify(globalMocks);
}
@Test
public void blockingSourceNotTimedOut() {
poller = new ChannelPoller(channelMock, scheduleMock);
poller.subscribe(endpointMock);
expect(channelMock.receive(1)).andReturn(messageMock);
expect(endpointMock.send(messageMock)).andReturn(false);
replay(globalMocks);
poller.setReceiveTimeout(1);
poller.run();
verify(globalMocks);
}
}

View File

@@ -24,7 +24,6 @@ import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.springframework.integration.bus.DefaultMessageBus;
import org.springframework.integration.dispatcher.PollingDispatcher;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageTarget;
import org.springframework.integration.message.PollableSource;
@@ -52,7 +51,7 @@ public class MessagingBridgeTests {
return new StringMessage("test");
}
};
PollingDispatcher poller = new PollingDispatcher(source, new PollingSchedule(1000));
SourcePoller poller = new SourcePoller(source, new PollingSchedule(1000));
poller.setMaxMessagesPerPoll(1);
bridge.setSource(poller);
bus.registerEndpoint(bridge);