use of org.springframework.scheduling.support.PeriodicTrigger in project spring-integration by spring-projects.
the class AbstractMethodAnnotationPostProcessor method configurePollingEndpoint.
protected void configurePollingEndpoint(AbstractPollingEndpoint pollingEndpoint, List<Annotation> annotations) {
PollerMetadata pollerMetadata = null;
Poller[] pollers = MessagingAnnotationUtils.resolveAttribute(annotations, "poller", Poller[].class);
if (!ObjectUtils.isEmpty(pollers)) {
Assert.state(pollers.length == 1, "The 'poller' for an Annotation-based endpoint can have only one '@Poller'.");
Poller poller = pollers[0];
String ref = poller.value();
String triggerRef = poller.trigger();
String executorRef = poller.taskExecutor();
String fixedDelayValue = this.beanFactory.resolveEmbeddedValue(poller.fixedDelay());
String fixedRateValue = this.beanFactory.resolveEmbeddedValue(poller.fixedRate());
String maxMessagesPerPollValue = this.beanFactory.resolveEmbeddedValue(poller.maxMessagesPerPoll());
String cron = this.beanFactory.resolveEmbeddedValue(poller.cron());
String errorChannel = this.beanFactory.resolveEmbeddedValue(poller.errorChannel());
if (StringUtils.hasText(ref)) {
Assert.state(!StringUtils.hasText(triggerRef) && !StringUtils.hasText(executorRef) && !StringUtils.hasText(cron) && !StringUtils.hasText(fixedDelayValue) && !StringUtils.hasText(fixedRateValue) && !StringUtils.hasText(maxMessagesPerPollValue), "The '@Poller' 'ref' attribute is mutually exclusive with other attributes.");
pollerMetadata = this.beanFactory.getBean(ref, PollerMetadata.class);
} else {
pollerMetadata = new PollerMetadata();
if (StringUtils.hasText(maxMessagesPerPollValue)) {
pollerMetadata.setMaxMessagesPerPoll(Long.parseLong(maxMessagesPerPollValue));
} else if (pollingEndpoint instanceof SourcePollingChannelAdapter) {
// SPCAs default to 1 message per poll
pollerMetadata.setMaxMessagesPerPoll(1);
}
if (StringUtils.hasText(executorRef)) {
pollerMetadata.setTaskExecutor(this.beanFactory.getBean(executorRef, TaskExecutor.class));
}
Trigger trigger = null;
if (StringUtils.hasText(triggerRef)) {
Assert.state(!StringUtils.hasText(cron) && !StringUtils.hasText(fixedDelayValue) && !StringUtils.hasText(fixedRateValue), "The '@Poller' 'trigger' attribute is mutually exclusive with other attributes.");
trigger = this.beanFactory.getBean(triggerRef, Trigger.class);
} else if (StringUtils.hasText(cron)) {
Assert.state(!StringUtils.hasText(fixedDelayValue) && !StringUtils.hasText(fixedRateValue), "The '@Poller' 'cron' attribute is mutually exclusive with other attributes.");
trigger = new CronTrigger(cron);
} else if (StringUtils.hasText(fixedDelayValue)) {
Assert.state(!StringUtils.hasText(fixedRateValue), "The '@Poller' 'fixedDelay' attribute is mutually exclusive with other attributes.");
trigger = new PeriodicTrigger(Long.parseLong(fixedDelayValue));
} else if (StringUtils.hasText(fixedRateValue)) {
trigger = new PeriodicTrigger(Long.parseLong(fixedRateValue));
((PeriodicTrigger) trigger).setFixedRate(true);
}
// 'Trigger' can be null. 'PollingConsumer' does fallback to the 'new PeriodicTrigger(10)'.
pollerMetadata.setTrigger(trigger);
if (StringUtils.hasText(errorChannel)) {
MessagePublishingErrorHandler errorHandler = new MessagePublishingErrorHandler();
errorHandler.setDefaultErrorChannelName(errorChannel);
errorHandler.setBeanFactory(this.beanFactory);
pollerMetadata.setErrorHandler(errorHandler);
}
}
} else {
pollerMetadata = PollerMetadata.getDefaultPollerMetadata(this.beanFactory);
Assert.notNull(pollerMetadata, "No poller has been defined for Annotation-based endpoint, " + "and no default poller is available within the context.");
}
pollingEndpoint.setTaskExecutor(pollerMetadata.getTaskExecutor());
pollingEndpoint.setTrigger(pollerMetadata.getTrigger());
pollingEndpoint.setAdviceChain(pollerMetadata.getAdviceChain());
pollingEndpoint.setMaxMessagesPerPoll(pollerMetadata.getMaxMessagesPerPoll());
pollingEndpoint.setErrorHandler(pollerMetadata.getErrorHandler());
if (pollingEndpoint instanceof PollingConsumer) {
((PollingConsumer) pollingEndpoint).setReceiveTimeout(pollerMetadata.getReceiveTimeout());
}
pollingEndpoint.setTransactionSynchronizationFactory(pollerMetadata.getTransactionSynchronizationFactory());
}
use of org.springframework.scheduling.support.PeriodicTrigger in project spring-integration by spring-projects.
the class ExpressionEvaluatingMessageSourceIntegrationTests method test.
@Test
public void test() throws Exception {
QueueChannel channel = new QueueChannel();
String payloadExpression = "'test-' + T(org.springframework.integration.endpoint.ExpressionEvaluatingMessageSourceIntegrationTests).next()";
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.afterPropertiesSet();
Map<String, Expression> headerExpressions = new HashMap<String, Expression>();
headerExpressions.put("foo", new LiteralExpression("x"));
headerExpressions.put("bar", new SpelExpressionParser().parseExpression("7 * 6"));
ExpressionFactoryBean factoryBean = new ExpressionFactoryBean(payloadExpression);
factoryBean.afterPropertiesSet();
Expression expression = factoryBean.getObject();
ExpressionEvaluatingMessageSource<Object> source = new ExpressionEvaluatingMessageSource<Object>(expression, Object.class);
source.setBeanFactory(mock(BeanFactory.class));
source.setHeaderExpressions(headerExpressions);
SourcePollingChannelAdapter adapter = new SourcePollingChannelAdapter();
adapter.setSource(source);
adapter.setTaskScheduler(scheduler);
adapter.setMaxMessagesPerPoll(3);
adapter.setTrigger(new PeriodicTrigger(60000));
adapter.setOutputChannel(channel);
adapter.setErrorHandler(t -> {
throw new IllegalStateException("unexpected exception in test", t);
});
adapter.start();
List<Message<?>> messages = new ArrayList<Message<?>>();
for (int i = 0; i < 3; i++) {
messages.add(channel.receive(1000));
}
scheduler.destroy();
Message<?> message1 = messages.get(0);
assertEquals("test-1", message1.getPayload());
assertEquals("x", message1.getHeaders().get("foo"));
assertEquals(42, message1.getHeaders().get("bar"));
Message<?> message2 = messages.get(1);
assertEquals("test-2", message2.getPayload());
assertEquals("x", message2.getHeaders().get("foo"));
assertEquals(42, message2.getHeaders().get("bar"));
Message<?> message3 = messages.get(2);
assertEquals("test-3", message3.getPayload());
assertEquals("x", message3.getHeaders().get("foo"));
assertEquals(42, message3.getHeaders().get("bar"));
}
use of org.springframework.scheduling.support.PeriodicTrigger in project spring-integration by spring-projects.
the class PollerAdviceTests method testCompoundTriggerAdvice.
@Test
public void testCompoundTriggerAdvice() throws Exception {
SourcePollingChannelAdapter adapter = new SourcePollingChannelAdapter();
final CountDownLatch latch = new CountDownLatch(5);
final LinkedList<Object> overridePresent = new LinkedList<Object>();
final CompoundTrigger compoundTrigger = new CompoundTrigger(new PeriodicTrigger(10));
Trigger override = spy(new PeriodicTrigger(5));
final CompoundTriggerAdvice advice = new CompoundTriggerAdvice(compoundTrigger, override);
adapter.setSource(() -> {
overridePresent.add(TestUtils.getPropertyValue(compoundTrigger, "override"));
Message<Object> m = null;
if (latch.getCount() % 2 == 0) {
m = new GenericMessage<>("foo");
}
latch.countDown();
return m;
});
adapter.setAdviceChain(Collections.singletonList(advice));
adapter.setTrigger(compoundTrigger);
configure(adapter);
adapter.afterPropertiesSet();
adapter.start();
assertTrue(latch.await(10, TimeUnit.SECONDS));
adapter.stop();
while (overridePresent.size() > 5) {
overridePresent.removeLast();
}
assertThat(overridePresent, contains(null, override, null, override, null));
verify(override, atLeast(2)).nextExecutionTime(any(TriggerContext.class));
}
use of org.springframework.scheduling.support.PeriodicTrigger in project spring-integration by spring-projects.
the class PollingLifecycleTests method ensurePollerTaskStops.
@Test
public void ensurePollerTaskStops() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);
QueueChannel channel = new QueueChannel();
channel.send(new GenericMessage<String>("foo"));
MessageHandler handler = Mockito.spy(new MessageHandler() {
@Override
public void handleMessage(Message<?> message) throws MessagingException {
latch.countDown();
}
});
PollingConsumer consumer = new PollingConsumer(channel, handler);
consumer.setTrigger(new PeriodicTrigger(0));
consumer.setErrorHandler(errorHandler);
consumer.setTaskScheduler(taskScheduler);
consumer.setBeanFactory(mock(BeanFactory.class));
consumer.afterPropertiesSet();
consumer.start();
assertTrue(latch.await(2, TimeUnit.SECONDS));
Mockito.verify(handler, times(1)).handleMessage(Mockito.any(Message.class));
consumer.stop();
for (int i = 0; i < 10; i++) {
channel.send(new GenericMessage<String>("foo"));
}
// give enough time for poller to kick in if it didn't stop properly
Thread.sleep(2000);
// we'll still have a natural race condition between call to stop() and poller polling
// so what we really have to assert is that it doesn't poll for more then once after stop() was called
Mockito.reset(handler);
Mockito.verify(handler, atMost(1)).handleMessage(Mockito.any(Message.class));
}
use of org.springframework.scheduling.support.PeriodicTrigger in project spring-integration by spring-projects.
the class SourcePollingChannelAdapterFactoryBeanTests method testTransactionalAdviceChain.
@Test
public void testTransactionalAdviceChain() throws Throwable {
SourcePollingChannelAdapterFactoryBean factoryBean = new SourcePollingChannelAdapterFactoryBean();
QueueChannel outputChannel = new QueueChannel();
TestApplicationContext context = TestUtils.createTestApplicationContext();
factoryBean.setBeanFactory(context.getBeanFactory());
factoryBean.setBeanClassLoader(ClassUtils.getDefaultClassLoader());
factoryBean.setOutputChannel(outputChannel);
factoryBean.setSource(() -> new GenericMessage<>("test"));
PollerMetadata pollerMetadata = new PollerMetadata();
List<Advice> adviceChain = new ArrayList<Advice>();
final AtomicBoolean adviceApplied = new AtomicBoolean(false);
adviceChain.add((MethodInterceptor) invocation -> {
adviceApplied.set(true);
return invocation.proceed();
});
pollerMetadata.setTrigger(new PeriodicTrigger(5000));
pollerMetadata.setMaxMessagesPerPoll(1);
final AtomicInteger count = new AtomicInteger();
final MethodInterceptor txAdvice = mock(MethodInterceptor.class);
adviceChain.add((MethodInterceptor) invocation -> {
count.incrementAndGet();
return invocation.proceed();
});
when(txAdvice.invoke(any(MethodInvocation.class))).thenAnswer(invocation -> {
count.incrementAndGet();
return ((MethodInvocation) invocation.getArgument(0)).proceed();
});
pollerMetadata.setAdviceChain(adviceChain);
factoryBean.setPollerMetadata(pollerMetadata);
factoryBean.setAutoStartup(true);
factoryBean.afterPropertiesSet();
context.registerEndpoint("testPollingEndpoint", factoryBean.getObject());
context.refresh();
Message<?> message = outputChannel.receive(5000);
assertEquals("test", message.getPayload());
assertEquals(1, count.get());
assertTrue("adviceChain was not applied", adviceApplied.get());
}
Aggregations