/* * Copyright 2002-2016 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.config; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.springframework.integration.test.util.TestUtils.getPropertyValue; import java.util.List; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.integration.aggregator.CorrelationStrategy; import org.springframework.integration.aggregator.MethodInvokingCorrelationStrategy; import org.springframework.integration.aggregator.MethodInvokingReleaseStrategy; import org.springframework.integration.aggregator.ReleaseStrategy; import org.springframework.integration.aggregator.ResequencingMessageHandler; import org.springframework.integration.channel.NullChannel; import org.springframework.integration.endpoint.EventDrivenConsumer; import org.springframework.integration.store.MessageGroup; import org.springframework.integration.store.SimpleMessageGroup; import org.springframework.integration.support.MessageBuilder; import org.springframework.integration.test.util.TestUtils; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; /** * @author Marius Bogoevici * @author Mark Fisher * @author Dave Syer * @author Oleg Zhurakousky * @author Stefan Ferstl * @author Artem Bilan * @author Gary Russell */ public class ResequencerParserTests { private ApplicationContext context; @Before public void setUp() { this.context = new ClassPathXmlApplicationContext("resequencerParserTests.xml", this.getClass()); } @Test public void testDefaultResequencerProperties() { EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("defaultResequencer"); ResequencingMessageHandler resequencer = TestUtils.getPropertyValue(endpoint, "handler", ResequencingMessageHandler.class); assertNull(getPropertyValue(resequencer, "outputChannel")); assertTrue(getPropertyValue(resequencer, "discardChannel") instanceof NullChannel); assertEquals("The ResequencerEndpoint is not set with the appropriate timeout value", -1L, getPropertyValue( resequencer, "messagingTemplate.sendTimeout")); assertEquals( "The ResequencerEndpoint is not configured with the appropriate 'send partial results on timeout' flag", false, getPropertyValue(resequencer, "sendPartialResultOnExpiry")); assertEquals("The ResequencerEndpoint is not configured with the appropriate 'release partial sequences' flag", false, getPropertyValue(getPropertyValue(resequencer, "releaseStrategy"), "releasePartialSequences")); } @Test public void testPropertyAssignment() throws Exception { EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("completelyDefinedResequencer"); MessageChannel outputChannel = (MessageChannel) context.getBean("outputChannel"); MessageChannel discardChannel = (MessageChannel) context.getBean("discardChannel"); ResequencingMessageHandler resequencer = TestUtils.getPropertyValue(endpoint, "handler", ResequencingMessageHandler.class); assertEquals("The ResequencerEndpoint is not injected with the appropriate output channel", outputChannel, getPropertyValue(resequencer, "outputChannel")); assertEquals("The ResequencerEndpoint is not injected with the appropriate discard channel", discardChannel, getPropertyValue(resequencer, "discardChannel")); assertEquals("The ResequencerEndpoint is not set with the appropriate timeout value", 86420000L, getPropertyValue(resequencer, "messagingTemplate.sendTimeout")); assertEquals( "The ResequencerEndpoint is not configured with the appropriate 'send partial results on timeout' flag", true, getPropertyValue(resequencer, "sendPartialResultOnExpiry")); assertEquals("The ResequencerEndpoint is not configured with the appropriate 'release partial sequences' flag", true, getPropertyValue(getPropertyValue(resequencer, "releaseStrategy"), "releasePartialSequences")); assertEquals(60000L, getPropertyValue(resequencer, "minimumTimeoutForEmptyGroups", Long.class).longValue()); } @Test public void testCorrelationStrategyRefOnly() throws Exception { EventDrivenConsumer endpoint = (EventDrivenConsumer) context .getBean("resequencerWithCorrelationStrategyRefOnly"); ResequencingMessageHandler resequencer = TestUtils.getPropertyValue(endpoint, "handler", ResequencingMessageHandler.class); assertEquals("The ResequencerEndpoint is not configured with the appropriate CorrelationStrategy", context .getBean("testCorrelationStrategy"), getPropertyValue(resequencer, "correlationStrategy")); } @Test public void testReleaseStrategyRefOnly() throws Exception { EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("resequencerWithReleaseStrategyRefOnly"); ResequencingMessageHandler resequencer = getPropertyValue(endpoint, "handler", ResequencingMessageHandler.class); assertEquals("The ResequencerEndpoint is not configured with the appropriate ReleaseStrategy", context.getBean("testReleaseStrategy"), getPropertyValue(resequencer, "releaseStrategy")); assertFalse(TestUtils.getPropertyValue(resequencer, "expireGroupsUponTimeout", Boolean.class)); } @Test public void testReleaseStrategyRefAndMethod() throws Exception { EventDrivenConsumer endpoint = (EventDrivenConsumer) context .getBean("resequencerWithReleaseStrategyRefAndMethod"); ResequencingMessageHandler resequencer = getPropertyValue(endpoint, "handler", ResequencingMessageHandler.class); Object releaseStrategyBean = context.getBean("testReleaseStrategyPojo"); assertTrue("Release strategy is not of the expected type", releaseStrategyBean instanceof TestReleaseStrategyPojo); TestReleaseStrategyPojo expectedReleaseStrategy = (TestReleaseStrategyPojo) releaseStrategyBean; int currentInvocationCount = expectedReleaseStrategy.invocationCount; ReleaseStrategy effectiveReleaseStrategy = (ReleaseStrategy) getPropertyValue(resequencer, "releaseStrategy"); assertTrue("The release strategy is expected to be a MethodInvokingReleaseStrategy", effectiveReleaseStrategy instanceof MethodInvokingReleaseStrategy); effectiveReleaseStrategy.canRelease(new SimpleMessageGroup("test")); assertEquals("The ResequencerEndpoint was not invoked the expected number of times;", currentInvocationCount + 1, expectedReleaseStrategy.invocationCount); assertTrue(TestUtils.getPropertyValue(resequencer, "expireGroupsUponTimeout", Boolean.class)); } @Test public void shouldSetReleasePartialSequencesFlag() { EventDrivenConsumer endpoint = (EventDrivenConsumer) context.getBean("completelyDefinedResequencer"); ResequencingMessageHandler resequencer = TestUtils.getPropertyValue(endpoint, "handler", ResequencingMessageHandler.class); assertEquals("The ResequencerEndpoint is not configured with the appropriate 'release partial sequences' flag", true, getPropertyValue(getPropertyValue(resequencer, "releaseStrategy"), "releasePartialSequences")); } @Test public void testCorrelationStrategyRefAndMethod() throws Exception { EventDrivenConsumer endpoint = (EventDrivenConsumer) context .getBean("resequencerWithCorrelationStrategyRefAndMethod"); ResequencingMessageHandler resequencer = TestUtils.getPropertyValue(endpoint, "handler", ResequencingMessageHandler.class); Object correlationStrategy = getPropertyValue(resequencer, "correlationStrategy"); assertEquals("The ResequencerEndpoint is not configured with a CorrelationStrategy adapter", MethodInvokingCorrelationStrategy.class, correlationStrategy.getClass()); MethodInvokingCorrelationStrategy adapter = (MethodInvokingCorrelationStrategy) correlationStrategy; assertEquals("foo", adapter.getCorrelationKey(MessageBuilder.withPayload("not important").build())); } @SuppressWarnings("unused") private static <T> Message<T> createMessage(T payload, Object correlationId, int sequenceSize, int sequenceNumber, MessageChannel outputChannel) { return MessageBuilder.withPayload(payload).setCorrelationId(correlationId).setSequenceSize(sequenceSize) .setSequenceNumber(sequenceNumber).setReplyChannel(outputChannel).build(); } static class TestCorrelationStrategy implements CorrelationStrategy { @Override public Object getCorrelationKey(Message<?> message) { return "test"; } } static class TestCorrelationStrategyPojo { public Object foo(Object o) { return "foo"; } } static class TestReleaseStrategy implements ReleaseStrategy { @Override public boolean canRelease(MessageGroup group) { return true; } } static class TestReleaseStrategyPojo { private int invocationCount = 0; public boolean bar(List<Message<?>> messages) { invocationCount++; return true; } } }