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