Fix compatibility with the latest SF

* Mostly changes are related to the `TaskScheduler` and `Trigger` APIs
* Migrate to `micrometer-tracing` dependency
* Rework `SocketTestUtils` to use a `InetAddress.getLocalHost()`
for more stability and performance on Windows
* Fix docs for new `PeriodicTrigger` API
This commit is contained in:
Artem Bilan
2022-07-08 17:36:15 -04:00
parent 64aa4d5348
commit e0f137905a
46 changed files with 565 additions and 586 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -19,10 +19,13 @@ package org.springframework.integration.bus;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import java.time.Duration;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@@ -51,13 +54,24 @@ import org.springframework.scheduling.support.PeriodicTrigger;
*/
public class ApplicationContextMessageBusTests {
private TestApplicationContext context;
@BeforeEach
void setup() {
this.context = TestUtils.createTestApplicationContext();
}
@AfterEach
void tearDown() {
this.context.close();
}
@Test
public void endpointRegistrationWithInputChannelReference() {
TestApplicationContext context = TestUtils.createTestApplicationContext();
QueueChannel sourceChannel = new QueueChannel();
QueueChannel targetChannel = new QueueChannel();
context.registerChannel("sourceChannel", sourceChannel);
context.registerChannel("targetChannel", targetChannel);
this.context.registerChannel("sourceChannel", sourceChannel);
this.context.registerChannel("targetChannel", targetChannel);
Message<String> message = MessageBuilder.withPayload("test")
.setReplyChannelName("targetChannel").build();
sourceChannel.send(message);
@@ -68,29 +82,26 @@ public class ApplicationContextMessageBusTests {
return message;
}
};
handler.setBeanFactory(context);
handler.setBeanFactory(this.context);
handler.afterPropertiesSet();
PollingConsumer endpoint = new PollingConsumer(sourceChannel, handler);
endpoint.setBeanFactory(mock(BeanFactory.class));
context.registerEndpoint("testEndpoint", endpoint);
context.refresh();
this.context.registerEndpoint("testEndpoint", endpoint);
this.context.refresh();
Message<?> result = targetChannel.receive(10000);
assertThat(result.getPayload()).isEqualTo("test");
context.close();
}
@Test
public void channelsWithoutHandlers() {
TestApplicationContext context = TestUtils.createTestApplicationContext();
QueueChannel sourceChannel = new QueueChannel();
context.registerChannel("sourceChannel", sourceChannel);
this.context.registerChannel("sourceChannel", sourceChannel);
sourceChannel.send(new GenericMessage<>("test"));
QueueChannel targetChannel = new QueueChannel();
context.registerChannel("targetChannel", targetChannel);
context.refresh();
this.context.registerChannel("targetChannel", targetChannel);
this.context.refresh();
Message<?> result = targetChannel.receive(10);
assertThat(result).isNull();
context.close();
}
@Test
@@ -108,7 +119,6 @@ public class ApplicationContextMessageBusTests {
@Test
public void exactlyOneConsumerReceivesPointToPointMessage() {
TestApplicationContext context = TestUtils.createTestApplicationContext();
QueueChannel inputChannel = new QueueChannel();
QueueChannel outputChannel1 = new QueueChannel();
QueueChannel outputChannel2 = new QueueChannel();
@@ -126,28 +136,26 @@ public class ApplicationContextMessageBusTests {
return message;
}
};
context.registerChannel("input", inputChannel);
context.registerChannel("output1", outputChannel1);
context.registerChannel("output2", outputChannel2);
this.context.registerChannel("input", inputChannel);
this.context.registerChannel("output1", outputChannel1);
this.context.registerChannel("output2", outputChannel2);
handler1.setOutputChannel(outputChannel1);
handler2.setOutputChannel(outputChannel2);
PollingConsumer endpoint1 = new PollingConsumer(inputChannel, handler1);
endpoint1.setBeanFactory(mock(BeanFactory.class));
PollingConsumer endpoint2 = new PollingConsumer(inputChannel, handler2);
endpoint2.setBeanFactory(mock(BeanFactory.class));
context.registerEndpoint("testEndpoint1", endpoint1);
context.registerEndpoint("testEndpoint2", endpoint2);
context.refresh();
this.context.registerEndpoint("testEndpoint1", endpoint1);
this.context.registerEndpoint("testEndpoint2", endpoint2);
this.context.refresh();
inputChannel.send(new GenericMessage<>("testing"));
Message<?> message1 = outputChannel1.receive(10000);
Message<?> message2 = outputChannel2.receive(0);
context.close();
assertThat(message1 == null ^ message2 == null).as("exactly one message should be null").isTrue();
}
@Test
public void bothConsumersReceivePublishSubscribeMessage() throws InterruptedException {
TestApplicationContext context = TestUtils.createTestApplicationContext();
PublishSubscribeChannel inputChannel = new PublishSubscribeChannel();
QueueChannel outputChannel1 = new QueueChannel();
QueueChannel outputChannel2 = new QueueChannel();
@@ -168,43 +176,40 @@ public class ApplicationContextMessageBusTests {
return message;
}
};
context.registerChannel("input", inputChannel);
context.registerChannel("output1", outputChannel1);
context.registerChannel("output2", outputChannel2);
this.context.registerChannel("input", inputChannel);
this.context.registerChannel("output1", outputChannel1);
this.context.registerChannel("output2", outputChannel2);
handler1.setOutputChannel(outputChannel1);
handler2.setOutputChannel(outputChannel2);
EventDrivenConsumer endpoint1 = new EventDrivenConsumer(inputChannel, handler1);
EventDrivenConsumer endpoint2 = new EventDrivenConsumer(inputChannel, handler2);
context.registerEndpoint("testEndpoint1", endpoint1);
context.registerEndpoint("testEndpoint2", endpoint2);
context.refresh();
inputChannel.send(new GenericMessage<String>("testing"));
this.context.registerEndpoint("testEndpoint1", endpoint1);
this.context.registerEndpoint("testEndpoint2", endpoint2);
this.context.refresh();
inputChannel.send(new GenericMessage<>("testing"));
latch.await(500, TimeUnit.MILLISECONDS);
assertThat(latch.getCount()).as("both handlers should have been invoked").isEqualTo(0);
Message<?> message1 = outputChannel1.receive(500);
Message<?> message2 = outputChannel2.receive(500);
context.close();
assertThat(message1).as("both handlers should have replied to the message").isNotNull();
assertThat(message2).as("both handlers should have replied to the message").isNotNull();
}
@Test
public void errorChannelWithFailedDispatch() throws InterruptedException {
TestApplicationContext context = TestUtils.createTestApplicationContext();
QueueChannel errorChannel = new QueueChannel();
QueueChannel outputChannel = new QueueChannel();
context.registerChannel("errorChannel", errorChannel);
this.context.registerChannel("errorChannel", errorChannel);
CountDownLatch latch = new CountDownLatch(1);
SourcePollingChannelAdapter channelAdapter = new SourcePollingChannelAdapter();
channelAdapter.setSource(new FailingSource(latch));
PollerMetadata pollerMetadata = new PollerMetadata();
pollerMetadata.setTrigger(new PeriodicTrigger(1000));
pollerMetadata.setTrigger(new PeriodicTrigger(Duration.ofSeconds(1)));
channelAdapter.setOutputChannel(outputChannel);
context.registerEndpoint("testChannel", channelAdapter);
context.refresh();
this.context.registerEndpoint("testChannel", channelAdapter);
this.context.refresh();
latch.await(2000, TimeUnit.MILLISECONDS);
Message<?> message = errorChannel.receive(5000);
context.close();
assertThat(outputChannel.receive(100)).isNull();
assertThat(message).as("message should not be null").isNotNull();
assertThat(message instanceof ErrorMessage).isTrue();
@@ -214,9 +219,8 @@ public class ApplicationContextMessageBusTests {
@Test
public void consumerSubscribedToErrorChannel() throws InterruptedException {
TestApplicationContext context = TestUtils.createTestApplicationContext();
QueueChannel errorChannel = new QueueChannel();
context.registerChannel(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME, errorChannel);
this.context.registerChannel(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME, errorChannel);
final CountDownLatch latch = new CountDownLatch(1);
AbstractReplyProducingMessageHandler handler = new AbstractReplyProducingMessageHandler() {
@@ -228,22 +232,15 @@ public class ApplicationContextMessageBusTests {
};
PollingConsumer endpoint = new PollingConsumer(errorChannel, handler);
endpoint.setBeanFactory(mock(BeanFactory.class));
context.registerEndpoint("testEndpoint", endpoint);
context.refresh();
this.context.registerEndpoint("testEndpoint", endpoint);
this.context.refresh();
errorChannel.send(new ErrorMessage(new RuntimeException("test-exception")));
latch.await(1000, TimeUnit.MILLISECONDS);
assertThat(latch.getCount()).as("handler should have received error message").isEqualTo(0);
context.close();
}
private static class FailingSource implements MessageSource<Object> {
private final CountDownLatch latch;
FailingSource(CountDownLatch latch) {
this.latch = latch;
}
private record FailingSource(CountDownLatch latch) implements MessageSource<Object> {
@Override
public Message<Object> receive() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@@ -85,7 +86,7 @@ public class SourcePollingChannelAdapterFactoryBeanTests {
adviceApplied.set(true);
return invocation.proceed();
});
pollerMetadata.setTrigger(new PeriodicTrigger(5000));
pollerMetadata.setTrigger(new PeriodicTrigger(Duration.ofSeconds(5)));
pollerMetadata.setMaxMessagesPerPoll(1);
pollerMetadata.setAdviceChain(adviceChain);
factoryBean.setPollerMetadata(pollerMetadata);
@@ -115,7 +116,7 @@ public class SourcePollingChannelAdapterFactoryBeanTests {
adviceApplied.set(true);
return invocation.proceed();
});
pollerMetadata.setTrigger(new PeriodicTrigger(5000));
pollerMetadata.setTrigger(new PeriodicTrigger(Duration.ofSeconds(5)));
pollerMetadata.setMaxMessagesPerPoll(1);
final AtomicInteger count = new AtomicInteger();
final MethodInterceptor txAdvice = mock(MethodInterceptor.class);
@@ -232,7 +233,7 @@ public class SourcePollingChannelAdapterFactoryBeanTests {
SourcePollingChannelAdapter pollingChannelAdapter = new SourcePollingChannelAdapter();
pollingChannelAdapter.setTaskScheduler(taskScheduler);
pollingChannelAdapter.setSource(() -> new GenericMessage<>("test"));
pollingChannelAdapter.setTrigger(new PeriodicTrigger(1));
pollingChannelAdapter.setTrigger(new PeriodicTrigger(Duration.ofMillis(1)));
pollingChannelAdapter.setMaxMessagesPerPoll(0);
QueueChannel outputChannel = new QueueChannel();
pollingChannelAdapter.setOutputChannel(outputChannel);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -16,7 +16,8 @@
package org.springframework.integration.config;
import java.util.Date;
import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.ScheduledFuture;
import org.springframework.scheduling.TaskScheduler;
@@ -24,30 +25,38 @@ import org.springframework.scheduling.Trigger;
/**
* @author Mark Fisher
* @author Artem Bilan
*/
public class StubTaskScheduler implements TaskScheduler {
@Override
public ScheduledFuture<?> schedule(Runnable task, Trigger trigger) {
return null;
}
public ScheduledFuture<?> schedule(Runnable task, Date startTime) {
@Override
public ScheduledFuture<?> schedule(Runnable task, Instant startTime) {
return null;
}
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, long period) {
@Override
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Instant startTime, Duration period) {
return null;
}
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Date startTime, long period) {
@Override
public ScheduledFuture<?> scheduleAtFixedRate(Runnable task, Duration period) {
return null;
}
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, long delay) {
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Instant startTime, Duration delay) {
return null;
}
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
@Override
public ScheduledFuture<?> scheduleWithFixedDelay(Runnable task, Duration delay) {
return null;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2019 the original author or authors.
* Copyright 2016-2022 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.
@@ -16,17 +16,19 @@
package org.springframework.integration.config;
import java.util.Date;
import java.time.Instant;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
/**
* @author Marius Bogoevici
* @author Artem Bilan
*/
public class TestTrigger implements Trigger {
public Date nextExecutionTime(TriggerContext triggerContext) {
@Override
public Instant nextExecution(TriggerContext triggerContext) {
throw new UnsupportedOperationException();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -18,6 +18,7 @@ package org.springframework.integration.config.xml;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Duration;
import java.util.Map;
import org.junit.jupiter.api.Test;
@@ -57,7 +58,7 @@ public class InboundChannelAdapterExpressionTests {
Trigger trigger = TestUtils.getPropertyValue(adapter, "trigger", Trigger.class);
assertThat(trigger.getClass()).isEqualTo(PeriodicTrigger.class);
DirectFieldAccessor triggerAccessor = new DirectFieldAccessor(trigger);
assertThat(triggerAccessor.getPropertyValue("period")).isEqualTo(1234L);
assertThat(triggerAccessor.getPropertyValue("period")).isEqualTo(Duration.ofMillis(1234));
assertThat(triggerAccessor.getPropertyValue("fixedRate")).isEqualTo(Boolean.FALSE);
assertThat(adapterAccessor.getPropertyValue("outputChannel"))
.isEqualTo(this.context.getBean("fixedDelayChannel"));
@@ -74,7 +75,7 @@ public class InboundChannelAdapterExpressionTests {
Trigger trigger = TestUtils.getPropertyValue(adapter, "trigger", Trigger.class);
assertThat(trigger.getClass()).isEqualTo(PeriodicTrigger.class);
DirectFieldAccessor triggerAccessor = new DirectFieldAccessor(trigger);
assertThat(triggerAccessor.getPropertyValue("period")).isEqualTo(5678L);
assertThat(triggerAccessor.getPropertyValue("period")).isEqualTo(Duration.ofMillis(5678));
assertThat(triggerAccessor.getPropertyValue("fixedRate")).isEqualTo(Boolean.TRUE);
assertThat(adapterAccessor.getPropertyValue("outputChannel"))
.isEqualTo(this.context.getBean("fixedRateChannel"));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -18,23 +18,22 @@ package org.springframework.integration.config.xml;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
/**
* @author Mark Fisher
* @author Artem Bilan
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringJUnitConfig
public class InboundChannelAdapterWithDefaultPollerTests {
@Autowired
@@ -44,10 +43,10 @@ public class InboundChannelAdapterWithDefaultPollerTests {
@Test
public void verifyDefaultPollerInUse() {
Trigger trigger = TestUtils.getPropertyValue(adapter, "trigger", Trigger.class);
assertThat(trigger.getClass()).isEqualTo(PeriodicTrigger.class);
DirectFieldAccessor triggerAccessor = new DirectFieldAccessor(trigger);
assertThat(triggerAccessor.getPropertyValue("period")).isEqualTo(12345L);
assertThat(triggerAccessor.getPropertyValue("fixedRate")).isEqualTo(Boolean.TRUE);
assertThat(trigger).isInstanceOf(PeriodicTrigger.class);
PeriodicTrigger periodicTrigger = (PeriodicTrigger) trigger;
assertThat(periodicTrigger.getPeriodDuration()).isEqualTo(Duration.ofMillis(12345));
assertThat(periodicTrigger.isFixedRate()).isTrue();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -18,53 +18,45 @@ package org.springframework.integration.config.xml;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.integration.scheduling.PollerMetadata;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
/**
* @author Marius Bogoevici
* @author Artem Bilan
*/
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringJUnitConfig
public class IntervalTriggerParserTests {
@Autowired
ApplicationContext context;
PollerMetadata pollerWithFixedRateAttribute;
@Autowired
PollerMetadata pollerWithFixedDelayAttribute;
@Test
public void testFixedRateTrigger() {
Object poller = context.getBean("pollerWithFixedRateAttribute");
assertThat(poller.getClass()).isEqualTo(PollerMetadata.class);
PollerMetadata metadata = (PollerMetadata) poller;
Trigger trigger = metadata.getTrigger();
assertThat(trigger.getClass()).isEqualTo(PeriodicTrigger.class);
DirectFieldAccessor accessor = new DirectFieldAccessor(trigger);
Boolean fixedRate = (Boolean) accessor.getPropertyValue("fixedRate");
Long period = (Long) accessor.getPropertyValue("period");
assertThat(true).isEqualTo(fixedRate);
assertThat(period.longValue()).isEqualTo(36L);
Trigger trigger = this.pollerWithFixedRateAttribute.getTrigger();
assertThat(trigger).isInstanceOf(PeriodicTrigger.class);
PeriodicTrigger periodicTrigger = (PeriodicTrigger) trigger;
assertThat(periodicTrigger.getPeriodDuration()).isEqualTo(Duration.ofMillis(36));
assertThat(periodicTrigger.isFixedRate()).isTrue();
}
@Test
public void testFixedDelayTrigger() {
Object poller = context.getBean("pollerWithFixedDelayAttribute");
assertThat(poller.getClass()).isEqualTo(PollerMetadata.class);
PollerMetadata metadata = (PollerMetadata) poller;
Trigger trigger = metadata.getTrigger();
assertThat(trigger.getClass()).isEqualTo(PeriodicTrigger.class);
DirectFieldAccessor accessor = new DirectFieldAccessor(trigger);
Boolean fixedRate = (Boolean) accessor.getPropertyValue("fixedRate");
Long period = (Long) accessor.getPropertyValue("period");
assertThat(false).isEqualTo(fixedRate);
assertThat(period.longValue()).isEqualTo(37L);
Trigger trigger = this.pollerWithFixedDelayAttribute.getTrigger();
assertThat(trigger).isInstanceOf(PeriodicTrigger.class);
PeriodicTrigger periodicTrigger = (PeriodicTrigger) trigger;
assertThat(periodicTrigger.getPeriodDuration()).isEqualTo(Duration.ofMillis(37));
assertThat(periodicTrigger.isFixedRate()).isFalse();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -17,12 +17,13 @@
package org.springframework.integration.config.xml;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import org.aopalliance.aop.Advice;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@@ -62,16 +63,18 @@ public class PollerParserTests {
context.close();
}
@Test(expected = BeanDefinitionParsingException.class)
@Test
public void multipleDefaultPollers() {
new ClassPathXmlApplicationContext(
"multipleDefaultPollers.xml", PollerParserTests.class).close();
assertThatExceptionOfType(BeanDefinitionParsingException.class)
.isThrownBy(() ->
new ClassPathXmlApplicationContext("multipleDefaultPollers.xml", PollerParserTests.class));
}
@Test(expected = BeanDefinitionParsingException.class)
@Test
public void topLevelPollerWithoutId() {
new ClassPathXmlApplicationContext(
"topLevelPollerWithoutId.xml", PollerParserTests.class).close();
assertThatExceptionOfType(BeanDefinitionParsingException.class)
.isThrownBy(() ->
new ClassPathXmlApplicationContext("topLevelPollerWithoutId.xml", PollerParserTests.class));
}
@Test
@@ -89,8 +92,9 @@ public class PollerParserTests {
assertThat(metadata.getAdviceChain().get(2)).isSameAs(context.getBean("adviceBean3"));
Advice txAdvice = metadata.getAdviceChain().get(3);
assertThat(txAdvice.getClass()).isEqualTo(TransactionInterceptor.class);
TransactionAttributeSource transactionAttributeSource = ((TransactionInterceptor) txAdvice).getTransactionAttributeSource();
assertThat(transactionAttributeSource.getClass()).isEqualTo(NameMatchTransactionAttributeSource.class);
TransactionAttributeSource transactionAttributeSource =
((TransactionInterceptor) txAdvice).getTransactionAttributeSource();
assertThat(transactionAttributeSource).isInstanceOf(NameMatchTransactionAttributeSource.class);
@SuppressWarnings("rawtypes")
HashMap nameMap = TestUtils.getPropertyValue(transactionAttributeSource, "nameMap", HashMap.class);
assertThat(nameMap.size()).isEqualTo(1);
@@ -108,7 +112,7 @@ public class PollerParserTests {
PollerMetadata metadata = (PollerMetadata) poller;
assertThat(metadata.getReceiveTimeout()).isEqualTo(1234);
PeriodicTrigger trigger = (PeriodicTrigger) metadata.getTrigger();
assertThat(TestUtils.getPropertyValue(trigger, "timeUnit").toString()).isEqualTo(TimeUnit.SECONDS.toString());
assertThat(TestUtils.getPropertyValue(trigger, "chronoUnit")).isEqualTo(ChronoUnit.SECONDS);
context.close();
}
@@ -123,22 +127,25 @@ public class PollerParserTests {
context.close();
}
@Test(expected = BeanDefinitionParsingException.class)
@Test
public void pollerWithCronTriggerAndTimeUnit() {
new ClassPathXmlApplicationContext(
"cronTriggerWithTimeUnit-fail.xml", PollerParserTests.class).close();
assertThatExceptionOfType(BeanDefinitionParsingException.class)
.isThrownBy(() ->
new ClassPathXmlApplicationContext("cronTriggerWithTimeUnit-fail.xml", PollerParserTests.class));
}
@Test(expected = BeanDefinitionParsingException.class)
@Test
public void topLevelPollerWithRef() {
new ClassPathXmlApplicationContext(
"defaultPollerWithRef.xml", PollerParserTests.class).close();
assertThatExceptionOfType(BeanDefinitionParsingException.class)
.isThrownBy(() ->
new ClassPathXmlApplicationContext("defaultPollerWithRef.xml", PollerParserTests.class));
}
@Test(expected = BeanDefinitionParsingException.class)
@Test
public void pollerWithCronAndFixedDelay() {
new ClassPathXmlApplicationContext(
"pollerWithCronAndFixedDelay.xml", PollerParserTests.class).close();
assertThatExceptionOfType(BeanDefinitionParsingException.class)
.isThrownBy(() ->
new ClassPathXmlApplicationContext("pollerWithCronAndFixedDelay.xml", PollerParserTests.class));
}
}

View File

@@ -28,6 +28,7 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.time.Duration;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -62,6 +63,7 @@ import org.springframework.context.annotation.ImportResource;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.expression.EnvironmentAccessor;
import org.springframework.context.expression.MapAccessor;
import org.springframework.core.annotation.AliasFor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.log.LogAccessor;
import org.springframework.core.serializer.support.SerializingConverter;
@@ -319,8 +321,9 @@ public class EnableIntegrationTests {
Trigger trigger = TestUtils.getPropertyValue(this.serviceActivatorEndpoint, "trigger", Trigger.class);
assertThat(trigger).isInstanceOf(PeriodicTrigger.class);
assertThat(TestUtils.getPropertyValue(trigger, "period")).isEqualTo(100L);
assertThat(TestUtils.getPropertyValue(trigger, "fixedRate", Boolean.class)).isFalse();
PeriodicTrigger periodicTrigger = (PeriodicTrigger) trigger;
assertThat(periodicTrigger.getPeriodDuration()).isEqualTo(Duration.ofMillis(100));
assertThat(periodicTrigger.isFixedRate()).isFalse();
assertThat(this.annotationTestService.isRunning()).isTrue();
LogAccessor logger = spy(TestUtils.getPropertyValue(this.serviceActivatorEndpoint, "logger", LogAccessor.class));
@@ -343,8 +346,9 @@ public class EnableIntegrationTests {
trigger = TestUtils.getPropertyValue(this.serviceActivatorEndpoint1, "trigger", Trigger.class);
assertThat(trigger).isInstanceOf(PeriodicTrigger.class);
assertThat(TestUtils.getPropertyValue(trigger, "period")).isEqualTo(100L);
assertThat(TestUtils.getPropertyValue(trigger, "fixedRate", Boolean.class)).isTrue();
periodicTrigger = (PeriodicTrigger) trigger;
assertThat(periodicTrigger.getPeriodDuration()).isEqualTo(Duration.ofMillis(100));
assertThat(periodicTrigger.isFixedRate()).isTrue();
trigger = TestUtils.getPropertyValue(this.serviceActivatorEndpoint2, "trigger", Trigger.class);
assertThat(trigger).isInstanceOf(CronTrigger.class);
@@ -352,19 +356,22 @@ public class EnableIntegrationTests {
trigger = TestUtils.getPropertyValue(this.serviceActivatorEndpoint3, "trigger", Trigger.class);
assertThat(trigger).isInstanceOf(PeriodicTrigger.class);
assertThat(TestUtils.getPropertyValue(trigger, "period")).isEqualTo(11L);
assertThat(TestUtils.getPropertyValue(trigger, "fixedRate", Boolean.class)).isFalse();
periodicTrigger = (PeriodicTrigger) trigger;
assertThat(periodicTrigger.getPeriodDuration()).isEqualTo(Duration.ofMillis(11));
assertThat(periodicTrigger.isFixedRate()).isFalse();
trigger = TestUtils.getPropertyValue(this.serviceActivatorEndpoint4, "trigger", Trigger.class);
assertThat(trigger).isInstanceOf(PeriodicTrigger.class);
assertThat(TestUtils.getPropertyValue(trigger, "period")).isEqualTo(1000L);
assertThat(TestUtils.getPropertyValue(trigger, "fixedRate", Boolean.class)).isFalse();
periodicTrigger = (PeriodicTrigger) trigger;
assertThat(periodicTrigger.getPeriodDuration()).isEqualTo(Duration.ofSeconds(1));
assertThat(periodicTrigger.isFixedRate()).isFalse();
assertThat(trigger).isSameAs(this.myTrigger);
trigger = TestUtils.getPropertyValue(this.transformer, "trigger", Trigger.class);
assertThat(trigger).isInstanceOf(PeriodicTrigger.class);
assertThat(TestUtils.getPropertyValue(trigger, "period")).isEqualTo(10L);
assertThat(TestUtils.getPropertyValue(trigger, "fixedRate", Boolean.class)).isFalse();
periodicTrigger = (PeriodicTrigger) trigger;
assertThat(periodicTrigger.getPeriodDuration()).isEqualTo(Duration.ofMillis(10));
assertThat(periodicTrigger.isFixedRate()).isFalse();
this.input.send(MessageBuilder.withPayload("Foo").build());
@@ -588,7 +595,7 @@ public class EnableIntegrationTests {
assertThat(TestUtils.getPropertyValue(consumer, "handler.outputChannelName")).isEqualTo("annOutput");
assertThat(TestUtils.getPropertyValue(consumer,
"handler.adviceChain", List.class).get(0)).isSameAs(context.getBean("annAdvice"));
assertThat(TestUtils.getPropertyValue(consumer, "trigger.period")).isEqualTo(1000L);
assertThat(TestUtils.getPropertyValue(consumer, "trigger.period")).isEqualTo(Duration.ofSeconds(1));
consumer = this.context.getBean("annotationTestService.annCount1.serviceActivator",
PollingConsumer.class);
@@ -599,7 +606,7 @@ public class EnableIntegrationTests {
assertThat(TestUtils.getPropertyValue(consumer, "handler.outputChannel.beanName")).isEqualTo("annOutput");
assertThat(TestUtils.getPropertyValue(consumer,
"handler.adviceChain", List.class).get(0)).isSameAs(context.getBean("annAdvice1"));
assertThat(TestUtils.getPropertyValue(consumer, "trigger.period")).isEqualTo(2000L);
assertThat(TestUtils.getPropertyValue(consumer, "trigger.period")).isEqualTo(Duration.ofSeconds(2));
consumer = this.context.getBean("annotationTestService.annCount2.serviceActivator",
PollingConsumer.class);
@@ -609,7 +616,7 @@ public class EnableIntegrationTests {
assertThat(TestUtils.getPropertyValue(consumer, "handler.outputChannelName")).isEqualTo("annOutput");
assertThat(TestUtils.getPropertyValue(consumer,
"handler.adviceChain", List.class).get(0)).isSameAs(context.getBean("annAdvice"));
assertThat(TestUtils.getPropertyValue(consumer, "trigger.period")).isEqualTo(1000L);
assertThat(TestUtils.getPropertyValue(consumer, "trigger.period")).isEqualTo(Duration.ofSeconds(1));
// Tests when the channel is in a "middle" annotation
consumer = this.context.getBean("annotationTestService.annCount5.serviceActivator", PollingConsumer.class);
@@ -619,7 +626,7 @@ public class EnableIntegrationTests {
assertThat(TestUtils.getPropertyValue(consumer, "handler.outputChannelName")).isEqualTo("annOutput");
assertThat(TestUtils.getPropertyValue(consumer,
"handler.adviceChain", List.class).get(0)).isSameAs(context.getBean("annAdvice"));
assertThat(TestUtils.getPropertyValue(consumer, "trigger.period")).isEqualTo(1000L);
assertThat(TestUtils.getPropertyValue(consumer, "trigger.period")).isEqualTo(Duration.ofSeconds(1));
consumer = this.context.getBean("annotationTestService.annAgg1.aggregator", PollingConsumer.class);
assertThat(TestUtils.getPropertyValue(consumer, "autoStartup", Boolean.class)).isFalse();
@@ -627,7 +634,7 @@ public class EnableIntegrationTests {
assertThat(TestUtils.getPropertyValue(consumer, "inputChannel")).isSameAs(context.getBean("annInput"));
assertThat(TestUtils.getPropertyValue(consumer, "handler.outputChannelName")).isEqualTo("annOutput");
assertThat(TestUtils.getPropertyValue(consumer, "handler.discardChannelName")).isEqualTo("annOutput");
assertThat(TestUtils.getPropertyValue(consumer, "trigger.period")).isEqualTo(1000L);
assertThat(TestUtils.getPropertyValue(consumer, "trigger.period")).isEqualTo(Duration.ofSeconds(1));
assertThat(TestUtils.getPropertyValue(consumer, "handler.messagingTemplate.sendTimeout")).isEqualTo(-1L);
assertThat(TestUtils.getPropertyValue(consumer, "handler.sendPartialResultOnExpiry", Boolean.class)).isFalse();
@@ -637,7 +644,7 @@ public class EnableIntegrationTests {
assertThat(TestUtils.getPropertyValue(consumer, "inputChannel")).isSameAs(context.getBean("annInput"));
assertThat(TestUtils.getPropertyValue(consumer, "handler.outputChannelName")).isEqualTo("annOutput");
assertThat(TestUtils.getPropertyValue(consumer, "handler.discardChannelName")).isEqualTo("annOutput");
assertThat(TestUtils.getPropertyValue(consumer, "trigger.period")).isEqualTo(1000L);
assertThat(TestUtils.getPropertyValue(consumer, "trigger.period")).isEqualTo(Duration.ofSeconds(1));
assertThat(TestUtils.getPropertyValue(consumer, "handler.messagingTemplate.sendTimeout")).isEqualTo(75L);
assertThat(TestUtils.getPropertyValue(consumer, "handler.sendPartialResultOnExpiry", Boolean.class)).isTrue();
}
@@ -852,7 +859,7 @@ public class EnableIntegrationTests {
@Bean
public Trigger myTrigger() {
return new PeriodicTrigger(1000L);
return new PeriodicTrigger(Duration.ofSeconds(1));
}
@Bean
@@ -1193,14 +1200,14 @@ public class EnableIntegrationTests {
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata defaultPoller() {
PollerMetadata pollerMetadata = new PollerMetadata();
pollerMetadata.setTrigger(new PeriodicTrigger(10));
pollerMetadata.setTrigger(new PeriodicTrigger(Duration.ofMillis(10)));
return pollerMetadata;
}
@Bean
public PollerMetadata myPoller() {
PollerMetadata pollerMetadata = new PollerMetadata();
pollerMetadata.setTrigger(new PeriodicTrigger(11));
pollerMetadata.setTrigger(new PeriodicTrigger(Duration.ofMillis(11)));
return pollerMetadata;
}
@@ -1342,7 +1349,7 @@ public class EnableIntegrationTests {
assertThat(message.getHeaders().get("foo")).isEqualTo("FOO");
assertThat(message.getHeaders()).containsKey("calledMethod");
assertThat(message.getHeaders().get("calledMethod")).isEqualTo("echo");
return handle(message.getPayload()) + Arrays.asList(new Throwable().getStackTrace()).toString();
return handle(message.getPayload()) + Arrays.asList(new Throwable().getStackTrace());
}
@Transformer(inputChannel = "gatewayChannel2")
@@ -1352,7 +1359,7 @@ public class EnableIntegrationTests {
assertThat(message.getHeaders().get("foo")).isEqualTo("FOO");
assertThat(message.getHeaders()).containsKey("calledMethod");
assertThat(message.getHeaders().get("calledMethod")).isEqualTo("echo2");
return handle(message.getPayload()) + "2" + Arrays.asList(new Throwable().getStackTrace()).toString();
return handle(message.getPayload()) + "2" + Arrays.asList(new Throwable().getStackTrace());
}
@MyInboundChannelAdapter1
@@ -1490,6 +1497,7 @@ public class EnableIntegrationTests {
defaultHeaders = @GatewayHeader(name = "foo", value = "FOO"))
public @interface TestMessagingGateway {
@AliasFor(annotation = MessagingGateway.class, attribute = "defaultRequestChannel")
String defaultRequestChannel() default "";
}
@@ -1499,6 +1507,7 @@ public class EnableIntegrationTests {
@TestMessagingGateway(defaultRequestChannel = "gatewayChannel2")
public @interface TestMessagingGateway2 {
@AliasFor(annotation = TestMessagingGateway.class, attribute = "defaultRequestChannel")
String defaultRequestChannel() default "";
}
@@ -1513,16 +1522,22 @@ public class EnableIntegrationTests {
poller = @Poller(fixedDelay = "1000"))
public @interface MyServiceActivator {
@AliasFor(annotation = ServiceActivator.class, attribute = "inputChannel")
String inputChannel() default "";
@AliasFor(annotation = ServiceActivator.class, attribute = "outputChannel")
String outputChannel() default "";
@AliasFor(annotation = ServiceActivator.class, attribute = "adviceChain")
String[] adviceChain() default { };
@AliasFor(annotation = ServiceActivator.class, attribute = "autoStartup")
String autoStartup() default "";
@AliasFor(annotation = ServiceActivator.class, attribute = "phase")
String phase() default "";
@AliasFor(annotation = ServiceActivator.class, attribute = "poller")
Poller poller() default @Poller(ValueConstants.DEFAULT_NONE);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019 the original author or authors.
* Copyright 2019-2022 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.
@@ -19,7 +19,6 @@ package org.springframework.integration.dsl;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
@@ -27,6 +26,8 @@ import org.springframework.scheduling.support.PeriodicTrigger;
/**
* @author Gary Russell
* @author Artem Bilan
*
* @since 5.1.4
*
*/
@@ -35,24 +36,20 @@ public class PollersTests {
@Test
public void testDurations() {
PeriodicTrigger trigger = (PeriodicTrigger) Pollers.fixedDelay(Duration.ofMinutes(1L)).get().getTrigger();
assertThat(trigger.getPeriod()).isEqualTo(60_000L);
assertThat(trigger.getTimeUnit()).isEqualTo(TimeUnit.MILLISECONDS);
assertThat(trigger.getPeriodDuration()).isEqualTo(Duration.ofSeconds(60));
assertThat(trigger.isFixedRate()).isFalse();
trigger = (PeriodicTrigger) Pollers.fixedDelay(Duration.ofMinutes(1L), Duration.ofSeconds(10L))
.get().getTrigger();
assertThat(trigger.getPeriod()).isEqualTo(60_000L);
assertThat(trigger.getInitialDelay()).isEqualTo(10_000L);
assertThat(trigger.getTimeUnit()).isEqualTo(TimeUnit.MILLISECONDS);
assertThat(trigger.getPeriodDuration()).isEqualTo(Duration.ofSeconds(60));
assertThat(trigger.getInitialDelayDuration()).isEqualTo(Duration.ofSeconds(10));
assertThat(trigger.isFixedRate()).isFalse();
trigger = (PeriodicTrigger) Pollers.fixedRate(Duration.ofMinutes(1L)).get().getTrigger();
assertThat(trigger.getPeriod()).isEqualTo(60_000L);
assertThat(trigger.getTimeUnit()).isEqualTo(TimeUnit.MILLISECONDS);
assertThat(trigger.getPeriodDuration()).isEqualTo(Duration.ofSeconds(60));
assertThat(trigger.isFixedRate()).isTrue();
trigger = (PeriodicTrigger) Pollers.fixedRate(Duration.ofMinutes(1L), Duration.ofSeconds(10L))
.get().getTrigger();
assertThat(trigger.getPeriod()).isEqualTo(60_000L);
assertThat(trigger.getInitialDelay()).isEqualTo(10_000L);
assertThat(trigger.getTimeUnit()).isEqualTo(TimeUnit.MILLISECONDS);
assertThat(trigger.getPeriodDuration()).isEqualTo(Duration.ofSeconds(60));
assertThat(trigger.getInitialDelayDuration()).isEqualTo(Duration.ofSeconds(10));
assertThat(trigger.isFixedRate()).isTrue();
}

View File

@@ -18,9 +18,9 @@ package org.springframework.integration.dsl.flowservices;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Instant;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
@@ -165,15 +165,15 @@ public class FlowServiceTests {
@Component
public static class MyFlowAdapter extends IntegrationFlowAdapter {
private final AtomicReference<Date> executionDate = new AtomicReference<>(new Date());
private final AtomicReference<Instant> executionDate = new AtomicReference<>(Instant.now());
private Date nextExecutionTime(TriggerContext triggerContext) {
private Instant nextExecution(TriggerContext triggerContext) {
return this.executionDate.getAndSet(null);
}
@Override
protected IntegrationFlowDefinition<?> buildFlow() {
return fromSupplier(this::messageSource, e -> e.poller(p -> p.trigger(this::nextExecutionTime)))
return fromSupplier(this::messageSource, e -> e.poller(p -> p.trigger(this::nextExecution)))
.split(this, null, e -> e.applySequence(false))
.transform(this)
.aggregate(a -> a.processor(this, null))

View File

@@ -22,6 +22,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import java.lang.reflect.Method;
import java.time.Instant;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -539,7 +540,7 @@ public class ManualFlowTests {
private static class MyFlowAdapter extends IntegrationFlowAdapter {
private final AtomicReference<Date> nextExecutionTime = new AtomicReference<>(new Date());
private final AtomicReference<Instant> nextExecutionTime = new AtomicReference<>(Instant.now());
@Override
protected IntegrationFlowDefinition<?> buildFlow() {

View File

@@ -19,9 +19,9 @@ package org.springframework.integration.dsl.reactivestreams;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
@@ -109,11 +109,11 @@ public class ReactiveStreamsTests {
CountDownLatch latch = new CountDownLatch(6);
Disposable disposable =
Flux.from(this.publisher)
.map(m -> m.getPayload().toUpperCase())
.subscribe(p -> {
results.add(p);
latch.countDown();
});
.map(m -> m.getPayload().toUpperCase())
.subscribe(p -> {
results.add(p);
latch.countDown();
});
assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue();
String[] strings = results.toArray(new String[0]);
assertThat(strings).isEqualTo(new String[]{ "A", "B", "C", "D", "E", "F" });
@@ -251,7 +251,7 @@ public class ReactiveStreamsTests {
public Publisher<Message<String>> reactiveFlow() {
return IntegrationFlow
.from(() -> new GenericMessage<>("a,b,c,d,e,f"),
e -> e.poller(p -> p.trigger(ctx -> this.invoked.getAndSet(true) ? null : new Date()))
e -> e.poller(p -> p.trigger(ctx -> this.invoked.getAndSet(true) ? null : Instant.now()))
.id("reactiveStreamsMessageSource"))
.split(String.class, p -> p.split(","))
.log()

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -19,13 +19,14 @@ package org.springframework.integration.endpoint;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.expression.Expression;
@@ -40,39 +41,42 @@ import org.springframework.scheduling.support.PeriodicTrigger;
/**
* @author Mark Fisher
* @author Gary Russell
* @author Artem Bilan
*
* @since 2.0
*/
public class ExpressionEvaluatingMessageSourceIntegrationTests {
private static final AtomicInteger counter = new AtomicInteger();
@Test
public void test() throws Exception {
QueueChannel channel = new QueueChannel();
String payloadExpression = "'test-' + T(org.springframework.integration.endpoint.ExpressionEvaluatingMessageSourceIntegrationTests).next()";
String payloadExpression =
"'test-' + T(org.springframework.integration.endpoint.ExpressionEvaluatingMessageSourceIntegrationTests).next()";
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.afterPropertiesSet();
Map<String, Expression> headerExpressions = new HashMap<String, Expression>();
Map<String, Expression> headerExpressions = new HashMap<>();
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);
ExpressionEvaluatingMessageSource<Object> source =
new ExpressionEvaluatingMessageSource<>(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.setTrigger(new PeriodicTrigger(Duration.ofSeconds(60)));
adapter.setOutputChannel(channel);
adapter.setErrorHandler(t -> {
throw new IllegalStateException("unexpected exception in test", t);
});
adapter.start();
List<Message<?>> messages = new ArrayList<Message<?>>();
List<Message<?>> messages = new ArrayList<>();
for (int i = 0; i < 3; i++) {
messages.add(channel.receive(1000));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2020 the original author or authors.
* Copyright 2014-2022 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.
@@ -22,6 +22,7 @@ import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
@@ -335,8 +336,8 @@ public class PollerAdviceTests {
SourcePollingChannelAdapter adapter = new SourcePollingChannelAdapter();
final CountDownLatch latch = new CountDownLatch(5);
final LinkedList<Object> overridePresent = new LinkedList<>();
final CompoundTrigger compoundTrigger = new CompoundTrigger(new PeriodicTrigger(10));
Trigger override = spy(new PeriodicTrigger(5));
final CompoundTrigger compoundTrigger = new CompoundTrigger(new PeriodicTrigger(Duration.ofMillis(10)));
Trigger override = spy(new PeriodicTrigger(Duration.ofMillis(5)));
final CompoundTriggerAdvice advice = new CompoundTriggerAdvice(compoundTrigger, override);
adapter.setSource(() -> {
synchronized (overridePresent) {
@@ -359,7 +360,7 @@ public class PollerAdviceTests {
synchronized (overridePresent) {
assertThat(overridePresent.subList(0, 5)).containsExactly(null, override, null, override, null);
}
verify(override, atLeast(2)).nextExecutionTime(any(TriggerContext.class));
verify(override, atLeast(2)).nextExecution(any(TriggerContext.class));
}
private void configure(SourcePollingChannelAdapter adapter) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -16,6 +16,8 @@
package org.springframework.integration.endpoint;
import java.time.Duration;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.GenericMessage;
import org.springframework.scheduling.support.PeriodicTrigger;
@@ -24,11 +26,12 @@ import org.springframework.scheduling.support.PeriodicTrigger;
* @author Jonas Partner
* @author Gary Russell
* @author Andreas Baer
* @author Artem Bilan
*/
public class PollingEndpointStub extends AbstractPollingEndpoint {
public PollingEndpointStub() {
this.setTrigger(new PeriodicTrigger(500));
this.setTrigger(new PeriodicTrigger(Duration.ofMillis(500)));
}
@Override
@@ -38,7 +41,7 @@ public class PollingEndpointStub extends AbstractPollingEndpoint {
@Override
protected Message<?> receiveMessage() {
return new GenericMessage<String>("test message");
return new GenericMessage<>("test message");
}
@Override
@@ -50,4 +53,5 @@ public class PollingEndpointStub extends AbstractPollingEndpoint {
protected String getResourceKey() {
return "PollingEndpointStub";
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2021 the original author or authors.
* Copyright 2002-2022 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.
@@ -22,6 +22,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import java.time.Duration;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -85,7 +86,7 @@ public class PollingLifecycleTests {
});
PollingConsumer consumer = new PollingConsumer(channel, handler);
consumer.setTrigger(new PeriodicTrigger(0));
consumer.setTrigger(new PeriodicTrigger(Duration.ZERO));
consumer.setErrorHandler(errorHandler);
consumer.setTaskScheduler(taskScheduler);
consumer.setBeanFactory(mock(BeanFactory.class));
@@ -107,7 +108,7 @@ public class PollingLifecycleTests {
SourcePollingChannelAdapterFactoryBean adapterFactory = new SourcePollingChannelAdapterFactoryBean();
PollerMetadata pollerMetadata = new PollerMetadata();
pollerMetadata.setTrigger(new PeriodicTrigger(2000));
pollerMetadata.setTrigger(new PeriodicTrigger(Duration.ofSeconds(2)));
adapterFactory.setPollerMetadata(pollerMetadata);
//Has to be an explicit implementation - Mockito cannot mock/spy lambdas
@@ -140,7 +141,7 @@ public class PollingLifecycleTests {
SourcePollingChannelAdapterFactoryBean adapterFactory = new SourcePollingChannelAdapterFactoryBean();
PollerMetadata pollerMetadata = new PollerMetadata();
pollerMetadata.setMaxMessagesPerPoll(-1);
pollerMetadata.setTrigger(new PeriodicTrigger(2000));
pollerMetadata.setTrigger(new PeriodicTrigger(Duration.ofSeconds(2)));
adapterFactory.setPollerMetadata(pollerMetadata);
final Runnable caughtInterrupted = mock(Runnable.class);
final CountDownLatch interruptedLatch = new CountDownLatch(1);
@@ -180,7 +181,7 @@ public class PollingLifecycleTests {
adapterFactory.setOutputChannel(new NullChannel());
adapterFactory.setBeanFactory(mock(ConfigurableBeanFactory.class));
PollerMetadata pollerMetadata = new PollerMetadata();
pollerMetadata.setTrigger(new PeriodicTrigger(2000));
pollerMetadata.setTrigger(new PeriodicTrigger(Duration.ofSeconds(2)));
adapterFactory.setPollerMetadata(pollerMetadata);
final AtomicBoolean startInvoked = new AtomicBoolean();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 the original author or authors.
* Copyright 2016-2022 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.
@@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import java.io.ByteArrayOutputStream;
import java.time.Duration;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -334,7 +335,7 @@ public class IntegrationGraphServerTests {
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata defaultPoller() {
PollerMetadata poller = new PollerMetadata();
poller.setTrigger(new PeriodicTrigger(60000));
poller.setTrigger(new PeriodicTrigger(Duration.ofSeconds(60)));
MessagePublishingErrorHandler errorHandler = new MessagePublishingErrorHandler();
errorHandler.setDefaultErrorChannel(myErrors());
poller.setErrorHandler(errorHandler);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -17,13 +17,17 @@
package org.springframework.integration.message;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.mockito.Mockito.mock;
import java.time.Duration;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.integration.channel.QueueChannel;
@@ -47,7 +51,8 @@ public class MethodInvokingMessageHandlerTests {
public void validMethod() {
MethodInvokingMessageHandler handler = new MethodInvokingMessageHandler(new TestSink(), "validMethod");
handler.setBeanFactory(mock(BeanFactory.class));
handler.handleMessage(new GenericMessage<>("test"));
assertThatNoException()
.isThrownBy(() -> handler.handleMessage(new GenericMessage<>("test")));
}
@Test
@@ -55,23 +60,21 @@ public class MethodInvokingMessageHandlerTests {
new MethodInvokingMessageHandler(new TestSink(), "validMethodWithNoArgs");
}
@Test(expected = MessagingException.class)
@Test
public void methodWithReturnValue() {
Message<?> message = new GenericMessage<>("test");
try {
MethodInvokingMessageHandler handler = new MethodInvokingMessageHandler(new TestSink(),
"methodWithReturnValue");
handler.handleMessage(message);
}
catch (MessagingException e) {
assertThat(message).isEqualTo(e.getFailedMessage());
throw e;
}
MethodInvokingMessageHandler handler = new MethodInvokingMessageHandler(new TestSink(),
"methodWithReturnValue");
assertThatExceptionOfType(MessagingException.class)
.isThrownBy(() -> handler.handleMessage(message))
.satisfies(messagingException ->
assertThat(messagingException.getFailedMessage()).isEqualTo(message));
}
@Test(expected = IllegalStateException.class)
@Test
public void noMatchingMethodName() {
new MethodInvokingMessageHandler(new TestSink(), "noSuchMethod");
assertThatIllegalStateException()
.isThrownBy(() -> new MethodInvokingMessageHandler(new TestSink(), "noSuchMethod"));
}
@Test
@@ -87,7 +90,7 @@ public class MethodInvokingMessageHandlerTests {
MethodInvokingMessageHandler handler = new MethodInvokingMessageHandler(testBean, "foo");
handler.setBeanFactory(context);
PollingConsumer endpoint = new PollingConsumer(channel, handler);
endpoint.setTrigger(new PeriodicTrigger(10));
endpoint.setTrigger(new PeriodicTrigger(Duration.ofMillis(10)));
context.registerEndpoint("testEndpoint", endpoint);
context.refresh();
String result = queue.poll(2000, TimeUnit.MILLISECONDS);
@@ -97,13 +100,7 @@ public class MethodInvokingMessageHandlerTests {
}
private static class TestBean {
private final BlockingQueue<String> queue;
TestBean(BlockingQueue<String> queue) {
this.queue = queue;
}
private record TestBean(BlockingQueue<String> queue) {
@SuppressWarnings("unused")
public void foo(String s) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2019 the original author or authors.
* Copyright 2002-2022 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.
@@ -18,14 +18,17 @@ package org.springframework.integration.transformer;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.assertj.core.api.Assertions.fail;
import static org.mockito.Mockito.mock;
import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanInitializationException;
@@ -74,7 +77,6 @@ public class ContentEnricherTests {
*/
@Test
public void replyChannelReplyTimingOut() throws Exception {
final long requestTimeout = 500L;
final long replyTimeout = 100L;
@@ -93,7 +95,7 @@ public class ContentEnricherTests {
expressionFactoryBean.setSingleton(false);
expressionFactoryBean.afterPropertiesSet();
final Map<String, Expression> expressions = new HashMap<String, Expression>();
final Map<String, Expression> expressions = new HashMap<>();
expressions.put("name", new LiteralExpression("cartman"));
expressions.put("child.name", expressionFactoryBean.getObject());
@@ -103,20 +105,21 @@ public class ContentEnricherTests {
enricher.setBeanFactory(mock(BeanFactory.class));
enricher.afterPropertiesSet();
final AbstractReplyProducingMessageHandler handler = new AbstractReplyProducingMessageHandler() {
final AbstractReplyProducingMessageHandler handler =
new AbstractReplyProducingMessageHandler() {
@Override
protected Object handleRequestMessage(Message<?> requestMessage) {
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
fail(e.getMessage());
}
return new Target("child");
}
@Override
protected Object handleRequestMessage(Message<?> requestMessage) {
try {
Thread.sleep(5000);
}
catch (InterruptedException e) {
fail(e.getMessage());
}
return new Target("child");
}
};
};
handler.setBeanFactory(mock(BeanFactory.class));
handler.afterPropertiesSet();
@@ -124,7 +127,7 @@ public class ContentEnricherTests {
final PollingConsumer consumer = new PollingConsumer(requestChannel, handler);
final TestErrorHandler errorHandler = new TestErrorHandler();
consumer.setTrigger(new PeriodicTrigger(0));
consumer.setTrigger(new PeriodicTrigger(Duration.ZERO));
consumer.setErrorHandler(errorHandler);
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
@@ -139,27 +142,16 @@ public class ContentEnricherTests {
final Target target = new Target("replace me");
Message<?> requestMessage = MessageBuilder.withPayload(target).setReplyChannel(replyChannel).build();
try {
enricher.handleMessage(requestMessage);
}
catch (ReplyRequiredException e) {
assertThat(e.getMessage())
.isEqualTo("No reply produced by handler 'Enricher', and its 'requiresReply' property is set to " +
"true.");
return;
}
finally {
consumer.stop();
taskScheduler.destroy();
}
fail("ReplyRequiredException expected.");
assertThatExceptionOfType(ReplyRequiredException.class)
.isThrownBy(() -> enricher.handleMessage(requestMessage))
.withMessage("No reply produced by handler 'Enricher', and its 'requiresReply' property is set to true.");
consumer.stop();
taskScheduler.destroy();
}
@Test
public void requestChannelSendTimingOut() {
final String requestChannelName = "Request_Channel";
final long requestTimeout = 200L;
@@ -214,57 +206,36 @@ public class ContentEnricherTests {
@Test
public void setReplyChannelWithoutRequestChannel() {
QueueChannel replyChannel = new QueueChannel();
ContentEnricher enricher = new ContentEnricher();
enricher.setReplyChannel(replyChannel);
enricher.setBeanFactory(mock(BeanFactory.class));
try {
enricher.afterPropertiesSet();
}
catch (IllegalStateException e) {
assertThat(e.getMessage())
.isEqualTo("If the replyChannel is set, then the requestChannel must not be null");
return;
}
fail("Expected an exception.");
assertThatIllegalStateException()
.isThrownBy(enricher::afterPropertiesSet)
.withMessage("If the replyChannel is set, then the requestChannel must not be null");
}
@Test
public void setNullReplyTimeout() {
ContentEnricher enricher = new ContentEnricher();
enricher.setBeanFactory(mock(BeanFactory.class));
try {
enricher.setReplyTimeout(null);
}
catch (IllegalArgumentException e) {
assertThat(e.getMessage()).isEqualTo("replyTimeout must not be null");
return;
}
fail("Expected an exception.");
assertThatIllegalArgumentException()
.isThrownBy(() -> enricher.setReplyTimeout(null))
.withMessage("replyTimeout must not be null");
}
@Test
public void setNullRequestTimeout() {
ContentEnricher enricher = new ContentEnricher();
enricher.setBeanFactory(mock(BeanFactory.class));
try {
enricher.setRequestTimeout(null);
}
catch (IllegalArgumentException e) {
assertThat(e.getMessage()).isEqualTo("requestTimeout must not be null");
return;
}
fail("Expected an exception.");
assertThatIllegalArgumentException()
.isThrownBy(() -> enricher.setRequestTimeout(null))
.withMessage("requestTimeout must not be null");
}
@Test
@@ -272,7 +243,7 @@ public class ContentEnricherTests {
QueueChannel replyChannel = new QueueChannel();
ContentEnricher enricher = new ContentEnricher();
SpelExpressionParser parser = new SpelExpressionParser();
Map<String, Expression> propertyExpressions = new HashMap<String, Expression>();
Map<String, Expression> propertyExpressions = new HashMap<>();
propertyExpressions.put("name", parser.parseExpression("'just a static string'"));
enricher.setPropertyExpressions(propertyExpressions);
enricher.setBeanFactory(mock(BeanFactory.class));
@@ -286,21 +257,13 @@ public class ContentEnricherTests {
@Test
public void testContentEnricherWithNullRequestChannel() {
ContentEnricher enricher = new ContentEnricher();
enricher.setReplyChannel(new QueueChannel());
enricher.setBeanFactory(mock(BeanFactory.class));
try {
enricher.afterPropertiesSet();
}
catch (IllegalStateException e) {
assertThat(e.getMessage())
.isEqualTo("If the replyChannel is set, then the requestChannel must not be null");
return;
}
fail("Expected an IllegalArgumentException to be thrown.");
assertThatIllegalStateException()
.isThrownBy(enricher::afterPropertiesSet)
.withMessage("If the replyChannel is set, then the requestChannel must not be null");
}
@Test
@@ -318,7 +281,7 @@ public class ContentEnricherTests {
enricher.setRequestChannel(requestChannel);
SpelExpressionParser parser = new SpelExpressionParser();
Map<String, Expression> propertyExpressions = new HashMap<String, Expression>();
Map<String, Expression> propertyExpressions = new HashMap<>();
propertyExpressions.put("child.name", parser.parseExpression("payload.lastName + ', ' + payload.firstName"));
enricher.setPropertyExpressions(propertyExpressions);
enricher.setBeanFactory(mock(BeanFactory.class));
@@ -349,7 +312,7 @@ public class ContentEnricherTests {
enricher.setShouldClonePayload(true);
SpelExpressionParser parser = new SpelExpressionParser();
Map<String, Expression> propertyExpressions = new HashMap<String, Expression>();
Map<String, Expression> propertyExpressions = new HashMap<>();
propertyExpressions.put("name", parser.parseExpression("payload.lastName + ', ' + payload.firstName"));
enricher.setPropertyExpressions(propertyExpressions);
enricher.setBeanFactory(mock(BeanFactory.class));
@@ -380,7 +343,7 @@ public class ContentEnricherTests {
enricher.setShouldClonePayload(true);
SpelExpressionParser parser = new SpelExpressionParser();
Map<String, Expression> propertyExpressions = new HashMap<String, Expression>();
Map<String, Expression> propertyExpressions = new HashMap<>();
propertyExpressions.put("name", parser.parseExpression("payload.lastName + ', ' + payload.firstName"));
enricher.setPropertyExpressions(propertyExpressions);
enricher.setBeanFactory(mock(BeanFactory.class));
@@ -414,7 +377,7 @@ public class ContentEnricherTests {
enricher.setShouldClonePayload(true);
SpelExpressionParser parser = new SpelExpressionParser();
Map<String, Expression> propertyExpressions = new HashMap<String, Expression>();
Map<String, Expression> propertyExpressions = new HashMap<>();
propertyExpressions.put("name", parser.parseExpression("payload.lastName + ', ' + payload.firstName"));
enricher.setPropertyExpressions(propertyExpressions);
enricher.setBeanFactory(mock(BeanFactory.class));
@@ -425,16 +388,10 @@ public class ContentEnricherTests {
Message<?> requestMessage = MessageBuilder.withPayload(target).setReplyChannel(replyChannel).build();
try {
enricher.handleMessage(requestMessage);
}
catch (MessageHandlingException e) {
assertThat(e.getMessage()).contains("Failed to clone payload object");
return;
}
fail("Expected a MessageHandlingException to be thrown.");
assertThatExceptionOfType(MessageHandlingException.class)
.isThrownBy(() -> enricher.handleMessage(requestMessage))
.withMessageContaining("Failed to clone payload object");
}
@Test
@@ -451,7 +408,6 @@ public class ContentEnricherTests {
@Test
public void testLifeCycleMethodsWithRequestChannel() {
DirectChannel requestChannel = new DirectChannel();
requestChannel.subscribe(new AbstractReplyProducingMessageHandler() {
@@ -484,9 +440,8 @@ public class ContentEnricherTests {
* the "error-channel" which returns a alternative {@link Target}.
*/
@Test
public void testErrorChannel() throws Exception {
final DirectChannel requestChannel = new DirectChannel();
public void testErrorChannel() {
DirectChannel requestChannel = new DirectChannel();
requestChannel.subscribe(new AbstractReplyProducingMessageHandler() {
@Override
@@ -496,7 +451,7 @@ public class ContentEnricherTests {
});
final DirectChannel errorChannel = new DirectChannel();
DirectChannel errorChannel = new DirectChannel();
errorChannel.subscribe(new AbstractReplyProducingMessageHandler() {
@Override
@@ -513,7 +468,7 @@ public class ContentEnricherTests {
enricher.setErrorChannel(errorChannel);
SpelExpressionParser parser = new SpelExpressionParser();
Map<String, Expression> propertyExpressions = new HashMap<String, Expression>();
Map<String, Expression> propertyExpressions = new HashMap<>();
propertyExpressions.put("name", parser.parseExpression("payload.name + ' target'"));
enricher.setPropertyExpressions(propertyExpressions);
@@ -536,15 +491,10 @@ public class ContentEnricherTests {
Collections.singletonMap(MessageHeaders.TIMESTAMP, new StaticHeaderValueMessageProcessor<>("foo")));
contentEnricher.setBeanFactory(mock(BeanFactory.class));
try {
contentEnricher.afterPropertiesSet();
fail("BeanInitializationException expected");
}
catch (Exception e) {
assertThat(e).isInstanceOf(BeanInitializationException.class);
assertThat(e.getMessage())
.contains("ContentEnricher cannot override 'id' and 'timestamp' read-only headers.");
}
assertThatExceptionOfType(BeanInitializationException.class)
.isThrownBy(contentEnricher::afterPropertiesSet)
.withMessageContaining("ContentEnricher cannot override 'id' and 'timestamp' read-only headers.");
}
@Test
@@ -554,28 +504,14 @@ public class ContentEnricherTests {
Collections.singletonMap(MessageHeaders.ID, new StaticHeaderValueMessageProcessor<>("foo")));
contentEnricher.setBeanFactory(mock(BeanFactory.class));
try {
contentEnricher.afterPropertiesSet();
fail("BeanInitializationException expected");
}
catch (Exception e) {
assertThat(e).isInstanceOf(BeanInitializationException.class);
assertThat(e.getMessage())
.contains("ContentEnricher cannot override 'id' and 'timestamp' read-only headers.");
}
assertThatExceptionOfType(BeanInitializationException.class)
.isThrownBy(contentEnricher::afterPropertiesSet)
.withMessageContaining("ContentEnricher cannot override 'id' and 'timestamp' read-only headers.");
}
@SuppressWarnings("unused")
private static final class Source {
private final String firstName;
private final String lastName;
Source(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
private record Source(String firstName, String lastName) {
public String getFirstName() {
return firstName;