Search in sources :

Example 16 with SimpleMessageStore

use of org.springframework.integration.store.SimpleMessageStore in project spring-integration by spring-projects.

the class AggregatorAnnotationPostProcessor method createHandler.

@Override
protected MessageHandler createHandler(Object bean, Method method, List<Annotation> annotations) {
    MethodInvokingMessageGroupProcessor processor = new MethodInvokingMessageGroupProcessor(bean, method);
    processor.setBeanFactory(this.beanFactory);
    MethodInvokingReleaseStrategy releaseStrategy = null;
    Method releaseStrategyMethod = MessagingAnnotationUtils.findAnnotatedMethod(bean, ReleaseStrategy.class);
    if (releaseStrategyMethod != null) {
        releaseStrategy = new MethodInvokingReleaseStrategy(bean, releaseStrategyMethod);
    }
    MethodInvokingCorrelationStrategy correlationStrategy = null;
    Method correlationStrategyMethod = MessagingAnnotationUtils.findAnnotatedMethod(bean, CorrelationStrategy.class);
    if (correlationStrategyMethod != null) {
        correlationStrategy = new MethodInvokingCorrelationStrategy(bean, correlationStrategyMethod);
    }
    AggregatingMessageHandler handler = new AggregatingMessageHandler(processor, new SimpleMessageStore(), correlationStrategy, releaseStrategy);
    String discardChannelName = MessagingAnnotationUtils.resolveAttribute(annotations, "discardChannel", String.class);
    if (StringUtils.hasText(discardChannelName)) {
        handler.setDiscardChannelName(discardChannelName);
    }
    String outputChannelName = MessagingAnnotationUtils.resolveAttribute(annotations, "outputChannel", String.class);
    if (StringUtils.hasText(outputChannelName)) {
        handler.setOutputChannelName(outputChannelName);
    }
    String sendPartialResultsOnExpiry = MessagingAnnotationUtils.resolveAttribute(annotations, "sendPartialResultsOnExpiry", String.class);
    if (sendPartialResultsOnExpiry != null) {
        handler.setSendPartialResultOnExpiry(Boolean.parseBoolean(this.beanFactory.resolveEmbeddedValue(sendPartialResultsOnExpiry)));
    }
    handler.setBeanFactory(this.beanFactory);
    return handler;
}
Also used : AggregatingMessageHandler(org.springframework.integration.aggregator.AggregatingMessageHandler) SimpleMessageStore(org.springframework.integration.store.SimpleMessageStore) MethodInvokingMessageGroupProcessor(org.springframework.integration.aggregator.MethodInvokingMessageGroupProcessor) Method(java.lang.reflect.Method) MethodInvokingCorrelationStrategy(org.springframework.integration.aggregator.MethodInvokingCorrelationStrategy) MethodInvokingReleaseStrategy(org.springframework.integration.aggregator.MethodInvokingReleaseStrategy)

Example 17 with SimpleMessageStore

use of org.springframework.integration.store.SimpleMessageStore in project spring-integration by spring-projects.

the class AbstractCorrelatingMessageHandlerTests method testReaperDoesntReapAProcessingGroup.

