From cb73c7720cd09ad6ca364448cbc4ea81dc11e8ae Mon Sep 17 00:00:00 2001 From: Jakub Vrubel Date: Tue, 26 Aug 2025 10:56:07 +0200 Subject: [PATCH] Add more methods to FileSystem to support HttpStreamingExampleTest --- system-x/services/filesystem/pom.xml | 8 ++ .../resource/local/LocalFileSystem.java | 7 ++ .../openshift/OpenShiftFileSystem.java | 76 ++++++++++++++++++- .../tnb/filesystem/service/FileSystem.java | 2 + 4 files changed, 92 insertions(+), 1 deletion(-) diff --git a/system-x/services/filesystem/pom.xml b/system-x/services/filesystem/pom.xml index 32b7dfdc1..fb1f97d64 100644 --- a/system-x/services/filesystem/pom.xml +++ b/system-x/services/filesystem/pom.xml @@ -15,4 +15,12 @@ + + + org.awaitility + awaitility + ${awaitility.version} + + + diff --git a/system-x/services/filesystem/src/main/java/software/tnb/filesystem/resource/local/LocalFileSystem.java b/system-x/services/filesystem/src/main/java/software/tnb/filesystem/resource/local/LocalFileSystem.java index 587d30a79..eb95ac9c7 100644 --- a/system-x/services/filesystem/src/main/java/software/tnb/filesystem/resource/local/LocalFileSystem.java +++ b/system-x/services/filesystem/src/main/java/software/tnb/filesystem/resource/local/LocalFileSystem.java @@ -4,6 +4,8 @@ import software.tnb.common.utils.IOUtils; import software.tnb.filesystem.service.FileSystem; +import org.apache.commons.io.FileUtils; + import com.google.auto.service.AutoService; import java.io.IOException; @@ -28,6 +30,11 @@ public boolean createFile(Path directory, String filename, String content) throw return true; } + @Override + public void copyFile(Path srcPath, Path destPath) throws IOException { + FileUtils.copyFile(srcPath.toFile(), destPath.toFile()); + } + @Override public Path createTempDirectory() throws IOException { return Files.createTempDirectory("tnb-filesystem"); diff --git a/system-x/services/filesystem/src/main/java/software/tnb/filesystem/resource/openshift/OpenShiftFileSystem.java b/system-x/services/filesystem/src/main/java/software/tnb/filesystem/resource/openshift/OpenShiftFileSystem.java index f89a72fe1..3365627f8 100644 --- a/system-x/services/filesystem/src/main/java/software/tnb/filesystem/resource/openshift/OpenShiftFileSystem.java +++ b/system-x/services/filesystem/src/main/java/software/tnb/filesystem/resource/openshift/OpenShiftFileSystem.java @@ -4,13 +4,19 @@ import software.tnb.common.openshift.OpenshiftClient; import software.tnb.filesystem.service.FileSystem; +import org.junit.jupiter.api.Assertions; + +import org.awaitility.Awaitility; + import com.google.auto.service.AutoService; import java.io.BufferedReader; import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.nio.file.Files; import java.nio.file.Path; import java.util.concurrent.TimeUnit; import java.util.function.Predicate; @@ -18,6 +24,7 @@ import cz.xtf.core.openshift.OpenShiftWaiters; import io.fabric8.kubernetes.api.model.Pod; +import io.fabric8.kubernetes.client.dsl.ExecWatch; @AutoService(FileSystem.class) public class OpenShiftFileSystem extends FileSystem implements OpenshiftDeployable { @@ -41,12 +48,53 @@ public String getFileContent(Path path) { .inNamespace(OpenshiftClient.get().getNamespace()) .withName(podName) .inContainer(integrationContainer).file(path.toString()).read()) { - return new BufferedReader(new InputStreamReader(is)).lines().collect(Collectors.joining("\n")); + return new BufferedReader(new InputStreamReader(is)).lines().collect(Collectors.joining(System.lineSeparator())); } catch (IOException e) { throw new RuntimeException(e); } } + /** + * Transfers a file between the local filesystem and a pod. + * Works both ways, meaning it will download a file from a pod if the source is remote + * and upload a file to a pod if the source is local. + * One path must be remote and one path must be local. + * + * @param srcPath the source file. + * @param destPath the destination. This file should not exist. + */ + @Override + public void copyFile(Path srcPath, Path destPath) throws IOException { + final String podLabelKey = "app.kubernetes.io/name"; + podIsReady(podLabelKey, podLabelValue); + final String podName = getPodName(podLabelKey, podLabelValue); + final Pod pod = OpenshiftClient.get().getPod(podName); + final String integrationContainer = OpenshiftClient.get().getIntegrationContainer(pod); + + if (srcPath.toFile().exists() && !fileExistsOnOCP(destPath.toString())) { + OpenshiftClient.get().pods() + .inNamespace(OpenshiftClient.get().getNamespace()) + .withName(podName) + .inContainer(integrationContainer).file(destPath.toString()) + .upload(srcPath); + waitForFile(destPath.toString()); + } else if (!destPath.toFile().exists() && fileExistsOnOCP(srcPath.toString())) { + try (InputStream is = OpenshiftClient.get().pods() + .inNamespace(OpenshiftClient.get().getNamespace()) + .withName(podName) + .inContainer(integrationContainer).file(srcPath.toString()).read()) { + Files.write( + destPath, + new BufferedReader(new InputStreamReader(is)).lines().collect(Collectors.joining(System.lineSeparator())).getBytes() + ); + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + throw new IOException("Both or neither file exist on OCP or locally"); + } + } + @Override public boolean createFile(Path directory, String filename, String content) throws IOException { final String podLabelKey = "app.kubernetes.io/name"; @@ -94,4 +142,30 @@ private void podIsReady(String key, String value) { throw new RuntimeException(e); } } + + private boolean fileExistsOnOCP(String path) throws IOException { + final String podLabelKey = "app.kubernetes.io/name"; + final String podName = getPodName(podLabelKey, podLabelValue); + final Pod pod = OpenshiftClient.get().getPod(podName); + final String integrationContainer = OpenshiftClient.get().getIntegrationContainer(pod); + + try (ByteArrayOutputStream out = new ByteArrayOutputStream(); + ExecWatch watch = OpenshiftClient.get().pods() + .inNamespace(OpenshiftClient.get().getNamespace()) + .withName(podName) + .inContainer(integrationContainer) + .writingOutput(out) + .exec("test", "-f", path)) { + return watch.exitCode().join().equals(0); + } + } + + private void waitForFile(String path) { + Awaitility.await("Wait for " + path + "to be uploaded") + .atMost(30, TimeUnit.MINUTES) + .pollInterval(20, TimeUnit.SECONDS) + .untilAsserted(() -> { + Assertions.assertTrue(fileExistsOnOCP(path)); + }); + } } diff --git a/system-x/services/filesystem/src/main/java/software/tnb/filesystem/service/FileSystem.java b/system-x/services/filesystem/src/main/java/software/tnb/filesystem/service/FileSystem.java index d9615ae8f..1c039347e 100644 --- a/system-x/services/filesystem/src/main/java/software/tnb/filesystem/service/FileSystem.java +++ b/system-x/services/filesystem/src/main/java/software/tnb/filesystem/service/FileSystem.java @@ -15,6 +15,8 @@ public abstract class FileSystem extends Service