AggregatingMessageHandler aggregator = new AggregatingMessageHandler(outputProcessor); aggregator.setExpireGroupsUponCompletion(this.expireGroupsUponCompletion); aggregator.setSendTimeout(this.sendTimeout); aggregator.setOutputChannelName(this.outputChannelName); aggregator.configureMetrics(this.metrics); aggregator.setStatsEnabled(this.statsEnabled); aggregator.setCountsEnabled(this.countsEnabled); aggregator.setLockRegistry(this.lockRegistry); aggregator.setMessageStore(this.messageStore); aggregator.setCorrelationStrategy(this.correlationStrategy); aggregator.setReleaseStrategy(this.releaseStrategy); aggregator.setGroupTimeoutExpression(this.groupTimeoutExpression); aggregator.setForceReleaseAdviceChain(this.forceReleaseAdviceChain); aggregator.setTaskScheduler(this.taskScheduler); aggregator.setDiscardChannel(this.discardChannel);
/** * Complete the group and remove all its messages. * If the {@link #expireGroupsUponCompletion} is true, then remove group fully. * @param messageGroup the group to clean up. * @param completedMessages The completed messages. Ignored in this implementation. */ @Override protected void afterRelease(MessageGroup messageGroup, Collection<Message<?>> completedMessages) { Object groupId = messageGroup.getGroupId(); MessageGroupStore messageStore = getMessageStore(); messageStore.completeGroup(groupId); if (this.expireGroupsUponCompletion) { remove(messageGroup); } else { if (messageStore instanceof SimpleMessageStore) { ((SimpleMessageStore) messageStore).clearMessageGroup(groupId); } else { messageStore.removeMessagesFromGroup(groupId, messageGroup.getMessages()); } } }
AggregatingMessageHandler handler = new AggregatingMessageHandler(processor, new SimpleMessageStore(), correlationStrategy, releaseStrategy); handler.setDiscardChannelName(discardChannelName); handler.setOutputChannelName(outputChannelName); handler.setSendPartialResultOnExpiry( Boolean.parseBoolean(this.beanFactory.resolveEmbeddedValue(sendPartialResultsOnExpiry))); handler.setBeanFactory(this.beanFactory); return handler;
@Before public void initializeSubject() { handler = new AggregatingMessageHandler(processor, store, correlationStrategy, ReleaseStrategy); handler.setOutputChannel(outputChannel); }
@Before public void configureAggregator() { this.aggregator = new AggregatingMessageHandler(new MultiplyingProcessor(), store); this.aggregator.setBeanFactory(mock(BeanFactory.class)); this.aggregator.setApplicationEventPublisher(event -> expiryEvents.add((MessageGroupExpiredEvent) event)); this.aggregator.setBeanName("testAggregator"); this.aggregator.afterPropertiesSet(); expiryEvents.clear(); }
@Test @Ignore public void testAggPerf() throws InterruptedException, ExecutionException, TimeoutException { AggregatingMessageHandler handler = new AggregatingMessageHandler(new DefaultAggregatingMessageGroupProcessor()); handler.setCorrelationStrategy(message -> "foo"); handler.setReleaseStrategy(new MessageCountReleaseStrategy(60000)); handler.setExpireGroupsUponCompletion(true); handler.setSendPartialResultOnExpiry(true); DirectChannel outputChannel = new DirectChannel(); handler.setOutputChannel(outputChannel); handler.setMessageStore(store); stopwatch.start(); handler.handleMessage(message);
@Test public void batchingWithoutLeftovers() { QueueChannel outputChannel = new QueueChannel(); QueueChannel discardChannel = new QueueChannel(); defaultHandler.setOutputChannel(outputChannel); defaultHandler.setDiscardChannel(discardChannel); defaultHandler.setReleaseStrategy(new SampleSizeReleaseStrategy()); defaultHandler.setExpireGroupsUponCompletion(true); for (int i = 0; i < 10; i++) { defaultHandler.handleMessage(MessageBuilder.withPayload(i).setCorrelationId("A").build()); } assertEquals(5, ((List<?>) outputChannel.receive(0).getPayload()).size()); assertEquals(5, ((List<?>) outputChannel.receive(0).getPayload()).size()); assertNull(discardChannel.receive(0)); }
@Test public void testInt3483DeadlockOnMessageStoreRemoveMessageGroup() throws InterruptedException { final AggregatingMessageHandler handler = new AggregatingMessageHandler(new DefaultAggregatingMessageGroupProcessor()); handler.setOutputChannel(new QueueChannel()); QueueChannel discardChannel = new QueueChannel(); handler.setDiscardChannel(discardChannel); handler.setReleaseStrategy(group -> true); handler.setExpireGroupsUponTimeout(false); SimpleMessageStore messageStore = new SimpleMessageStore() { handler.setMessageStore(messageStore); handler.handleMessage(MessageBuilder.withPayload("foo") .setCorrelationId(1) .setSequenceNumber(1) executorService.execute(() -> handler.handleMessage(MessageBuilder.withPayload("foo") .setCorrelationId(1) .setSequenceNumber(2)
@Test /* INT-3216 */ public void testDontReapIfAlreadyComplete() throws Exception { MessageGroupProcessor mgp = new DefaultAggregatingMessageGroupProcessor(); AggregatingMessageHandler handler = new AggregatingMessageHandler(mgp); handler.setReleaseStrategy(group -> true); QueueChannel outputChannel = new QueueChannel(); handler.setOutputChannel(outputChannel); MessageGroupStore mgs = TestUtils.getPropertyValue(handler, "messageStore", MessageGroupStore.class); mgs.addMessagesToGroup("foo", new GenericMessage<>("foo")); mgs.completeGroup("foo"); mgs = spy(mgs); new DirectFieldAccessor(handler).setPropertyValue("messageStore", mgs); Method forceComplete = AbstractCorrelatingMessageHandler.class.getDeclaredMethod("forceComplete", MessageGroup.class); forceComplete.setAccessible(true); MessageGroup group = (MessageGroup) TestUtils.getPropertyValue(mgs, "groupIdToMessageGroup", Map.class) .get("foo"); assertTrue(group.isComplete()); forceComplete.invoke(handler, group); verify(mgs, never()).getMessageGroup("foo"); assertNull(outputChannel.receive(0)); }
public void testScheduleRemoveAnEmptyGroupAfterConfiguredDelay() throws Exception { final MessageGroupStore groupStore = new SimpleMessageStore(); AggregatingMessageHandler handler = new AggregatingMessageHandler(group -> group, groupStore); handler.setOutputChannel((message, timeout) -> { return true; }); handler.setReleaseStrategy(group -> group.size() == 1); handler.setMinimumTimeoutForEmptyGroups(100); handler.setTaskScheduler(taskScheduler); handler.handleMessage(message);
@Test public void jdkProxy() { DirectChannel input = new DirectChannel(); QueueChannel output = new QueueChannel(); GreetingService testBean = new GreetingBean(); ProxyFactory proxyFactory = new ProxyFactory(testBean); proxyFactory.setProxyTargetClass(true); testBean = (GreetingService) proxyFactory.getProxy(); MethodInvokingMessageGroupProcessor aggregator = new MethodInvokingMessageGroupProcessor(testBean); AggregatingMessageHandler handler = new AggregatingMessageHandler(aggregator); handler.setReleaseStrategy(new MessageCountReleaseStrategy()); handler.setOutputChannel(output); handler.setBeanFactory(mock(BeanFactory.class)); handler.afterPropertiesSet(); EventDrivenConsumer endpoint = new EventDrivenConsumer(input, handler); endpoint.start(); Message<?> message = MessageBuilder.withPayload("proxy").setCorrelationId("abc").build(); input.send(message); assertEquals("hello proxy", output.receive(0).getPayload()); }
@Bean @ServiceActivator(inputChannel = "aggregatorChannel") public MessageHandler aggregator() { AggregatingMessageHandler handler = new AggregatingMessageHandler(new SimpleMessageGroupProcessor()); handler.setCorrelationStrategy(new ExpressionEvaluatingCorrelationStrategy("1")); handler.setReleaseStrategy(new ExpressionEvaluatingReleaseStrategy("size() == 10")); handler.setOutputChannelName("splitterChannel"); return handler; }
@Test public void testGroupRemainsAfterTimeoutUnlockB4Discard() { this.aggregator.setSendPartialResultOnExpiry(true); this.aggregator.setExpireGroupsUponTimeout(false); this.aggregator.setReleaseLockBeforeSend(true); QueueChannel replyChannel = new QueueChannel(); MessageChannel lockCheckingChannel = (m, to) -> { }; QueueChannel discardChannel = new QueueChannel(); this.aggregator.setDiscardChannel((m, to) -> { checkLock(this.aggregator, "ABC", false); discardChannel.send(m); Message<?> message1 = createMessage(3, "ABC", 3, 1, lockCheckingChannel, null); Message<?> message2 = createMessage(5, "ABC", 3, 2, lockCheckingChannel, null); this.aggregator.handleMessage(message1); this.aggregator.handleMessage(message2); this.store.expireMessageGroups(-10000); Message<?> reply = replyChannel.receive(1000); assertEquals(0, this.store.getMessageGroup("ABC").size()); Message<?> message3 = createMessage(5, "ABC", 3, 3, lockCheckingChannel, null); this.aggregator.handleMessage(message3); assertEquals(0, this.store.getMessageGroup("ABC").size()); Message<?> discardedMessage = discardChannel.receive(1000);
@Test @Ignore("Time sensitive") public void testAggPerfDefaultPartial() throws InterruptedException, ExecutionException, TimeoutException { AggregatingMessageHandler handler = new AggregatingMessageHandler(new DefaultAggregatingMessageGroupProcessor()); handler.setCorrelationStrategy(message -> "foo"); handler.setReleasePartialSequences(true); DirectChannel outputChannel = new DirectChannel(); handler.setOutputChannel(outputChannel); handler.setMessageStore(store); stopwatch.start(); handler.handleMessage(MessageBuilder.withPayload("foo") .setSequenceSize(120000) .setSequenceNumber(i + 1)
@Test @Ignore("Until 5.2 with new 'owner' feature on groups") public void testDontReapMessageOfOtherHandler() { MessageGroupStore groupStore = new SimpleMessageStore(); AggregatingMessageHandler handler1 = new AggregatingMessageHandler(group -> group, groupStore); AggregatingMessageHandler handler2 = new AggregatingMessageHandler(group -> group, groupStore); QueueChannel handler1DiscardChannel = new QueueChannel(); handler1.setDiscardChannel(handler1DiscardChannel); QueueChannel handler2DiscardChannel = new QueueChannel(); handler2.setDiscardChannel(handler2DiscardChannel); handler1.setReleaseStrategy(group -> false); handler2.setReleaseStrategy(group -> false); handler1.handleMessage(MessageBuilder.withPayload("foo").setCorrelationId("foo").build()); handler1.handleMessage(MessageBuilder.withPayload("foo").setCorrelationId("foo").build()); handler2.handleMessage(MessageBuilder.withPayload("foo").setCorrelationId("bar").build()); groupStore.expireMessageGroups(0); assertEquals(2, handler1DiscardChannel.getQueueSize()); assertEquals(1, handler2DiscardChannel.getQueueSize()); }
@Test // INT-2833 public void testReaperReapsAnEmptyGroup() { final MessageGroupStore groupStore = new SimpleMessageStore(); AggregatingMessageHandler handler = new AggregatingMessageHandler(group -> group, groupStore); final List<Message<?>> outputMessages = new ArrayList<>(); handler.setOutputChannel((message, timeout) -> { /* * Executes when group 'bar' completes normally */ outputMessages.add(message); return true; }); handler.setReleaseStrategy(group -> group.size() == 1); Message<String> message = MessageBuilder.withPayload("foo") .setCorrelationId("bar") .build(); handler.handleMessage(message); assertEquals(1, outputMessages.size()); assertEquals(1, TestUtils.getPropertyValue(handler, "messageStore.groupIdToMessageGroup", Map.class).size()); groupStore.expireMessageGroups(0); assertEquals(0, TestUtils.getPropertyValue(handler, "messageStore.groupIdToMessageGroup", Map.class).size()); }
@Before public void setupHandler() { when(outputChannel.send(isA(Message.class))).thenReturn(true); defaultHandler.setOutputChannel(outputChannel); defaultHandler.setSendTimeout(-1); defaultHandler.setBeanFactory(mock(BeanFactory.class)); defaultHandler.afterPropertiesSet(); }
AggregatorSpec() { super(new AggregatingMessageHandler(new DefaultAggregatingMessageGroupProcessor())); }
/** * @param expireGroupsUponCompletion the expireGroupsUponCompletion. * @return the aggregator spec. * @see AggregatingMessageHandler#setExpireGroupsUponCompletion(boolean) */ public AggregatorSpec expireGroupsUponCompletion(boolean expireGroupsUponCompletion) { this.handler.setExpireGroupsUponCompletion(expireGroupsUponCompletion); return _this(); }
@Before public void configureAggregator() { this.taskExecutor = new SimpleAsyncTaskExecutor(); this.aggregator = new AggregatingMessageHandler(new MultiplyingProcessor(), this.store); this.aggregator.setReleaseStrategy(new SimpleSequenceSizeReleaseStrategy()); }