GH-3315: Fix (S)FTP Stream with Fair Rotation

Resolves https://github.com/spring-projects/spring-integration/issues/3315

`maxFetchSize` ignored with filters supporting single file filtering (default).
This breaks "fair" rotation with the `RotatingServerAdvice`.

Honor `maxFetchSize`, even with filters that support single file filtering.

**cherry-pick to 5.3.x, 5.2.x**
This commit is contained in:
Gary Russell
2020-07-01 11:18:00 -04:00
committed by Artem Bilan
parent 0ddbfa6e6d
commit f3d61ec44a
3 changed files with 131 additions and 15 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2019 the original author or authors.
* Copyright 2016-2020 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 java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import org.springframework.context.Lifecycle;
import org.springframework.expression.Expression;
@@ -65,6 +66,8 @@ public abstract class AbstractRemoteFileStreamingMessageSource<F>
private final AtomicBoolean running = new AtomicBoolean();
private final AtomicInteger fetched = new AtomicInteger();
private boolean fileInfoJson = true;
/**
@@ -183,12 +186,11 @@ public abstract class AbstractRemoteFileStreamingMessageSource<F>
@Override
protected Object doReceive(int maxFetchSize) {
return doReceive();
}
@Override
protected Object doReceive() {
Assert.state(this.running.get(), () -> getComponentName() + " is not running");
if (maxFetchSize > 0 && this.fetched.get() >= maxFetchSize) {
this.toBeReceived.clear();
this.fetched.set(0);
}
AbstractFileInfo<F> file = poll();
while (file != null) {
if (this.filter != null && this.filter.supportsSingleFileFiltering()
@@ -205,6 +207,9 @@ public abstract class AbstractRemoteFileStreamingMessageSource<F>
try {
String remotePath = remotePath(file);
Session<?> session = this.remoteFileTemplate.getSession();
if (maxFetchSize > 0) {
this.fetched.incrementAndGet();
}
try {
return getMessageBuilderFactory()
.withPayload(session.readRaw(remotePath))

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 the original author or authors.
* Copyright 2015-2020 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.file.remote;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -70,7 +71,7 @@ public class RemoteFileStreamingMessageSourceTests {
testRemoteFileStreamingMessageSource.setBeanFactory(mock(BeanFactory.class));
testRemoteFileStreamingMessageSource.start();
assertThat(testRemoteFileStreamingMessageSource.doReceive()).isNull();
assertThat(testRemoteFileStreamingMessageSource.doReceive(-1)).isNull();
}
@Test
@@ -94,7 +95,7 @@ public class RemoteFileStreamingMessageSourceTests {
testRemoteFileStreamingMessageSource.start();
assertThatExceptionOfType(UncheckedIOException.class)
.isThrownBy(testRemoteFileStreamingMessageSource::doReceive);
.isThrownBy(() -> testRemoteFileStreamingMessageSource.doReceive(anyInt()));
assertThat(cachingSessionFactory.getSession()).isNotNull();
}