/** * Create an ExecutorChannel with a {@link LoadBalancingStrategy} that * delegates to the provided {@link Executor} when dispatching Messages. * <p> * The Executor must not be null. * @param executor The executor. * @param loadBalancingStrategy The load balancing strategy implementation. */ public ExecutorChannel(Executor executor, LoadBalancingStrategy loadBalancingStrategy) { super(executor); Assert.notNull(executor, "executor must not be null"); UnicastingDispatcher unicastingDispatcher = new UnicastingDispatcher(executor); if (loadBalancingStrategy != null) { this.loadBalancingStrategy = loadBalancingStrategy; unicastingDispatcher.setLoadBalancingStrategy(loadBalancingStrategy); } this.dispatcher = unicastingDispatcher; }
@Override protected AbstractDispatcher createDispatcher() { UnicastingDispatcher unicastingDispatcher = new UnicastingDispatcher(); unicastingDispatcher.setLoadBalancingStrategy(new RoundRobinLoadBalancingStrategy()); return unicastingDispatcher; }
@Test public void pointToPoint() throws InterruptedException { UnicastingDispatcher dispatcher = new UnicastingDispatcher(); final CountDownLatch latch = new CountDownLatch(1); final AtomicInteger counter1 = new AtomicInteger(); final AtomicInteger counter2 = new AtomicInteger(); dispatcher.addHandler(createConsumer(TestHandlers.countingCountDownHandler(counter1, latch))); dispatcher.addHandler(createConsumer(TestHandlers.countingCountDownHandler(counter2, latch))); dispatcher.dispatch(new GenericMessage<>("test")); assertTrue(latch.await(500, TimeUnit.MILLISECONDS)); assertEquals("only 1 handler should have received the message", 1, counter1.get() + counter2.get()); }
private void configureDispatcher(boolean isPubSub) { if (isPubSub) { BroadcastingDispatcher broadcastingDispatcher = new BroadcastingDispatcher(true); broadcastingDispatcher.setBeanFactory(this.getBeanFactory()); this.dispatcher = broadcastingDispatcher; } else { UnicastingDispatcher unicastingDispatcher = new UnicastingDispatcher(); unicastingDispatcher.setLoadBalancingStrategy(new RoundRobinLoadBalancingStrategy()); this.dispatcher = unicastingDispatcher; } if (this.maxSubscribers == null) { this.maxSubscribers = this.getIntegrationProperty(isPubSub ? IntegrationProperties.CHANNELS_MAX_BROADCAST_SUBSCRIBERS : IntegrationProperties.CHANNELS_MAX_UNICAST_SUBSCRIBERS, Integer.class); } this.dispatcher.setMaxSubscribers(this.maxSubscribers); }
@Test public void singleMessage() throws InterruptedException { UnicastingDispatcher dispatcher = new UnicastingDispatcher(); final CountDownLatch latch = new CountDownLatch(1); dispatcher.addHandler(createConsumer(TestHandlers.countDownHandler(latch))); dispatcher.dispatch(new GenericMessage<>("test")); assertTrue(latch.await(500, TimeUnit.MILLISECONDS)); }
@Test public void noDuplicateSubscriptions() { UnicastingDispatcher dispatcher = new UnicastingDispatcher(); final AtomicInteger counter = new AtomicInteger(); MessageHandler target = new CountingTestEndpoint(counter, false); dispatcher.addHandler(target); dispatcher.addHandler(target); try { dispatcher.dispatch(new GenericMessage<>("test")); } catch (Exception e) { // ignore } assertEquals("target should not have duplicate subscriptions", 1, counter.get()); }
@Test(expected = MessageDeliveryException.class) public void removeConsumerLastTargetCausesDeliveryException() { UnicastingDispatcher dispatcher = new UnicastingDispatcher(); final AtomicInteger counter = new AtomicInteger(); MessageHandler target = new CountingTestEndpoint(counter, false); dispatcher.addHandler(target); try { dispatcher.dispatch(new GenericMessage<>("test1")); } catch (Exception e) { // ignore } assertEquals(1, counter.get()); dispatcher.removeHandler(target); dispatcher.dispatch(new GenericMessage<>("test2")); }
@Test public void firstHandlerReturnsTrue() { UnicastingDispatcher dispatcher = new UnicastingDispatcher(); final AtomicInteger counter = new AtomicInteger(); MessageHandler target1 = new CountingTestEndpoint(counter, true); MessageHandler target2 = new CountingTestEndpoint(counter, false); MessageHandler target3 = new CountingTestEndpoint(counter, false); dispatcher.addHandler(target1); dispatcher.addHandler(target2); dispatcher.addHandler(target3); assertTrue(dispatcher.dispatch(new GenericMessage<>("test"))); assertEquals("only the first target should have been invoked", 1, counter.get()); }
@Override public final void onInit() { Assert.state(getDispatcher().getHandlerCount() == 0, "You cannot subscribe() until the channel " + "bean is fully initialized by the framework. Do not subscribe in a @Bean definition"); super.onInit(); if (!(this.executor instanceof ErrorHandlingTaskExecutor)) { ErrorHandler errorHandler = new MessagePublishingErrorHandler( new BeanFactoryChannelResolver(this.getBeanFactory())); this.executor = new ErrorHandlingTaskExecutor(this.executor, errorHandler); } UnicastingDispatcher unicastingDispatcher = new UnicastingDispatcher(this.executor); unicastingDispatcher.setFailover(this.failover); if (this.maxSubscribers == null) { this.maxSubscribers = getIntegrationProperty(IntegrationProperties.CHANNELS_MAX_UNICAST_SUBSCRIBERS, Integer.class); } unicastingDispatcher.setMaxSubscribers(this.maxSubscribers); if (this.loadBalancingStrategy != null) { unicastingDispatcher.setLoadBalancingStrategy(this.loadBalancingStrategy); } unicastingDispatcher.setMessageHandlingTaskDecorator(task -> { if (ExecutorChannel.this.executorInterceptorsSize > 0) { return new MessageHandlingTask(task); } else { return task; } }); this.dispatcher = unicastingDispatcher; }
@Test public void middleHandlerReturnsTrue() { UnicastingDispatcher dispatcher = new UnicastingDispatcher(); final AtomicInteger counter = new AtomicInteger(); MessageHandler target1 = new CountingTestEndpoint(counter, false); MessageHandler target2 = new CountingTestEndpoint(counter, true); MessageHandler target3 = new CountingTestEndpoint(counter, false); dispatcher.addHandler(target1); dispatcher.addHandler(target2); dispatcher.addHandler(target3); assertTrue(dispatcher.dispatch(new GenericMessage<>("test"))); assertEquals("first two targets should have been invoked", 2, counter.get()); }
@Test public void allHandlersReturnFalse() { UnicastingDispatcher dispatcher = new UnicastingDispatcher(); final AtomicInteger counter = new AtomicInteger(); MessageHandler target1 = new CountingTestEndpoint(counter, false); MessageHandler target2 = new CountingTestEndpoint(counter, false); MessageHandler target3 = new CountingTestEndpoint(counter, false); dispatcher.addHandler(target1); dispatcher.addHandler(target2); dispatcher.addHandler(target3); try { assertFalse(dispatcher.dispatch(new GenericMessage<>("test"))); } catch (Exception e) { // ignore } assertEquals("each target should have been invoked", 3, counter.get()); }
@Test public void removeConsumerBeforeSend() { UnicastingDispatcher dispatcher = new UnicastingDispatcher(); final AtomicInteger counter = new AtomicInteger(); MessageHandler target1 = new CountingTestEndpoint(counter, false); MessageHandler target2 = new CountingTestEndpoint(counter, false); MessageHandler target3 = new CountingTestEndpoint(counter, false); dispatcher.addHandler(target1); dispatcher.addHandler(target2); dispatcher.addHandler(target3); dispatcher.removeHandler(target2); try { dispatcher.dispatch(new GenericMessage<>("test")); } catch (Exception e) { // ignore } assertEquals(2, counter.get()); }
@Test public void removeConsumerBetweenSends() { UnicastingDispatcher dispatcher = new UnicastingDispatcher(); final AtomicInteger counter = new AtomicInteger(); MessageHandler target1 = new CountingTestEndpoint(counter, false);
/** * Create an ExecutorChannel with a {@link LoadBalancingStrategy} that * delegates to the provided {@link TaskExecutor} when dispatching Messages. * <p> * The TaskExecutor must not be null. */ public ExecutorChannel(TaskExecutor taskExecutor, LoadBalancingStrategy loadBalancingStrategy) { Assert.notNull(taskExecutor, "taskExecutor must not be null"); this.taskExecutor = taskExecutor; this.dispatcher = new UnicastingDispatcher(taskExecutor); if (loadBalancingStrategy != null) { this.loadBalancingStrategy = loadBalancingStrategy; this.dispatcher.setLoadBalancingStrategy(loadBalancingStrategy); } }
/** * Create an ExecutorChannel with a {@link LoadBalancingStrategy} that * delegates to the provided {@link Executor} when dispatching Messages. * <p> * The Executor must not be null. * @param executor The executor. * @param loadBalancingStrategy The load balancing strategy implementation. */ public ExecutorChannel(Executor executor, LoadBalancingStrategy loadBalancingStrategy) { super(executor); Assert.notNull(executor, "executor must not be null"); UnicastingDispatcher unicastingDispatcher = new UnicastingDispatcher(executor); if (loadBalancingStrategy != null) { this.loadBalancingStrategy = loadBalancingStrategy; unicastingDispatcher.setLoadBalancingStrategy(loadBalancingStrategy); } this.dispatcher = unicastingDispatcher; }
@Override protected AbstractDispatcher createDispatcher() { UnicastingDispatcher unicastingDispatcher = new UnicastingDispatcher(); unicastingDispatcher.setLoadBalancingStrategy(new RoundRobinLoadBalancingStrategy()); return unicastingDispatcher; }
public void setBeanFactory(BeanFactory beanFactory) { if (!(this.taskExecutor instanceof ErrorHandlingTaskExecutor)) { ErrorHandler errorHandler = new MessagePublishingErrorHandler(new BeanFactoryChannelResolver(beanFactory)); this.taskExecutor = new ErrorHandlingTaskExecutor(this.taskExecutor, errorHandler); } this.dispatcher = new UnicastingDispatcher(this.taskExecutor); this.dispatcher.setFailover(this.failover); if (this.loadBalancingStrategy != null) { this.dispatcher.setLoadBalancingStrategy(this.loadBalancingStrategy); } }
private void configureDispatcher(boolean isPubSub) { if (isPubSub) { BroadcastingDispatcher broadcastingDispatcher = new BroadcastingDispatcher(true); broadcastingDispatcher.setBeanFactory(this.getBeanFactory()); this.dispatcher = broadcastingDispatcher; } else { UnicastingDispatcher unicastingDispatcher = new UnicastingDispatcher(); unicastingDispatcher.setLoadBalancingStrategy(new RoundRobinLoadBalancingStrategy()); this.dispatcher = unicastingDispatcher; } if (this.maxSubscribers == null) { this.maxSubscribers = this.getIntegrationProperty(isPubSub ? IntegrationProperties.CHANNELS_MAX_BROADCAST_SUBSCRIBERS : IntegrationProperties.CHANNELS_MAX_UNICAST_SUBSCRIBERS, Integer.class); } this.dispatcher.setMaxSubscribers(this.maxSubscribers); }
@Override public final void onInit() { Assert.state(getDispatcher().getHandlerCount() == 0, "You cannot subscribe() until the channel " + "bean is fully initialized by the framework. Do not subscribe in a @Bean definition"); super.onInit(); if (!(this.executor instanceof ErrorHandlingTaskExecutor)) { ErrorHandler errorHandler = new MessagePublishingErrorHandler( new BeanFactoryChannelResolver(this.getBeanFactory())); this.executor = new ErrorHandlingTaskExecutor(this.executor, errorHandler); } UnicastingDispatcher unicastingDispatcher = new UnicastingDispatcher(this.executor); unicastingDispatcher.setFailover(this.failover); if (this.maxSubscribers == null) { this.maxSubscribers = getIntegrationProperty(IntegrationProperties.CHANNELS_MAX_UNICAST_SUBSCRIBERS, Integer.class); } unicastingDispatcher.setMaxSubscribers(this.maxSubscribers); if (this.loadBalancingStrategy != null) { unicastingDispatcher.setLoadBalancingStrategy(this.loadBalancingStrategy); } unicastingDispatcher.setMessageHandlingTaskDecorator(task -> { if (ExecutorChannel.this.executorInterceptorsSize > 0) { return new MessageHandlingTask(task); } else { return task; } }); this.dispatcher = unicastingDispatcher; }