// INT-2751
@Test
public void testReaperDoesntReapAProcessingGroup() throws Exception {
    final MessageGroupStore groupStore = new SimpleMessageStore();
    final CountDownLatch waitForSendLatch = new CountDownLatch(1);
    final CountDownLatch waitReapStartLatch = new CountDownLatch(1);
    final CountDownLatch waitReapCompleteLatch = new CountDownLatch(1);
    AbstractCorrelatingMessageHandler handler = new AbstractCorrelatingMessageHandler(group -> group, groupStore) {

        @Override
        protected void afterRelease(MessageGroup group, Collection<Message<?>> completedMessages) {
        }
    };
    handler.setReleasePartialSequences(true);
    /*
		 * Runs "reap" when group 'bar' is in completion
		 */
    ExecutorService exec = Executors.newSingleThreadExecutor();
    exec.execute(() -> {
        try {
            waitReapStartLatch.await(10, TimeUnit.SECONDS);
        } catch (InterruptedException e1) {
            Thread.currentThread().interrupt();
        }
        waitForSendLatch.countDown();
        try {
            Thread.sleep(100);
        } catch (InterruptedException e2) {
            Thread.currentThread().interrupt();
        }
        groupStore.expireMessageGroups(50);
        waitReapCompleteLatch.countDown();
    });
    final List<Message<?>> outputMessages = new ArrayList<Message<?>>();
    handler.setOutputChannel((message, timeout) -> {
        /*
			 * Executes when group 'bar' completes normally
			 */
        outputMessages.add(message);
        // wake reaper
        waitReapStartLatch.countDown();
        try {
            waitForSendLatch.await(10, TimeUnit.SECONDS);
            // wait a little longer for reaper to grab groups
            Thread.sleep(2000);
            // simulate tx commit
            groupStore.removeMessageGroup("bar");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        return true;
    });
    handler.setReleaseStrategy(group -> group.size() == 2);
    QueueChannel discards = new QueueChannel();
    handler.setDiscardChannel(discards);
    handler.setSendPartialResultOnExpiry(true);
    Message<String> message = MessageBuilder.withPayload("foo").setCorrelationId("qux").build();
    // partial group that will be reaped
    handler.handleMessage(message);
    message = MessageBuilder.withPayload("foo").setCorrelationId("bar").build();
    // full group that should not be reaped
    handler.handleMessage(message);
    message = MessageBuilder.withPayload("baz").setCorrelationId("bar").build();
    handler.handleMessage(message);
    assertTrue(waitReapCompleteLatch.await(10, TimeUnit.SECONDS));
    // Before INT-2751 we got bar + bar + qux
    // bar + qux
    assertEquals(2, outputMessages.size());
    // normal release
    // 'bar'
    assertEquals(2, ((MessageGroup) outputMessages.get(0).getPayload()).size());
    // reaper release
    // 'qux'
    assertEquals(1, ((MessageGroup) outputMessages.get(1).getPayload()).size());
    assertNull(discards.receive(0));
    exec.shutdownNow();
}
Also used : MessageGroupStore(org.springframework.integration.store.MessageGroupStore) SimpleMessageStore(org.springframework.integration.store.SimpleMessageStore) Message(org.springframework.messaging.Message) GenericMessage(org.springframework.messaging.support.GenericMessage) QueueChannel(org.springframework.integration.channel.QueueChannel) MessageGroup(org.springframework.integration.store.MessageGroup) SimpleMessageGroup(org.springframework.integration.store.SimpleMessageGroup) ArrayList(java.util.ArrayList) CountDownLatch(java.util.concurrent.CountDownLatch) ExecutorService(java.util.concurrent.ExecutorService) Collection(java.util.Collection) Test(org.junit.Test)

Example 18 with SimpleMessageStore

use of org.springframework.integration.store.SimpleMessageStore in project spring-integration by spring-projects.

the class AbstractCorrelatingMessageHandlerTests method testReaperReapsAnEmptyGroupAfterConfiguredDelay.

// INT-2833
@Test
public void testReaperReapsAnEmptyGroupAfterConfiguredDelay() throws Exception {
    final MessageGroupStore groupStore = new SimpleMessageStore();
    AggregatingMessageHandler handler = new AggregatingMessageHandler(group -> group, groupStore);
    final List<Message<?>> outputMessages = new ArrayList<Message<?>>();
    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);
    handler.setMinimumTimeoutForEmptyGroups(10_000);
    assertEquals(1, outputMessages.size());
    assertEquals(1, TestUtils.getPropertyValue(handler, "messageStore.groupIdToMessageGroup", Map.class).size());
    groupStore.expireMessageGroups(0);
    assertEquals(1, TestUtils.getPropertyValue(handler, "messageStore.groupIdToMessageGroup", Map.class).size());
    handler.setMinimumTimeoutForEmptyGroups(10);
    int n = 0;
    while (n++ < 200) {
        groupStore.expireMessageGroups(0);
        if (TestUtils.getPropertyValue(handler, "messageStore.groupIdToMessageGroup", Map.class).size() > 0) {
            Thread.sleep(50);
        } else {
            break;
        }
    }
    assertTrue(n < 200);
    assertEquals(0, TestUtils.getPropertyValue(handler, "messageStore.groupIdToMessageGroup", Map.class).size());
}
Also used : MessageGroupStore(org.springframework.integration.store.MessageGroupStore) SimpleMessageStore(org.springframework.integration.store.SimpleMessageStore) Message(org.springframework.messaging.Message) GenericMessage(org.springframework.messaging.support.GenericMessage) ArrayList(java.util.ArrayList) Test(org.junit.Test)

Example 19 with SimpleMessageStore

use of org.springframework.integration.store.SimpleMessageStore in project spring-integration by spring-projects.

the class AbstractCorrelatingMessageHandlerTests method testScheduleRemoveAnEmptyGroupAfterConfiguredDelay.

