From a86bb5e1f7b420099672f49d84993981150a587c Mon Sep 17 00:00:00 2001 From: Nils Gerstner Date: Sun, 22 Jan 2023 09:37:18 +0100 Subject: [PATCH] Add simple file-watch route --- pom.xml | 20 +++++++ .../java/se/gerstner/notes/observer/Main.java | 13 ----- .../notes/observer/adapter/FileWatcher.java | 53 +++++++++++++++++++ .../observer/application/FileRouter.java | 33 ++++++++++++ .../notes/observer/beans/ByteConvert.java | 32 +++++++++++ .../notes/observer/data/UnparsedNote.java | 19 +++++++ src/main/resources/application.properties | 1 + .../notes/observer/beans/ByteConvertTest.java | 25 +++++++++ 8 files changed, 183 insertions(+), 13 deletions(-) delete mode 100644 src/main/java/se/gerstner/notes/observer/Main.java create mode 100644 src/main/java/se/gerstner/notes/observer/adapter/FileWatcher.java create mode 100644 src/main/java/se/gerstner/notes/observer/application/FileRouter.java create mode 100644 src/main/java/se/gerstner/notes/observer/beans/ByteConvert.java create mode 100644 src/main/java/se/gerstner/notes/observer/data/UnparsedNote.java create mode 100644 src/test/java/se/gerstner/notes/observer/beans/ByteConvertTest.java diff --git a/pom.xml b/pom.xml index 4505302..07ab27e 100644 --- a/pom.xml +++ b/pom.xml @@ -35,6 +35,18 @@ + + org.apache.camel.quarkus + camel-quarkus-log + + + org.apache.camel.quarkus + camel-quarkus-direct + + + org.apache.camel.quarkus + camel-quarkus-timer + org.apache.camel.quarkus camel-quarkus-arangodb @@ -56,6 +68,14 @@ quarkus-junit5 test + + org.apache.camel.quarkus + camel-quarkus-jackson + + + io.quarkus + quarkus-smallrye-health + diff --git a/src/main/java/se/gerstner/notes/observer/Main.java b/src/main/java/se/gerstner/notes/observer/Main.java deleted file mode 100644 index e2c3042..0000000 --- a/src/main/java/se/gerstner/notes/observer/Main.java +++ /dev/null @@ -1,13 +0,0 @@ -package se.gerstner.notes.observer; - -import io.quarkus.runtime.annotations.QuarkusMain; -import io.quarkus.runtime.Quarkus; - -@QuarkusMain -public class Main { - - public static void main(String ... args) { - System.out.println("Running QuarkusMain method"); - Quarkus.run(args); - } -} diff --git a/src/main/java/se/gerstner/notes/observer/adapter/FileWatcher.java b/src/main/java/se/gerstner/notes/observer/adapter/FileWatcher.java new file mode 100644 index 0000000..659d049 --- /dev/null +++ b/src/main/java/se/gerstner/notes/observer/adapter/FileWatcher.java @@ -0,0 +1,53 @@ +package se.gerstner.notes.observer.adapter; + +import java.io.File; +//import io.quarkus.logging.Log; +import java.nio.file.Files; +import java.util.Base64; + +import org.apache.camel.Message; +import org.apache.camel.builder.RouteBuilder; + +import se.gerstner.notes.observer.beans.ByteConvert; +import se.gerstner.notes.observer.data.UnparsedNote; + +public class FileWatcher extends RouteBuilder { + + @Override + public void configure() throws Exception { + from("file-watch://{{input.filewatch.folder.path}}?exchangePattern=InOut") + .routeId("FileWatcher") + + .process(exchange -> { + Message message = exchange.getMessage(); + String content = ""; + if (exchange.getMessage().getBody() instanceof File file) { + if (file.isDirectory()) { + message.setHeader("Type", "directory"); + } else if (file.isFile()) { + message.setHeader("Type", "file"); + content = Base64.getEncoder().encodeToString(Files.readAllBytes(file.toPath())); + } else { + message.setHeader("Type", ""); + } + String filetype = Files.probeContentType(file.toPath()); + message.setHeader("ContentType", filetype); + + UnparsedNote note = new UnparsedNote(message.getHeader("CamelFileAbsolutePath", String.class), + message.getHeader("CamelFileEventType", String.class), + message.getHeader("CamelFileLastModified", Long.class), + message.getHeader("CamelFileNameOnly", String.class), + message.getHeader("CamelFileParent", String.class), + message.getHeader("CamelFileRelativePath", String.class), + message.getHeader("CamelMessageTimestamp", Long.class), filetype, content); + + message.setBody(note); + } +// Log.info("Is File: " +file.isFile()); +// Log.info("Is Folder: " +file.isDirectory()); +// Log.info("Is Exists: " +file.exists()); + }).to("log:FileWatcher?showAll=true").log("FileWatcher ContentType: ${header.ContentType}") + .to("direct:FileRouter"); + } + +} diff --git a/src/main/java/se/gerstner/notes/observer/application/FileRouter.java b/src/main/java/se/gerstner/notes/observer/application/FileRouter.java new file mode 100644 index 0000000..056ea81 --- /dev/null +++ b/src/main/java/se/gerstner/notes/observer/application/FileRouter.java @@ -0,0 +1,33 @@ +package se.gerstner.notes.observer.application; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.model.dataformat.JsonLibrary; + +import io.quarkus.logging.Log; +import se.gerstner.notes.observer.data.UnparsedNote; + +public class FileRouter extends RouteBuilder { + + @Override + public void configure() throws Exception { + from("direct:FileRouter") + .routeId("FileRouter") + .process(exchange -> { + Log.info("FileRouter", + "€€€€€€€€€€€€4 This is the body: " + + exchange.getMessage().getBody(UnparsedNote.class).getContentAsDecodedString(), + null); + }) + .marshal().json(JsonLibrary.Jackson) + .convertBodyTo(String.class) + + // TODO add JMS endpoint + .choice() + .when(simple("${header.CamelFileEventType} == 'CREATE' || ${header.CamelFileEventType} == 'MODIFY'")) + .log("FileRouter.Create") + .when(simple("${header.CamelFileEventType} == 'DELETE'")) + .log("FileRouter.Delete") + .end(); + + } +} diff --git a/src/main/java/se/gerstner/notes/observer/beans/ByteConvert.java b/src/main/java/se/gerstner/notes/observer/beans/ByteConvert.java new file mode 100644 index 0000000..b6eacee --- /dev/null +++ b/src/main/java/se/gerstner/notes/observer/beans/ByteConvert.java @@ -0,0 +1,32 @@ +package se.gerstner.notes.observer.beans; + +import java.util.HexFormat; + +public class ByteConvert { + + public static String toHex(byte[] byteArray) { + return HexFormat.of().formatHex(byteArray); + // StringBuilder hex = new StringBuilder(); + // for (byte i : byteArray) + // hex.append(String.format("%02X", i)); + // return hex.toString(); + + // byte[] encoded = Base64.getEncoder().encode("Hello".getBytes()); + // println(new String(encoded)); // Outputs "SGVsbG8=" + // + // byte[] decoded = Base64.getDecoder().decode(encoded); + // println(new String(decoded)) // Outputs "Hello" + // Or if you just want the strings: + // + // String encoded = Base64.getEncoder().encodeToString("Hello".getBytes()); + // println(encoded); // Outputs "SGVsbG8=" + // + // String decoded = new String(Base64.getDecoder().decode(encoded.getBytes())); + // println(decoded) // Outputs "Hello" + } + + public static byte[] fromHex(String hexString) { + return HexFormat.of().parseHex(hexString); + } + +} diff --git a/src/main/java/se/gerstner/notes/observer/data/UnparsedNote.java b/src/main/java/se/gerstner/notes/observer/data/UnparsedNote.java new file mode 100644 index 0000000..e982dca --- /dev/null +++ b/src/main/java/se/gerstner/notes/observer/data/UnparsedNote.java @@ -0,0 +1,19 @@ +package se.gerstner.notes.observer.data; + +import java.util.Base64; + +public record UnparsedNote( + String absolutePath, // CamelFileAbsolutePath + String eventType, // CamelFileEventType + long lastModified, // CamelFileLastModified + String fileName, // CamelFileNameOnly + String parent, // CamelFileParent + String relativePath, // CamelFileRelativePath + long Timestamp, // CamelMessageTimestamp + String contentType, // ContentType + String content // Base64 String +) { + public String getContentAsDecodedString() { + return new String(Base64.getDecoder().decode(content)); + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e69de29..93b50e3 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -0,0 +1 @@ +input.filewatch.folder.path=./IN diff --git a/src/test/java/se/gerstner/notes/observer/beans/ByteConvertTest.java b/src/test/java/se/gerstner/notes/observer/beans/ByteConvertTest.java new file mode 100644 index 0000000..91f857e --- /dev/null +++ b/src/test/java/se/gerstner/notes/observer/beans/ByteConvertTest.java @@ -0,0 +1,25 @@ +package se.gerstner.notes.observer.beans; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +import io.netty.channel.VoidChannelPromise; + +class ByteConvertTest { + final String testString = "This is a test String"; + final byte[] testByteA = testString.getBytes(); + final String testHexString = ByteConvert.toHex(testByteA); + + @Test + void testToHex() { + String s = ByteConvert.toHex(testByteA); + assertArrayEquals(testByteA, ByteConvert.fromHex(s)); + } + + @Test + void testFromHex() { + byte[] b = ByteConvert.fromHex(testHexString); + assertEquals(testHexString, ByteConvert.toHex(b)); + } +}