Add Reactive mode for AbstractPollingEndpoint (#2429)
* Add Reactive mode for AbstractPollingEndpoint * When `SourcePollingChannelAdapter.outputChannel` is a `ReactiveStreamsSubscribableChannel`, use `Flux.generate()` for polling * Refactor `AbstractPollingEndpoint` to remove redundant `Poller` class in favor of lambda * Extract `pollForMessage()` method to handle TX states instead of `Poller` class previously * * Rebase and fix conflicts * Polishing for GatewayProxyFactoryBeanTests
This commit is contained in:
committed by
Gary Russell
parent
76b1d1df06
commit
27353ed393
@@ -16,7 +16,9 @@
|
||||
|
||||
package org.springframework.integration.endpoint;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -24,6 +26,7 @@ import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.reactivestreams.Subscription;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
@@ -43,6 +46,7 @@ import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
import org.springframework.scheduling.Trigger;
|
||||
import org.springframework.scheduling.support.PeriodicTrigger;
|
||||
import org.springframework.scheduling.support.SimpleTriggerContext;
|
||||
import org.springframework.transaction.interceptor.TransactionInterceptor;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
@@ -51,6 +55,10 @@ import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ErrorHandler;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.core.scheduler.Schedulers;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
@@ -66,23 +74,27 @@ public abstract class AbstractPollingEndpoint extends AbstractEndpoint implement
|
||||
|
||||
private boolean syncExecutor = true;
|
||||
|
||||
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
|
||||
|
||||
private Trigger trigger = new PeriodicTrigger(10);
|
||||
|
||||
private long maxMessagesPerPoll = -1;
|
||||
|
||||
private ErrorHandler errorHandler;
|
||||
|
||||
private boolean errorHandlerIsDefault;
|
||||
|
||||
private Trigger trigger = new PeriodicTrigger(10);
|
||||
|
||||
private List<Advice> adviceChain;
|
||||
|
||||
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
|
||||
|
||||
private long maxMessagesPerPoll = -1;
|
||||
|
||||
private TransactionSynchronizationFactory transactionSynchronizationFactory;
|
||||
|
||||
private volatile ScheduledFuture<?> runningTask;
|
||||
private volatile Callable<Message<?>> pollingTask;
|
||||
|
||||
private volatile Runnable poller;
|
||||
private volatile Flux<Message<?>> pollingFlux;
|
||||
|
||||
private volatile Subscription subscription;
|
||||
|
||||
private volatile ScheduledFuture<?> runningTask;
|
||||
|
||||
private volatile boolean initialized;
|
||||
|
||||
@@ -167,6 +179,14 @@ public abstract class AbstractPollingEndpoint extends AbstractEndpoint implement
|
||||
protected void applyReceiveOnlyAdviceChain(Collection<Advice> chain) {
|
||||
}
|
||||
|
||||
protected boolean isReactive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected Flux<Message<?>> getPollingFlux() {
|
||||
return this.pollingFlux;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onInit() {
|
||||
synchronized (this.initializationMonitor) {
|
||||
@@ -200,8 +220,30 @@ public abstract class AbstractPollingEndpoint extends AbstractEndpoint implement
|
||||
}
|
||||
}
|
||||
|
||||
// LifecycleSupport implementation
|
||||
|
||||
@Override // guarded by super#lifecycleLock
|
||||
protected void doStart() {
|
||||
if (!this.initialized) {
|
||||
onInit();
|
||||
}
|
||||
|
||||
this.pollingTask = createPollingTask();
|
||||
|
||||
if (isReactive()) {
|
||||
this.pollingFlux = createFluxGenerator();
|
||||
}
|
||||
else {
|
||||
Assert.state(getTaskScheduler() != null, "unable to start polling, no taskScheduler available");
|
||||
|
||||
this.runningTask =
|
||||
getTaskScheduler()
|
||||
.schedule(createPoller(), this.trigger);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Runnable createPoller() throws Exception {
|
||||
private Callable<Message<?>> createPollingTask() {
|
||||
List<Advice> receiveOnlyAdviceChain = null;
|
||||
if (!CollectionUtils.isEmpty(this.adviceChain)) {
|
||||
receiveOnlyAdviceChain = this.adviceChain.stream()
|
||||
@@ -209,7 +251,7 @@ public abstract class AbstractPollingEndpoint extends AbstractEndpoint implement
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
Callable<Boolean> pollingTask = this::doPoll;
|
||||
Callable<Message<?>> pollingTask = this::doPoll;
|
||||
|
||||
List<Advice> adviceChain = this.adviceChain;
|
||||
if (!CollectionUtils.isEmpty(adviceChain)) {
|
||||
@@ -219,65 +261,122 @@ public abstract class AbstractPollingEndpoint extends AbstractEndpoint implement
|
||||
.filter(advice -> !isReceiveOnlyAdvice(advice))
|
||||
.forEach(proxyFactory::addAdvice);
|
||||
}
|
||||
pollingTask = (Callable<Boolean>) proxyFactory.getProxy(this.beanClassLoader);
|
||||
pollingTask = (Callable<Message<?>>) proxyFactory.getProxy(this.beanClassLoader);
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(receiveOnlyAdviceChain)) {
|
||||
applyReceiveOnlyAdviceChain(receiveOnlyAdviceChain);
|
||||
}
|
||||
return new Poller(pollingTask);
|
||||
|
||||
return pollingTask;
|
||||
}
|
||||
|
||||
// LifecycleSupport implementation
|
||||
private Runnable createPoller() {
|
||||
return () ->
|
||||
this.taskExecutor.execute(() -> {
|
||||
int count = 0;
|
||||
while (this.initialized && (this.maxMessagesPerPoll <= 0 || count < this.maxMessagesPerPoll)) {
|
||||
if (pollForMessage() == null) {
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override // guarded by super#lifecycleLock
|
||||
protected void doStart() {
|
||||
if (!this.initialized) {
|
||||
this.onInit();
|
||||
}
|
||||
Assert.state(this.getTaskScheduler() != null,
|
||||
"unable to start polling, no taskScheduler available");
|
||||
private Flux<Message<?>> createFluxGenerator() {
|
||||
SimpleTriggerContext triggerContext = new SimpleTriggerContext();
|
||||
|
||||
return Flux
|
||||
.<Duration>generate(sink -> {
|
||||
Date date = this.trigger.nextExecutionTime(triggerContext);
|
||||
if (date != null) {
|
||||
triggerContext.update(date, null, null);
|
||||
long millis = date.getTime() - System.currentTimeMillis();
|
||||
sink.next(Duration.ofMillis(millis));
|
||||
}
|
||||
else {
|
||||
sink.complete();
|
||||
}
|
||||
})
|
||||
.concatMap(duration ->
|
||||
Mono.delay(duration)
|
||||
.doOnNext(l ->
|
||||
triggerContext.update(triggerContext.lastScheduledExecutionTime(),
|
||||
new Date(), null))
|
||||
.flatMapMany(l ->
|
||||
Flux
|
||||
.<Message<?>>generate(fluxSink -> {
|
||||
Message<?> message = pollForMessage();
|
||||
if (message != null) {
|
||||
fluxSink.next(message);
|
||||
}
|
||||
else {
|
||||
fluxSink.complete();
|
||||
}
|
||||
})
|
||||
.take(this.maxMessagesPerPoll)
|
||||
.subscribeOn(Schedulers.fromExecutor(this.taskExecutor))
|
||||
.doOnComplete(() ->
|
||||
triggerContext.update(triggerContext.lastScheduledExecutionTime(),
|
||||
triggerContext.lastActualExecutionTime(),
|
||||
new Date())
|
||||
)), 1)
|
||||
.repeat(this::isRunning)
|
||||
.doOnSubscribe(subscription -> this.subscription = subscription);
|
||||
}
|
||||
|
||||
private Message<?> pollForMessage() {
|
||||
try {
|
||||
this.poller = createPoller();
|
||||
return this.pollingTask.call();
|
||||
}
|
||||
catch (Exception e) {
|
||||
this.initialized = false;
|
||||
throw new MessagingException("Failed to create Poller", e);
|
||||
if (e instanceof MessagingException) {
|
||||
throw (MessagingException) e;
|
||||
}
|
||||
else {
|
||||
Message<?> failedMessage = null;
|
||||
if (this.transactionSynchronizationFactory != null) {
|
||||
Object resource = TransactionSynchronizationManager.getResource(getResourceToBind());
|
||||
if (resource instanceof IntegrationResourceHolder) {
|
||||
failedMessage = ((IntegrationResourceHolder) resource).getMessage();
|
||||
}
|
||||
}
|
||||
throw new MessagingException(failedMessage, e);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (this.transactionSynchronizationFactory != null) {
|
||||
Object resource = getResourceToBind();
|
||||
if (TransactionSynchronizationManager.hasResource(resource)) {
|
||||
TransactionSynchronizationManager.unbindResource(resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.runningTask = this.getTaskScheduler().schedule(this.poller, this.trigger);
|
||||
}
|
||||
|
||||
@Override // guarded by super#lifecycleLock
|
||||
protected void doStop() {
|
||||
if (this.runningTask != null) {
|
||||
this.runningTask.cancel(true);
|
||||
}
|
||||
this.runningTask = null;
|
||||
}
|
||||
|
||||
private boolean doPoll() {
|
||||
IntegrationResourceHolder holder = this.bindResourceHolderIfNecessary(
|
||||
this.getResourceKey(), this.getResourceToBind());
|
||||
Message<?> message = null;
|
||||
private Message<?> doPoll() {
|
||||
IntegrationResourceHolder holder = bindResourceHolderIfNecessary(getResourceKey(), getResourceToBind());
|
||||
Message<?> message;
|
||||
try {
|
||||
message = this.receiveMessage();
|
||||
message = receiveMessage();
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (Thread.interrupted()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Poll interrupted - during stop()? : " + e.getMessage());
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
throw (RuntimeException) e;
|
||||
}
|
||||
}
|
||||
boolean result;
|
||||
|
||||
if (message == null) {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
this.logger.debug("Received no Message during the poll, returning 'false'");
|
||||
}
|
||||
result = false;
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
if (this.logger.isDebugEnabled()) {
|
||||
@@ -286,20 +385,35 @@ public abstract class AbstractPollingEndpoint extends AbstractEndpoint implement
|
||||
if (holder != null) {
|
||||
holder.setMessage(message);
|
||||
}
|
||||
try {
|
||||
this.handleMessage(message);
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (e instanceof MessagingException) {
|
||||
throw new MessagingExceptionWrapper(message, (MessagingException) e);
|
||||
|
||||
if (!isReactive()) {
|
||||
try {
|
||||
handleMessage(message);
|
||||
}
|
||||
else {
|
||||
throw new MessagingException(message, e);
|
||||
catch (Exception e) {
|
||||
if (e instanceof MessagingException) {
|
||||
throw new MessagingExceptionWrapper(message, (MessagingException) e);
|
||||
}
|
||||
else {
|
||||
throw new MessagingException(message, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override // guarded by super#lifecycleLock
|
||||
protected void doStop() {
|
||||
if (this.runningTask != null) {
|
||||
this.runningTask.cancel(true);
|
||||
}
|
||||
this.runningTask = null;
|
||||
|
||||
if (this.subscription != null) {
|
||||
this.subscription.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -369,57 +483,4 @@ public abstract class AbstractPollingEndpoint extends AbstractEndpoint implement
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default Poller implementation
|
||||
*/
|
||||
private final class Poller implements Runnable {
|
||||
|
||||
private final Callable<Boolean> pollingTask;
|
||||
|
||||
Poller(Callable<Boolean> pollingTask) {
|
||||
this.pollingTask = pollingTask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
AbstractPollingEndpoint.this.taskExecutor.execute(() -> {
|
||||
int count = 0;
|
||||
while (AbstractPollingEndpoint.this.initialized
|
||||
&& (AbstractPollingEndpoint.this.maxMessagesPerPoll <= 0
|
||||
|| count < AbstractPollingEndpoint.this.maxMessagesPerPoll)) {
|
||||
try {
|
||||
if (!Poller.this.pollingTask.call()) {
|
||||
break;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
catch (Exception e) {
|
||||
if (e instanceof MessagingException) {
|
||||
throw (MessagingException) e;
|
||||
}
|
||||
else {
|
||||
Message<?> failedMessage = null;
|
||||
if (AbstractPollingEndpoint.this.transactionSynchronizationFactory != null) {
|
||||
Object resource = TransactionSynchronizationManager.getResource(getResourceToBind());
|
||||
if (resource instanceof IntegrationResourceHolder) {
|
||||
failedMessage = ((IntegrationResourceHolder) resource).getMessage();
|
||||
}
|
||||
}
|
||||
throw new MessagingException(failedMessage, e);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
if (AbstractPollingEndpoint.this.transactionSynchronizationFactory != null) {
|
||||
Object resource = getResourceToBind();
|
||||
if (TransactionSynchronizationManager.hasResource(resource)) {
|
||||
TransactionSynchronizationManager.unbindResource(resource);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,8 +21,11 @@ import java.util.Deque;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.reactivestreams.Subscriber;
|
||||
|
||||
import org.springframework.context.Lifecycle;
|
||||
import org.springframework.integration.channel.ExecutorChannelInterceptorAware;
|
||||
import org.springframework.integration.channel.ReactiveStreamsSubscribableChannel;
|
||||
import org.springframework.integration.core.MessageProducer;
|
||||
import org.springframework.integration.router.MessageRouter;
|
||||
import org.springframework.integration.support.utils.IntegrationUtils;
|
||||
@@ -97,6 +100,12 @@ public class PollingConsumer extends AbstractPollingEndpoint implements Integrat
|
||||
return this.handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReactive() {
|
||||
return getOutputChannel() instanceof ReactiveStreamsSubscribableChannel &&
|
||||
this.handler instanceof Subscriber;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStart() {
|
||||
if (this.handler instanceof Lifecycle) {
|
||||
|
||||
@@ -31,6 +31,7 @@ import org.springframework.integration.StaticMessageHeaderAccessor;
|
||||
import org.springframework.integration.acks.AckUtils;
|
||||
import org.springframework.integration.acks.AcknowledgmentCallback;
|
||||
import org.springframework.integration.aop.MessageSourceMutator;
|
||||
import org.springframework.integration.channel.ReactiveStreamsSubscribableChannel;
|
||||
import org.springframework.integration.context.ExpressionCapable;
|
||||
import org.springframework.integration.core.MessageSource;
|
||||
import org.springframework.integration.core.MessagingTemplate;
|
||||
@@ -169,6 +170,11 @@ public class SourcePollingChannelAdapter extends AbstractPollingEndpoint
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isReactive() {
|
||||
return getOutputChannel() instanceof ReactiveStreamsSubscribableChannel;
|
||||
}
|
||||
|
||||
private NameMatchMethodPointcutAdvisor adviceToReceiveAdvisor(Advice advice) {
|
||||
NameMatchMethodPointcutAdvisor sourceAdvisor = new NameMatchMethodPointcutAdvisor(advice);
|
||||
sourceAdvisor.addMethodName("receive");
|
||||
@@ -181,6 +187,10 @@ public class SourcePollingChannelAdapter extends AbstractPollingEndpoint
|
||||
((Lifecycle) this.source).start();
|
||||
}
|
||||
super.doStart();
|
||||
|
||||
if (isReactive()) {
|
||||
((ReactiveStreamsSubscribableChannel) this.outputChannel).subscribeTo(getPollingFlux());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -197,7 +207,7 @@ public class SourcePollingChannelAdapter extends AbstractPollingEndpoint
|
||||
protected void onInit() {
|
||||
Assert.notNull(this.source, "source must not be null");
|
||||
Assert.state((this.outputChannelName == null && this.outputChannel != null)
|
||||
|| (this.outputChannelName != null && this.outputChannel == null),
|
||||
|| (this.outputChannelName != null && this.outputChannel == null),
|
||||
"One and only one of 'outputChannelName' or 'outputChannel' is required.");
|
||||
super.onInit();
|
||||
if (this.getBeanFactory() != null) {
|
||||
|
||||
@@ -523,7 +523,7 @@ public class EnableIntegrationTests {
|
||||
assertTrue(TestUtils.getPropertyValue(consumer, "autoStartup", Boolean.class));
|
||||
assertEquals(23, TestUtils.getPropertyValue(consumer, "phase"));
|
||||
assertSame(context.getBean("annInput1"), TestUtils.getPropertyValue(consumer, "inputChannel"));
|
||||
assertEquals("annOutput", TestUtils.getPropertyValue(consumer, "handler.outputChannelName"));
|
||||
assertEquals("annOutput", TestUtils.getPropertyValue(consumer, "handler.outputChannel.beanName"));
|
||||
assertSame(context.getBean("annAdvice1"), TestUtils.getPropertyValue(consumer,
|
||||
"handler.adviceChain", List.class).get(0));
|
||||
assertEquals(2000L, TestUtils.getPropertyValue(consumer, "trigger.period"));
|
||||
|
||||
@@ -89,8 +89,7 @@ public class PollingTransactionTests {
|
||||
List<Advice> adviceChain = TestUtils.getPropertyValue(advisedPoller, "adviceChain", List.class);
|
||||
assertEquals(4, adviceChain.size());
|
||||
advisedPoller.start();
|
||||
Runnable poller = TestUtils.getPropertyValue(advisedPoller, "poller", Runnable.class);
|
||||
Callable<?> pollingTask = TestUtils.getPropertyValue(poller, "pollingTask", Callable.class);
|
||||
Callable<?> pollingTask = TestUtils.getPropertyValue(advisedPoller, "pollingTask", Callable.class);
|
||||
assertTrue("Poller is not Advised", pollingTask instanceof Advised);
|
||||
Advisor[] advisors = ((Advised) pollingTask).getAdvisors();
|
||||
assertEquals(4, advisors.length);
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.integration.endpoint;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.integration.annotation.InboundChannelAdapter;
|
||||
import org.springframework.integration.annotation.Poller;
|
||||
import org.springframework.integration.channel.FluxMessageChannel;
|
||||
import org.springframework.integration.config.EnableIntegration;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
*
|
||||
* @since 5.1
|
||||
*/
|
||||
@SpringJUnitConfig
|
||||
@DirtiesContext
|
||||
public class ReactiveInboundChannelAdapterTests {
|
||||
|
||||
@Autowired
|
||||
private FluxMessageChannel fluxMessageChannel;
|
||||
|
||||
@Test
|
||||
public void testReactiveInboundChannelAdapter() {
|
||||
Flux<Integer> testFlux =
|
||||
Flux.from(this.fluxMessageChannel)
|
||||
.map(Message::getPayload)
|
||||
.cast(Integer.class);
|
||||
|
||||
StepVerifier.create(testFlux)
|
||||
.expectNext(2, 4, 6, 8, 10, 12, 14, 16)
|
||||
.thenCancel()
|
||||
.verify();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableIntegration
|
||||
public static class Config {
|
||||
|
||||
@Bean
|
||||
public AtomicInteger counter() {
|
||||
return new AtomicInteger();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TaskExecutor taskExecutor() {
|
||||
return new SimpleAsyncTaskExecutor();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@InboundChannelAdapter(value = "fluxChannel",
|
||||
poller = @Poller(fixedDelay = "100", maxMessagesPerPoll = "3", taskExecutor = "taskExecutor"))
|
||||
public Supplier<Integer> counterMessageSupplier() {
|
||||
return () -> {
|
||||
int i = counter().incrementAndGet();
|
||||
return i % 2 == 0 ? i : null;
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageChannel fluxChannel() {
|
||||
return new FluxMessageChannel();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
@@ -46,7 +47,6 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.common.LiteralExpression;
|
||||
import org.springframework.integration.annotation.Gateway;
|
||||
import org.springframework.integration.annotation.GatewayHeader;
|
||||
@@ -68,6 +68,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Gunnar Hillert
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
public class GatewayProxyFactoryBeanTests {
|
||||
|
||||
@@ -91,13 +92,16 @@ public class GatewayProxyFactoryBeanTests {
|
||||
QueueChannel requestChannel = new QueueChannel();
|
||||
startResponder(requestChannel);
|
||||
GenericConversionService cs = new DefaultConversionService();
|
||||
Converter<String, byte[]> stringToByteConverter = new Converter<String, byte[]>() {
|
||||
Converter<String, byte[]> stringToByteConverter =
|
||||
// Has to an interface (not lambda) to honor Mockito
|
||||
new Converter<String, byte[]>() {
|
||||
|
||||
@Override
|
||||
public byte[] convert(String source) {
|
||||
return source.getBytes();
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public byte[] convert(String source) {
|
||||
return source.getBytes();
|
||||
}
|
||||
|
||||
};
|
||||
stringToByteConverter = spy(stringToByteConverter);
|
||||
cs.addConverter(stringToByteConverter);
|
||||
GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean();
|
||||
@@ -134,7 +138,7 @@ public class GatewayProxyFactoryBeanTests {
|
||||
@Test
|
||||
public void testSolicitResponse() throws Exception {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
replyChannel.send(new GenericMessage<String>("foo"));
|
||||
replyChannel.send(new GenericMessage<>("foo"));
|
||||
GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean();
|
||||
proxyFactory.setServiceInterface(TestService.class);
|
||||
proxyFactory.setDefaultRequestChannel(new DirectChannel());
|
||||
@@ -169,7 +173,7 @@ public class GatewayProxyFactoryBeanTests {
|
||||
final QueueChannel requestChannel = new QueueChannel();
|
||||
new Thread(() -> {
|
||||
Message<?> input = requestChannel.receive();
|
||||
GenericMessage<String> reply = new GenericMessage<String>(input.getPayload() + "456");
|
||||
GenericMessage<String> reply = new GenericMessage<>(input.getPayload() + "456");
|
||||
((MessageChannel) input.getHeaders().getReplyChannel()).send(reply);
|
||||
}).start();
|
||||
GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean();
|
||||
@@ -229,7 +233,7 @@ public class GatewayProxyFactoryBeanTests {
|
||||
latch.countDown();
|
||||
});
|
||||
}
|
||||
latch.await(30, TimeUnit.SECONDS);
|
||||
assertTrue(latch.await(30, TimeUnit.SECONDS));
|
||||
for (int i = 0; i < numRequests; i++) {
|
||||
assertEquals("test-" + i + "!!!", results[i]);
|
||||
}
|
||||
@@ -251,7 +255,7 @@ public class GatewayProxyFactoryBeanTests {
|
||||
proxyFactory.setBeanFactory(mock(BeanFactory.class));
|
||||
proxyFactory.afterPropertiesSet();
|
||||
TestService service = (TestService) proxyFactory.getObject();
|
||||
String result = service.requestReplyWithMessageParameter(new GenericMessage<String>("foo"));
|
||||
String result = service.requestReplyWithMessageParameter(new GenericMessage<>("foo"));
|
||||
assertEquals("foobar", result);
|
||||
}
|
||||
|
||||
@@ -275,7 +279,7 @@ public class GatewayProxyFactoryBeanTests {
|
||||
final QueueChannel requestChannel = new QueueChannel();
|
||||
new Thread(() -> {
|
||||
Message<?> input = requestChannel.receive();
|
||||
GenericMessage<String> reply = new GenericMessage<String>(input.getPayload() + "bar");
|
||||
GenericMessage<String> reply = new GenericMessage<>(input.getPayload() + "bar");
|
||||
((MessageChannel) input.getHeaders().getReplyChannel()).send(reply);
|
||||
}).start();
|
||||
GatewayProxyFactoryBean proxyFactory = new GatewayProxyFactoryBean();
|
||||
@@ -345,7 +349,7 @@ public class GatewayProxyFactoryBeanTests {
|
||||
private static void startResponder(final PollableChannel requestChannel) {
|
||||
new Thread(() -> {
|
||||
Message<?> input = requestChannel.receive();
|
||||
GenericMessage<String> reply = new GenericMessage<String>(input.getPayload() + "bar");
|
||||
GenericMessage<String> reply = new GenericMessage<>(input.getPayload() + "bar");
|
||||
((MessageChannel) input.getHeaders().getReplyChannel()).send(reply);
|
||||
}).start();
|
||||
}
|
||||
@@ -359,7 +363,7 @@ public class GatewayProxyFactoryBeanTests {
|
||||
gpfb.setDefaultRequestChannel(drc);
|
||||
gpfb.setDefaultReplyTimeout(0L);
|
||||
GatewayMethodMetadata meta = new GatewayMethodMetadata();
|
||||
meta.setHeaderExpressions(Collections.<String, Expression>singletonMap("foo", new LiteralExpression("bar")));
|
||||
meta.setHeaderExpressions(Collections.singletonMap("foo", new LiteralExpression("bar")));
|
||||
gpfb.setGlobalMethodMetadata(meta);
|
||||
gpfb.afterPropertiesSet();
|
||||
((TestEchoService) gpfb.getObject()).echo("foo");
|
||||
@@ -385,7 +389,8 @@ public class GatewayProxyFactoryBeanTests {
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e, instanceOf(BeanInitializationException.class));
|
||||
assertThat(e.getMessage(), containsString("Messaging Gateway cannot override 'id' and 'timestamp' read-only headers"));
|
||||
assertThat(e
|
||||
.getMessage(), containsString("Messaging Gateway cannot override 'id' and 'timestamp' read-only headers"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,7 +406,8 @@ public class GatewayProxyFactoryBeanTests {
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e, instanceOf(BeanInitializationException.class));
|
||||
assertThat(e.getMessage(), containsString("Messaging Gateway cannot override 'id' and 'timestamp' read-only headers"));
|
||||
assertThat(e
|
||||
.getMessage(), containsString("Messaging Gateway cannot override 'id' and 'timestamp' read-only headers"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,7 +423,8 @@ public class GatewayProxyFactoryBeanTests {
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertThat(e, instanceOf(BeanInitializationException.class));
|
||||
assertThat(e.getMessage(), containsString("Messaging Gateway cannot override 'id' and 'timestamp' read-only headers"));
|
||||
assertThat(e
|
||||
.getMessage(), containsString("Messaging Gateway cannot override 'id' and 'timestamp' read-only headers"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,6 +487,7 @@ public class GatewayProxyFactoryBeanTests {
|
||||
interface TestEchoService {
|
||||
|
||||
Message<?> echo(String s);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -487,17 +495,20 @@ public class GatewayProxyFactoryBeanTests {
|
||||
|
||||
@Gateway(headers = @GatewayHeader(name = MessageHeaders.ID, value = "id"))
|
||||
Message<?> echo(String s);
|
||||
|
||||
}
|
||||
|
||||
interface HeadersParamService {
|
||||
|
||||
Message<?> echo(String s, @Header(MessageHeaders.TIMESTAMP) String foo);
|
||||
|
||||
}
|
||||
|
||||
|
||||
interface TestExceptionThrowingInterface {
|
||||
|
||||
String throwCheckedException(String s) throws TestException;
|
||||
|
||||
}
|
||||
|
||||
interface InheritSuper {
|
||||
@@ -530,6 +541,7 @@ public class GatewayProxyFactoryBeanTests {
|
||||
public TestClient(TestService service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ public class AdvisedMessageHandlerTests {
|
||||
|
||||
@Test
|
||||
public void circuitBreakerExceptionText() {
|
||||
GenericMessage<String> message = new GenericMessage<String>("foo");
|
||||
GenericMessage<String> message = new GenericMessage<>("foo");
|
||||
try {
|
||||
input.send(message);
|
||||
fail("expected exception");
|
||||
@@ -353,7 +353,7 @@ public class AdvisedMessageHandlerTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void circuitBreakerTests() throws Exception {
|
||||
public void circuitBreakerTests() {
|
||||
final AtomicBoolean doFail = new AtomicBoolean();
|
||||
AbstractReplyProducingMessageHandler handler = new AbstractReplyProducingMessageHandler() {
|
||||
|
||||
@@ -384,7 +384,7 @@ public class AdvisedMessageHandlerTests {
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
doFail.set(true);
|
||||
Message<String> message = new GenericMessage<String>("Hello, world!");
|
||||
Message<String> message = new GenericMessage<>("Hello, world!");
|
||||
try {
|
||||
handler.handleMessage(message);
|
||||
fail("Expected failure");
|
||||
@@ -483,7 +483,7 @@ public class AdvisedMessageHandlerTests {
|
||||
handler.setBeanFactory(mock(BeanFactory.class));
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
Message<String> message = new GenericMessage<String>("Hello, world!");
|
||||
Message<String> message = new GenericMessage<>("Hello, world!");
|
||||
handler.handleMessage(message);
|
||||
assertTrue(counter.get() == -1);
|
||||
Message<?> reply = replies.receive(10000);
|
||||
@@ -511,13 +511,13 @@ public class AdvisedMessageHandlerTests {
|
||||
|
||||
advice.setRetryStateGenerator(message -> new DefaultRetryState(message.getHeaders().getId()));
|
||||
|
||||
List<Advice> adviceChain = new ArrayList<Advice>();
|
||||
List<Advice> adviceChain = new ArrayList<>();
|
||||
adviceChain.add(advice);
|
||||
handler.setAdviceChain(adviceChain);
|
||||
handler.setBeanFactory(mock(BeanFactory.class));
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
Message<String> message = new GenericMessage<String>("Hello, world!");
|
||||
Message<String> message = new GenericMessage<>("Hello, world!");
|
||||
for (int i = 0; i < 3; i++) {
|
||||
try {
|
||||
handler.handleMessage(message);
|
||||
@@ -583,13 +583,13 @@ public class AdvisedMessageHandlerTests {
|
||||
AbstractReplyProducingMessageHandler handler, QueueChannel replies, RequestHandlerRetryAdvice advice) {
|
||||
advice.setRecoveryCallback(context -> "baz");
|
||||
|
||||
List<Advice> adviceChain = new ArrayList<Advice>();
|
||||
List<Advice> adviceChain = new ArrayList<>();
|
||||
adviceChain.add(advice);
|
||||
handler.setAdviceChain(adviceChain);
|
||||
handler.setBeanFactory(mock(BeanFactory.class));
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
Message<String> message = new GenericMessage<String>("Hello, world!");
|
||||
Message<String> message = new GenericMessage<>("Hello, world!");
|
||||
for (int i = 0; i < 4; i++) {
|
||||
try {
|
||||
handler.handleMessage(message);
|
||||
@@ -617,13 +617,13 @@ public class AdvisedMessageHandlerTests {
|
||||
ErrorMessageSendingRecoverer recoverer = new ErrorMessageSendingRecoverer(errors);
|
||||
advice.setRecoveryCallback(recoverer);
|
||||
|
||||
List<Advice> adviceChain = new ArrayList<Advice>();
|
||||
List<Advice> adviceChain = new ArrayList<>();
|
||||
adviceChain.add(advice);
|
||||
handler.setAdviceChain(adviceChain);
|
||||
handler.setBeanFactory(mock(BeanFactory.class));
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
Message<String> message = new GenericMessage<String>("Hello, world!");
|
||||
Message<String> message = new GenericMessage<>("Hello, world!");
|
||||
handler.handleMessage(message);
|
||||
Message<?> error = errors.receive(10000);
|
||||
assertNotNull(error);
|
||||
@@ -658,13 +658,13 @@ public class AdvisedMessageHandlerTests {
|
||||
advice.setBeanFactory(mock(BeanFactory.class));
|
||||
advice.afterPropertiesSet();
|
||||
|
||||
List<Advice> adviceChain = new ArrayList<Advice>();
|
||||
List<Advice> adviceChain = new ArrayList<>();
|
||||
adviceChain.add(advice);
|
||||
handler.setAdviceChain(adviceChain);
|
||||
handler.setBeanFactory(mock(BeanFactory.class));
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
Message<String> message = new GenericMessage<String>("Hello, world!");
|
||||
Message<String> message = new GenericMessage<>("Hello, world!");
|
||||
handler.handleMessage(message);
|
||||
Message<?> error = errors.receive(10000);
|
||||
assertNotNull(error);
|
||||
@@ -685,7 +685,7 @@ public class AdvisedMessageHandlerTests {
|
||||
}
|
||||
};
|
||||
|
||||
List<Advice> adviceChain = new ArrayList<Advice>();
|
||||
List<Advice> adviceChain = new ArrayList<>();
|
||||
|
||||
adviceChain.add(new RequestHandlerRetryAdvice());
|
||||
adviceChain.add((MethodInterceptor) invocation -> {
|
||||
@@ -698,7 +698,7 @@ public class AdvisedMessageHandlerTests {
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
try {
|
||||
handler.handleMessage(new GenericMessage<String>("test"));
|
||||
handler.handleMessage(new GenericMessage<>("test"));
|
||||
}
|
||||
catch (Exception e) {
|
||||
Throwable cause = e.getCause();
|
||||
@@ -724,7 +724,7 @@ public class AdvisedMessageHandlerTests {
|
||||
QueueChannel replies = new QueueChannel();
|
||||
handler.setOutputChannel(replies);
|
||||
|
||||
List<Advice> adviceChain = new ArrayList<Advice>();
|
||||
List<Advice> adviceChain = new ArrayList<>();
|
||||
|
||||
ExpressionEvaluatingRequestHandlerAdvice expressionAdvice = new ExpressionEvaluatingRequestHandlerAdvice();
|
||||
expressionAdvice.setBeanFactory(mock(BeanFactory.class));
|
||||
@@ -750,7 +750,7 @@ public class AdvisedMessageHandlerTests {
|
||||
handler.setBeanFactory(mock(BeanFactory.class));
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
handler.handleMessage(new GenericMessage<String>("test"));
|
||||
handler.handleMessage(new GenericMessage<>("test"));
|
||||
Message<?> receive = replies.receive(10000);
|
||||
assertNotNull(receive);
|
||||
assertEquals("intentional: 3", receive.getPayload());
|
||||
@@ -772,7 +772,7 @@ public class AdvisedMessageHandlerTests {
|
||||
|
||||
QueueChannel errors = new QueueChannel();
|
||||
|
||||
List<Advice> adviceChain = new ArrayList<Advice>();
|
||||
List<Advice> adviceChain = new ArrayList<>();
|
||||
|
||||
ExpressionEvaluatingRequestHandlerAdvice expressionAdvice = new ExpressionEvaluatingRequestHandlerAdvice();
|
||||
expressionAdvice.setBeanFactory(mock(BeanFactory.class));
|
||||
@@ -790,7 +790,7 @@ public class AdvisedMessageHandlerTests {
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
try {
|
||||
handler.handleMessage(new GenericMessage<String>("test"));
|
||||
handler.handleMessage(new GenericMessage<>("test"));
|
||||
}
|
||||
catch (Exception e) {
|
||||
assertEquals("intentional: 3", e.getCause().getMessage());
|
||||
@@ -833,7 +833,7 @@ public class AdvisedMessageHandlerTests {
|
||||
Method method = AbstractReplyProducingMessageHandler.class.getDeclaredMethod("handleRequestMessage",
|
||||
Message.class);
|
||||
when(methodInvocation.getMethod()).thenReturn(method);
|
||||
when(methodInvocation.getArguments()).thenReturn(new Object[] { new GenericMessage<String>("foo") });
|
||||
when(methodInvocation.getArguments()).thenReturn(new Object[] { new GenericMessage<>("foo") });
|
||||
try {
|
||||
doAnswer(invocation -> {
|
||||
throw theThrowable;
|
||||
@@ -851,7 +851,7 @@ public class AdvisedMessageHandlerTests {
|
||||
* ThrowableHolderException from the output message.
|
||||
*/
|
||||
@Test
|
||||
public void throwableProperlyPropagatedAndReported() throws Exception {
|
||||
public void throwableProperlyPropagatedAndReported() {
|
||||
QueueChannel errors = new QueueChannel();
|
||||
|
||||
ExpressionEvaluatingRequestHandlerAdvice expressionAdvice = new ExpressionEvaluatingRequestHandlerAdvice();
|
||||
@@ -866,7 +866,7 @@ public class AdvisedMessageHandlerTests {
|
||||
Bar fooHandler = (Bar) proxyFactory.getProxy();
|
||||
|
||||
try {
|
||||
fooHandler.handleRequestMessage(new GenericMessage<String>("foo"));
|
||||
fooHandler.handleRequestMessage(new GenericMessage<>("foo"));
|
||||
fail("Expected throwable");
|
||||
}
|
||||
catch (Throwable t) {
|
||||
@@ -898,12 +898,12 @@ public class AdvisedMessageHandlerTests {
|
||||
consumer.setTaskScheduler(mock(TaskScheduler.class));
|
||||
consumer.start();
|
||||
|
||||
Callable<?> pollingTask = TestUtils.getPropertyValue(consumer, "poller.pollingTask", Callable.class);
|
||||
Callable<?> pollingTask = TestUtils.getPropertyValue(consumer, "pollingTask", Callable.class);
|
||||
assertTrue(AopUtils.isAopProxy(pollingTask));
|
||||
Log logger = TestUtils.getPropertyValue(advice, "logger", Log.class);
|
||||
logger = spy(logger);
|
||||
when(logger.isWarnEnabled()).thenReturn(Boolean.TRUE);
|
||||
final AtomicReference<String> logMessage = new AtomicReference<String>();
|
||||
final AtomicReference<String> logMessage = new AtomicReference<>();
|
||||
doAnswer(invocation -> {
|
||||
logMessage.set(invocation.getArgument(0));
|
||||
return null;
|
||||
@@ -925,7 +925,7 @@ public class AdvisedMessageHandlerTests {
|
||||
MessageFilter filter = new MessageFilter(message -> false);
|
||||
QueueChannel discardChannel = new QueueChannel();
|
||||
filter.setDiscardChannel(discardChannel);
|
||||
filter.handleMessage(new GenericMessage<String>("foo"));
|
||||
filter.handleMessage(new GenericMessage<>("foo"));
|
||||
assertNotNull(discardChannel.receive(0));
|
||||
}
|
||||
|
||||
@@ -948,7 +948,7 @@ public class AdvisedMessageHandlerTests {
|
||||
filter.setAdviceChain(adviceChain);
|
||||
filter.setBeanFactory(mock(BeanFactory.class));
|
||||
filter.afterPropertiesSet();
|
||||
filter.handleMessage(new GenericMessage<String>("foo"));
|
||||
filter.handleMessage(new GenericMessage<>("foo"));
|
||||
assertNotNull(discardedWithinAdvice.get());
|
||||
assertNull(discardChannel.receive(0));
|
||||
}
|
||||
@@ -958,7 +958,7 @@ public class AdvisedMessageHandlerTests {
|
||||
MessageFilter filter = new MessageFilter(message -> false);
|
||||
final QueueChannel discardChannel = new QueueChannel();
|
||||
filter.setDiscardChannel(discardChannel);
|
||||
List<Advice> adviceChain = new ArrayList<Advice>();
|
||||
List<Advice> adviceChain = new ArrayList<>();
|
||||
final AtomicReference<Message<?>> discardedWithinAdvice = new AtomicReference<Message<?>>();
|
||||
final AtomicBoolean adviceCalled = new AtomicBoolean();
|
||||
adviceChain.add(new AbstractRequestHandlerAdvice() {
|
||||
@@ -975,7 +975,7 @@ public class AdvisedMessageHandlerTests {
|
||||
filter.setDiscardWithinAdvice(false);
|
||||
filter.setBeanFactory(mock(BeanFactory.class));
|
||||
filter.afterPropertiesSet();
|
||||
filter.handleMessage(new GenericMessage<String>("foo"));
|
||||
filter.handleMessage(new GenericMessage<>("foo"));
|
||||
assertTrue(adviceCalled.get());
|
||||
assertNull(discardedWithinAdvice.get());
|
||||
assertNotNull(discardChannel.receive(0));
|
||||
@@ -1022,13 +1022,13 @@ public class AdvisedMessageHandlerTests {
|
||||
|
||||
advice.setRetryTemplate(retryTemplate);
|
||||
|
||||
List<Advice> adviceChain = new ArrayList<Advice>();
|
||||
List<Advice> adviceChain = new ArrayList<>();
|
||||
adviceChain.add(advice);
|
||||
handler.setAdviceChain(adviceChain);
|
||||
handler.setBeanFactory(mock(BeanFactory.class));
|
||||
handler.afterPropertiesSet();
|
||||
|
||||
Message<String> message = new GenericMessage<String>("Hello, world!");
|
||||
Message<String> message = new GenericMessage<>("Hello, world!");
|
||||
try {
|
||||
handler.handleMessage(message);
|
||||
fail("MessagingException expected.");
|
||||
@@ -1042,7 +1042,7 @@ public class AdvisedMessageHandlerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enhancedRecoverer() throws Exception {
|
||||
public void enhancedRecoverer() {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
ErrorMessageSendingRecoverer recoverer = new ErrorMessageSendingRecoverer(channel);
|
||||
recoverer.publish(new GenericMessage<>("foo"), new GenericMessage<>("bar"), new RuntimeException("baz"));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 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.
|
||||
@@ -36,6 +36,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Gunnar Hillert
|
||||
* @author Gary Russell
|
||||
* @author Artem Bilan
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@@ -49,16 +50,16 @@ public class FtpsInboundChannelAdapterParserTests {
|
||||
private MessageChannel ftpChannel;
|
||||
|
||||
@Test
|
||||
public void testFtpsInboundChannelAdapterComplete() throws Exception {
|
||||
public void testFtpsInboundChannelAdapterComplete() {
|
||||
assertEquals("ftpInbound", ftpInbound.getComponentName());
|
||||
assertEquals("ftp:inbound-channel-adapter", ftpInbound.getComponentType());
|
||||
assertNotNull(TestUtils.getPropertyValue(ftpInbound, "poller"));
|
||||
assertNotNull(TestUtils.getPropertyValue(ftpInbound, "pollingTask"));
|
||||
assertEquals(this.ftpChannel, TestUtils.getPropertyValue(ftpInbound, "outputChannel"));
|
||||
FtpInboundFileSynchronizingMessageSource inbound =
|
||||
(FtpInboundFileSynchronizingMessageSource) TestUtils.getPropertyValue(ftpInbound, "source");
|
||||
(FtpInboundFileSynchronizingMessageSource) TestUtils.getPropertyValue(ftpInbound, "source");
|
||||
|
||||
FtpInboundFileSynchronizer fisync =
|
||||
(FtpInboundFileSynchronizer) TestUtils.getPropertyValue(inbound, "synchronizer");
|
||||
(FtpInboundFileSynchronizer) TestUtils.getPropertyValue(inbound, "synchronizer");
|
||||
assertNotNull(TestUtils.getPropertyValue(fisync, "filter"));
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user