@Test
public void testScheduleRemoveAnEmptyGroupAfterConfiguredDelay() throws Exception {
    final MessageGroupStore groupStore = new SimpleMessageStore();
    AggregatingMessageHandler handler = new AggregatingMessageHandler(group -> group, groupStore);
    final List<Message<?>> outputMessages = new ArrayList<Message<?>>();
    handler.setOutputChannel((message, timeout) -> {
        /*
			 * Executes when group 'bar' completes normally
			 */
        outputMessages.add(message);
        return true;
    });
    handler.setReleaseStrategy(group -> group.size() == 1);
    handler.setMinimumTimeoutForEmptyGroups(100);
    ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
    taskScheduler.afterPropertiesSet();
    handler.setTaskScheduler(taskScheduler);
    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());
    Thread.sleep(100);
    int n = 0;
    while (TestUtils.getPropertyValue(handler, "messageStore.groupIdToMessageGroup", Map.class).size() > 0 && n++ < 200) {
        Thread.sleep(50);
    }
    assertTrue(n < 200);
    assertEquals(0, TestUtils.getPropertyValue(handler, "messageStore.groupIdToMessageGroup", Map.class).size());
}
Also used : MessageGroupStore(org.springframework.integration.store.MessageGroupStore) SimpleMessageStore(org.springframework.integration.store.SimpleMessageStore) Message(org.springframework.messaging.Message) GenericMessage(org.springframework.messaging.support.GenericMessage) ArrayList(java.util.ArrayList) Map(java.util.Map) ThreadPoolTaskScheduler(org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler) Test(org.junit.Test)

Example 20 with SimpleMessageStore

use of org.springframework.integration.store.SimpleMessageStore in project spring-integration by spring-projects.

the class AbstractCorrelatingMessageHandlerTests method testInt3483DeadlockOnMessageStoreRemoveMessageGroup.

@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() {

        @Override
        public void removeMessageGroup(Object groupId) {
            throw new RuntimeException("intentional");
        }
    };
    handler.setMessageStore(messageStore);
    handler.handleMessage(MessageBuilder.withPayload("foo").setCorrelationId(1).setSequenceNumber(1).setSequenceSize(2).build());
    try {
        messageStore.expireMessageGroups(0);
    } catch (Exception e) {
    // suppress an intentional 'removeMessageGroup' exception
    }
    ExecutorService executorService = Executors.newSingleThreadExecutor();
    executorService.execute(() -> handler.handleMessage(MessageBuilder.withPayload("foo").setCorrelationId(1).setSequenceNumber(2).setSequenceSize(2).build()));
    executorService.shutdown();
    /* Previously lock for the groupId hasn't been unlocked from the 'forceComplete', because it wasn't
		 reachable in case of exception from the BasicMessageGroupStore.removeMessageGroup
		  */
    assertTrue(executorService.awaitTermination(10, TimeUnit.SECONDS));
    /* Since MessageGroup had been marked as 'complete', but hasn't been removed because of exception,
		 the second message is discarded
		  */
    Message<?> receive = discardChannel.receive(10000);
    assertNotNull(receive);
}
Also used : SimpleMessageStore(org.springframework.integration.store.SimpleMessageStore) QueueChannel(org.springframework.integration.channel.QueueChannel) ExecutorService(java.util.concurrent.ExecutorService) Test(org.junit.Test)

Aggregations

SimpleMessageStore (org.springframework.integration.store.SimpleMessageStore)25 Test (org.junit.Test)20 GenericMessage (org.springframework.messaging.support.GenericMessage)10 MessageGroupStore (org.springframework.integration.store.MessageGroupStore)8 Message (org.springframework.messaging.Message)8 AtomicReference (java.util.concurrent.atomic.AtomicReference)6 MessageGroupQueue (org.springframework.integration.store.MessageGroupQueue)6 LongRunningIntegrationTest (org.springframework.integration.test.support.LongRunningIntegrationTest)6 QueueChannel (org.springframework.integration.channel.QueueChannel)5 ArrayList (java.util.ArrayList)4 Collection (java.util.Collection)3 MessageStore (org.springframework.integration.store.MessageStore)3 UUID (java.util.UUID)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 ExecutorService (java.util.concurrent.ExecutorService)2 DirectChannel (org.springframework.integration.channel.DirectChannel)2 MessageGroup (org.springframework.integration.store.MessageGroup)2 SimpleMessageGroupFactory (org.springframework.integration.store.SimpleMessageGroupFactory)2 StopWatch (org.springframework.util.StopWatch)2 Method (java.lang.reflect.Method)1