@Test public void shouldReleaseHeadOfSequenceDeliveredOutOfOrder() { SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy(); releaseStrategy.setReleasePartialSequences(true); boolean canRelease = releaseStrategy.canRelease(groupWithLastAndFirstMessagesOfIncompleteSequence()); assertTrue(canRelease); }
@Test public void testEmptyList() { SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy(); assertTrue(releaseStrategy.canRelease(new SimpleMessageGroup("FOO"))); }
@Test public void testBasicResequencingA() throws InterruptedException { SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy(); releaseStrategy.setReleasePartialSequences(true); this.resequencer = new ResequencingMessageHandler(processor, store, null, releaseStrategy); this.resequencer.setBeanFactory(mock(BeanFactory.class)); this.resequencer.afterPropertiesSet(); QueueChannel replyChannel = new QueueChannel(); Message<?> message1 = createMessage("123", "ABC", 3, 1, replyChannel); Message<?> message3 = createMessage("789", "ABC", 3, 3, replyChannel); this.resequencer.handleMessage(message3); assertNull(replyChannel.receive(0)); this.resequencer.handleMessage(message1); assertNotNull(replyChannel.receive(0)); assertNull(replyChannel.receive(0)); }
/** * Set {@code releasePartialSequences} on an underlying default * {@link SequenceSizeReleaseStrategy}. Ignored for other release strategies. * @param releasePartialSequences true to allow release. */ public void setReleasePartialSequences(boolean releasePartialSequences) { if (!this.releaseStrategySet && releasePartialSequences) { setReleaseStrategy(new SequenceSizeReleaseStrategy()); } this.releasePartialSequences = releasePartialSequences; }
"] cannot release partial sequences. Use a SequenceSizeReleaseStrategy instead."); ((SequenceSizeReleaseStrategy) this.releaseStrategy) .setReleasePartialSequences(this.releasePartialSequences);
@Test public void testEmptyList() { SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy(); assertTrue(releaseStrategy.canRelease(new SimpleMessageGroup("FOO"))); }
@Test public void testBasicUnboundedResequencing() throws InterruptedException { SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy(); releaseStrategy.setReleasePartialSequences(true); this.resequencer = new ResequencingMessageHandler(processor, store, null, releaseStrategy); QueueChannel replyChannel = new QueueChannel(); this.resequencer.setCorrelationStrategy(message -> "A"); this.resequencer.setBeanFactory(mock(BeanFactory.class)); this.resequencer.afterPropertiesSet(); //Message<?> message0 = MessageBuilder.withPayload("0").setSequenceNumber(0).build(); Message<?> message1 = MessageBuilder.withPayload("1").setSequenceNumber(1).setReplyChannel(replyChannel).build(); Message<?> message2 = MessageBuilder.withPayload("2").setSequenceNumber(2).setReplyChannel(replyChannel).build(); Message<?> message3 = MessageBuilder.withPayload("3").setSequenceNumber(3).setReplyChannel(replyChannel).build(); Message<?> message4 = MessageBuilder.withPayload("4").setSequenceNumber(4).setReplyChannel(replyChannel).build(); Message<?> message5 = MessageBuilder.withPayload("5").setSequenceNumber(5).setReplyChannel(replyChannel).build(); this.resequencer.handleMessage(message3); assertNull(replyChannel.receive(0)); this.resequencer.handleMessage(message1); assertNotNull(replyChannel.receive(0)); this.resequencer.handleMessage(message2); assertNotNull(replyChannel.receive(0)); assertNotNull(replyChannel.receive(0)); assertNull(replyChannel.receive(0)); this.resequencer.handleMessage(message5); assertNull(replyChannel.receive(0)); this.resequencer.handleMessage(message4); assertNotNull(replyChannel.receive(0)); }
@Test public void shouldRejectDuplicatedSequenceNumbers() { QueueChannel replyChannel = new QueueChannel(); Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel, null); Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel, null); Message<?> message3 = createMessage(7, "ABC", 3, 3, replyChannel, null); Message<?> message4 = createMessage(7, "ABC", 3, 3, replyChannel, null); this.aggregator.setReleaseStrategy(new SequenceSizeReleaseStrategy()); this.aggregator.handleMessage(message1); this.aggregator.handleMessage(message3); // duplicated sequence number, either message3 or message4 should be rejected this.aggregator.handleMessage(message4); this.aggregator.handleMessage(message2); Message<?> reply = replyChannel.receive(10000); assertNotNull("A message should be aggregated", reply); assertThat((reply.getPayload()), is(105)); }
"] cannot release partial sequences. Use a SequenceSizeReleaseStrategy instead."); ((SequenceSizeReleaseStrategy) this.releaseStrategy) .setReleasePartialSequences(this.releasePartialSequences);
@Test public void shouldReleaseHeadOfSequenceDeliveredInOrder() { SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy(); releaseStrategy.setReleasePartialSequences(true); SimpleMessageGroup messages = new SimpleMessageGroup("FOO"); assertTrue(releaseStrategy.canRelease(groupWithFirstMessagesOfIncompleteSequence(messages))); }
@Test public void testIncompleteList() { Message<String> message = MessageBuilder.withPayload("test1").setSequenceSize(2).build(); SimpleMessageGroup messages = new SimpleMessageGroup("FOO"); messages.add(message); SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy(); assertFalse(releaseStrategy.canRelease(messages)); }
@Test public void testAdditionalMessageAfterCompletion() throws InterruptedException { QueueChannel replyChannel = new QueueChannel(); Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel, null); Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel, null); Message<?> message3 = createMessage(7, "ABC", 3, 3, replyChannel, null); Message<?> message4 = createMessage(7, "ABC", 3, 3, replyChannel, null); CountDownLatch latch = new CountDownLatch(4); this.aggregator.setReleaseStrategy(new SequenceSizeReleaseStrategy()); this.taskExecutor.execute(new AggregatorTestTask(this.aggregator, message1, latch)); this.taskExecutor.execute(new AggregatorTestTask(this.aggregator, message2, latch)); this.taskExecutor.execute(new AggregatorTestTask(this.aggregator, message3, latch)); this.taskExecutor.execute(new AggregatorTestTask(this.aggregator, message4, latch)); assertTrue(latch.await(10, TimeUnit.SECONDS)); Message<?> reply = replyChannel.receive(10000); assertNotNull("A message should be aggregated", reply); assertThat(reply.getPayload(), is(105)); }
@Test public void testEmptyGroup() { SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy(); releaseStrategy.setReleasePartialSequences(true); SimpleMessageGroup messages = new SimpleMessageGroup("FOO"); Message<String> message = MessageBuilder.withPayload("test1").setSequenceSize(1).build(); messages.add(message); messages.remove(message); assertTrue(releaseStrategy.canRelease(messages)); }
@Test public void testCompleteList() { Message<String> message1 = MessageBuilder.withPayload("test1").setSequenceSize(2).build(); Message<String> message2 = MessageBuilder.withPayload("test2").setSequenceSize(2).build(); SimpleMessageGroup messages = new SimpleMessageGroup("FOO"); messages.add(message1); messages.add(message2); SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy(); assertTrue(releaseStrategy.canRelease(messages)); }
/** * Set {@code releasePartialSequences} on an underlying default * {@link SequenceSizeReleaseStrategy}. Ignored for other release strategies. * @param releasePartialSequences true to allow release. */ public void setReleasePartialSequences(boolean releasePartialSequences) { if (!this.releaseStrategySet && releasePartialSequences) { setReleaseStrategy(new SequenceSizeReleaseStrategy()); } this.releasePartialSequences = releasePartialSequences; }
@Test public void shouldPartiallyReleaseAsEarlyAsPossible() { SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy(); releaseStrategy.setReleasePartialSequences(true); SimpleMessageGroup messages = new SimpleMessageGroup("FOO"); Message<String> message1 = MessageBuilder.withPayload("test1").setSequenceSize(5).setSequenceNumber(1).build(); Message<String> message2 = MessageBuilder.withPayload("test2").setSequenceSize(5).setSequenceNumber(2).build(); Message<String> message3 = MessageBuilder.withPayload("test3").setSequenceSize(5).setSequenceNumber(3).build(); Message<String> message4 = MessageBuilder.withPayload("test4").setSequenceSize(5).setSequenceNumber(4).build(); Message<String> message5 = MessageBuilder.withPayload("test5").setSequenceSize(5).setSequenceNumber(5).build(); messages.add(message5); assertFalse(releaseStrategy.canRelease(messages)); messages.add(message1); assertTrue(releaseStrategy.canRelease(messages)); messages.add(message2); assertTrue(releaseStrategy.canRelease(messages)); messages.add(message3); assertTrue(releaseStrategy.canRelease(messages)); messages.add(message4); assertTrue(releaseStrategy.canRelease(messages)); }
@Test public void testCompleteList() { Message<String> message1 = MessageBuilder.withPayload("test1") .setSequenceSize(2).build(); Message<String> message2 = MessageBuilder.withPayload("test2") .setSequenceSize(2).build(); SimpleMessageGroup messages = new SimpleMessageGroup("FOO"); messages.add(message1); messages.add(message2); SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy(); assertTrue(releaseStrategy.canRelease(messages)); }
@Test public void testResequencingWithCapacity() throws InterruptedException { this.resequencer.setReleaseStrategy(new SequenceSizeReleaseStrategy(true)); // INT-3846 this.resequencer.setMessageStore(new SimpleMessageStore(3, 2)); QueueChannel replyChannel = new QueueChannel(); Message<?> message1 = createMessage("123", "ABC", 4, 4, replyChannel); Message<?> message2 = createMessage("456", "ABC", 4, 2, replyChannel); Message<?> message3 = createMessage("789", "ABC", 4, 1, replyChannel); this.resequencer.handleMessage(message1); this.resequencer.handleMessage(message2); try { this.resequencer.handleMessage(message3); fail("Expected exception"); } catch (MessagingException e) { assertThat(e.getMessage(), containsString("out of capacity (2) for group 'ABC'")); } }
@Test public void testResequencingWithPartialSequenceAndComparator() throws InterruptedException { this.resequencer.setReleaseStrategy(new SequenceSizeReleaseStrategy(true)); QueueChannel replyChannel = new QueueChannel(); Message<?> message1 = createMessage("456", "ABC", 4, 2, replyChannel); Message<?> message2 = createMessage("123", "ABC", 4, 1, replyChannel); Message<?> message3 = createMessage("XYZ", "ABC", 4, 4, replyChannel); Message<?> message4 = createMessage("789", "ABC", 4, 3, replyChannel); this.resequencer.handleMessage(message1); this.resequencer.handleMessage(message2); this.resequencer.handleMessage(message3); Message<?> reply1 = replyChannel.receive(0); Message<?> reply2 = replyChannel.receive(0); Message<?> reply3 = replyChannel.receive(0); // only messages 1 and 2 should have been received by now assertNotNull(reply1); assertEquals(1, new IntegrationMessageHeaderAccessor(reply1).getSequenceNumber()); assertNotNull(reply2); assertEquals(2, new IntegrationMessageHeaderAccessor(reply2).getSequenceNumber()); assertNull(reply3); // when sending the last message, the whole sequence must have been sent this.resequencer.handleMessage(message4); reply3 = replyChannel.receive(0); Message<?> reply4 = replyChannel.receive(0); assertNotNull(reply3); assertEquals(3, new IntegrationMessageHeaderAccessor(reply3).getSequenceNumber()); assertNotNull(reply4); assertEquals(4, new IntegrationMessageHeaderAccessor(reply4).getSequenceNumber()); }
@Test public void testResequencingWithIncompleteSequenceRelease() throws InterruptedException { this.resequencer.setReleaseStrategy(new SequenceSizeReleaseStrategy(true));