/*
* Copyright 2002-2017 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.aggregator;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.integration.store.MessageGroupStore;
import org.springframework.integration.store.SimpleMessageStore;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
/**
* @author Iwein Fuld
* @author Dave Syer
* @author Gary Russell
*
*/
public class CorrelatingMessageHandlerIntegrationTests {
private final MessageGroupStore store = new SimpleMessageStore(100);
private final MessageChannel outputChannel = mock(MessageChannel.class);
private final MessageGroupProcessor processor = new SimpleMessageGroupProcessor();
private final AggregatingMessageHandler defaultHandler = new AggregatingMessageHandler(processor, store);
@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();
}
@Test
public void completesSingleMessage() throws Exception {
Message<?> message = correlatedMessage(1, 1, 1);
defaultHandler.handleMessage(message);
verify(outputChannel).send(message);
}
@Test
public void completesAfterThreshold() throws Exception {
defaultHandler.setReleaseStrategy(new MessageCountReleaseStrategy());
MessageChannel discardChannel = mock(MessageChannel.class);
when(discardChannel.send(any(Message.class))).thenReturn(true);
defaultHandler.setDiscardChannel(discardChannel);
Message<?> message1 = correlatedMessage(1, 2, 1);
Message<?> message2 = correlatedMessage(1, 2, 2);
defaultHandler.handleMessage(message1);
verify(outputChannel).send(message1);
defaultHandler.handleMessage(message2);
verify(outputChannel, never()).send(message2);
verify(discardChannel).send(message2);
}
@Test
public void completesIfNoSequence() throws Exception {
defaultHandler.setReleaseStrategy(new MessageCountReleaseStrategy(2));
Message<?> message1 = MessageBuilder.withPayload(1).setCorrelationId("foo").build();
Message<?> message2 = MessageBuilder.withPayload(2).setCorrelationId("foo").build();
Message<?> message3 = MessageBuilder.withPayload(3).setCorrelationId("foo").build();
defaultHandler.handleMessage(message1);
verify(outputChannel, never()).send(message3);
defaultHandler.handleMessage(message2);
verify(outputChannel).send(message2);
defaultHandler.handleMessage(message3);
verify(outputChannel, never()).send(message3);
}
@Test
public void completesWithoutReleasingIncompleteCorrelations() throws Exception {
Message<?> message1 = correlatedMessage(1, 2, 1);
Message<?> message2 = correlatedMessage(2, 2, 1);
Message<?> message1a = correlatedMessage(1, 2, 2);
Message<?> message2a = correlatedMessage(2, 2, 2);
defaultHandler.handleMessage(message1);
defaultHandler.handleMessage(message2);
verify(outputChannel, never()).send(message1);
verify(outputChannel, never()).send(message2);
defaultHandler.handleMessage(message1a);
verify(outputChannel).send(message1);
verify(outputChannel).send(message1a);
verify(outputChannel, never()).send(message2);
verify(outputChannel, never()).send(message2a);
defaultHandler.handleMessage(message2a);
verify(outputChannel).send(message2);
verify(outputChannel).send(message2a);
}
@Test
public void completesAfterSequenceComplete() throws Exception {
Message<?> message1 = correlatedMessage(1, 2, 1);
Message<?> message2 = correlatedMessage(1, 2, 2);
defaultHandler.handleMessage(message1);
verify(outputChannel, never()).send(message1);
defaultHandler.handleMessage(message2);
verify(outputChannel).send(message1);
verify(outputChannel).send(message2);
}
private Message<?> correlatedMessage(Object correlationId, Integer sequenceSize, Integer sequenceNumber) {
return MessageBuilder.withPayload("test")
.setCorrelationId(correlationId)
.setSequenceNumber(sequenceNumber)
.setSequenceSize(sequenceSize)
.build();
}
}