This is an automated email from the ASF dual-hosted git repository.
JingsongLi pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/paimon.git
The following commit(s) were added to refs/heads/master by this push:
new 53fd1c9fb0 [fs] Delegate listFilesIterative through RESTTokenFileIO
(#9071)
53fd1c9fb0 is described below
commit 53fd1c9fb04c120c0d8eccd9eb0d44cee43b1c12
Author: tonymtu <[email protected]>
AuthorDate: Thu Aug 6 22:13:26 2026 +0800
[fs] Delegate listFilesIterative through RESTTokenFileIO (#9071)
---
.../org/apache/paimon/rest/RESTTokenFileIO.java | 8 ++++
.../apache/paimon/rest/RESTTokenFileIOTest.java | 52 ++++++++++++++++++++++
2 files changed, 60 insertions(+)
diff --git
a/paimon-common/src/main/java/org/apache/paimon/rest/RESTTokenFileIO.java
b/paimon-common/src/main/java/org/apache/paimon/rest/RESTTokenFileIO.java
index 73b5541d3c..fb210dda43 100644
--- a/paimon-common/src/main/java/org/apache/paimon/rest/RESTTokenFileIO.java
+++ b/paimon-common/src/main/java/org/apache/paimon/rest/RESTTokenFileIO.java
@@ -25,6 +25,7 @@ import org.apache.paimon.fs.FileIO;
import org.apache.paimon.fs.FileStatus;
import org.apache.paimon.fs.Path;
import org.apache.paimon.fs.PositionOutputStream;
+import org.apache.paimon.fs.RemoteIterator;
import org.apache.paimon.fs.SeekableInputStream;
import org.apache.paimon.fs.TwoPhaseOutputStream;
import org.apache.paimon.options.ConfigOption;
@@ -132,6 +133,13 @@ public class RESTTokenFileIO implements FileIO {
return fileIO().listStatus(path);
}
+ @Override
+ public RemoteIterator<FileStatus> listFilesIterative(Path path, boolean
recursive)
+ throws IOException {
+ // the interface default would hide the inner FileIO's iterative
listing override
+ return fileIO().listFilesIterative(path, recursive);
+ }
+
@Override
public boolean exists(Path path) throws IOException {
return fileIO().exists(path);
diff --git
a/paimon-common/src/test/java/org/apache/paimon/rest/RESTTokenFileIOTest.java
b/paimon-common/src/test/java/org/apache/paimon/rest/RESTTokenFileIOTest.java
index 42e1746700..9bab3e1a89 100644
---
a/paimon-common/src/test/java/org/apache/paimon/rest/RESTTokenFileIOTest.java
+++
b/paimon-common/src/test/java/org/apache/paimon/rest/RESTTokenFileIOTest.java
@@ -23,7 +23,9 @@ import org.apache.paimon.catalog.Identifier;
import org.apache.paimon.data.BlobDescriptor;
import org.apache.paimon.fs.FileIO;
import org.apache.paimon.fs.FileIOLoader;
+import org.apache.paimon.fs.FileStatus;
import org.apache.paimon.fs.Path;
+import org.apache.paimon.fs.RemoteIterator;
import org.apache.paimon.options.Options;
import org.apache.paimon.rest.responses.GetTableTokenResponse;
@@ -112,4 +114,54 @@ class RESTTokenFileIOTest {
// the interface default would have written a temp file and renamed it
instead
verify(delegate, never()).rename(any(), any());
}
+
+ @Test
+ void testListFilesIterativeReachesInnerOverride() throws IOException {
+ Path tableRoot = new Path("oss://bucket/table");
+ FileIO delegate = mock(FileIO.class);
+ FileIOLoader loader = mock(FileIOLoader.class);
+ when(loader.load(any())).thenReturn(delegate);
+ when(loader.getScheme()).thenReturn("oss");
+ RESTApi api = mock(RESTApi.class);
+ Identifier identifier = Identifier.create("db", "table");
+ // a unique token, so the static token-keyed FileIO cache cannot serve
another test's
+ // delegate
+ when(api.loadTableToken(identifier))
+ .thenReturn(
+ new GetTableTokenResponse(
+ Collections.singletonMap("token",
UUID.randomUUID().toString()),
+ Long.MAX_VALUE));
+ RESTTokenFileIO fileIO =
+ new RESTTokenFileIO(
+ CatalogContext.create(new Options(), loader, null),
+ api,
+ identifier,
+ tableRoot);
+ FileStatus status = mock(FileStatus.class);
+ RemoteIterator<FileStatus> iterator =
+ new RemoteIterator<FileStatus>() {
+ private boolean emitted;
+
+ @Override
+ public boolean hasNext() {
+ return !emitted;
+ }
+
+ @Override
+ public FileStatus next() {
+ emitted = true;
+ return status;
+ }
+ };
+ when(delegate.listFilesIterative(tableRoot,
false)).thenReturn(iterator);
+
+ RemoteIterator<FileStatus> actual =
fileIO.listFilesIterative(tableRoot, false);
+
+ assertThat(actual.hasNext()).isTrue();
+ assertThat(actual.next()).isSameAs(status);
+ assertThat(actual.hasNext()).isFalse();
+ verify(delegate).listFilesIterative(tableRoot, false);
+ // the interface default would construct its own iterator backed by
listStatus
+ verify(delegate, never()).listStatus(any());
+ }
}