This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
commit 52e740f67b30e6369ce7a3082725b60e79beb297 Author: Jan Bednář <m...@janbednar.eu> AuthorDate: Fri Jul 5 21:58:38 2019 +0200 CAMEL-13628: Docs, polish --- .../src/main/docs/file-watch-component.adoc | 78 +++++++--------------- .../component/file/watch/FileWatchComponent.java | 2 +- .../component/file/watch/FileWatchConsumer.java | 14 ++-- .../component/file/watch/constants/FileEvent.java | 8 ++- .../file/watch/FileWatchComponentTestBase.java | 1 - .../camel/component/file/watch/TestHasher.java | 5 +- 6 files changed, 45 insertions(+), 63 deletions(-) diff --git a/components/camel-file-watch/src/main/docs/file-watch-component.adoc b/components/camel-file-watch/src/main/docs/file-watch-component.adoc index 5117873..67a469b 100644 --- a/components/camel-file-watch/src/main/docs/file-watch-component.adoc +++ b/components/camel-file-watch/src/main/docs/file-watch-component.adoc @@ -90,11 +90,30 @@ The component supports 3 options, which are listed below. |=== // spring-boot-auto-configure options: END -=== TODO +This component can be used to watch file modification events in folder. It is based on https://github.com/gmethvin/directory-watcher[gmethvin/directory-watcher]. +=== Examples: + +==== Recursive watch all events (file creation, file deletion, file modification): +[source,java] +---- +from("file-watch://some-directory") + .log("File event: ${header.CamelFileEventType} occurred on file ${header.CamelFileName} at ${header.CamelFileLastModified}"); +---- + +==== Recursive watch for creation and deletion of txt files: +[source,java] +---- +from("file-watch://some-directory?events=DELETE,CREATE&antInclude=**/*.txt") + .log("File event: ${header.CamelFileEventType} occurred on file ${header.CamelFileName} at ${header.CamelFileLastModified}"); +---- + +==== Create snapshot of file when modified: [source,java] ---- -TODO +from("file-watch://some-directory?events=MODIFY&recursive=false") + .setHeader(Exchange.FILE_NAME, simple("${header.CamelFileName}.${header.CamelFileLastModified}")) + .to("file:some-directory/snapshots"); ---- === Message Headers @@ -107,6 +126,9 @@ The following headers are supported by this component: |=== |Header |Description +|`CamelFileEventType` |Type of event. Possible values: CREATE, DELETE, MODIFY. +The java type of this header is `org.apache.camel.component.file.watch.constants.FileEventEnum` + |`CamelFileName` |Name of the consumed file as a relative file path with offset from the starting directory configured on the endpoint. @@ -128,55 +150,5 @@ relative filename. For absolute files this is the absolute path. |`CamelFileParent` |The parent path. -|`CamelFileLength` |A `long` value containing the file size. - -|`CamelFileLastModified` |A `Long` value containing the last modified timestamp of the file. In -*Camel 2.10.3 and older* the type is `Date`. +|`CamelFileLastModified` |A `Long` value containing the last modified timestamp of the file. |=== - -=== Filtering using ANT path matcher - -The file paths is matched with the following rules: - -* `?` matches one character -* `*` matches zero or more characters -* `**` matches zero or more directories in a path - -TIP: *New options from Camel 2.10 onwards* -There are now `antInclude` and `antExclude` options to make it easy to -specify ANT style include/exclude without having to define the filter. -See the URI options above for more information. - -The sample below demonstrates how to use it: - -=== Using consumer.bridgeErrorHandler - -If you want to use the Camel Error Handler to -deal with any exception occurring in the file consumer, then you can -enable the `consumer.bridgeErrorHandler` option as shown below: - -[source,java] ----- -// to handle any IOException being thrown -onException(IOException.class) - .handled(true) - .log("IOException occurred due: ${exception.message}") - .transform().simple("Error ${exception.message}") - .to("mock:error"); - -// this is the file route that pickup files, notice how we bridge the consumer to use the Camel routing error handler -// the exclusiveReadLockStrategy is only configured because this is from an unit test, so we use that to simulate exceptions -from("file-watch:target/nospace?consumer.bridgeErrorHandler=true") - .convertBodyTo(String.class) - .to("mock:result"); ----- - -So all you have to do is to enable this option, and the error handler in -the route will take it from there. - -IMPORTANT: *Important when using consumer.bridgeErrorHandler* -When using consumer.bridgeErrorHandler, then -interceptors, OnCompletions -does *not* apply. The Exchange is processed directly -by the Camel Error Handler, and does not allow -prior actions such as interceptors, onCompletion to take action. diff --git a/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchComponent.java b/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchComponent.java index 49ee6e0..03bafa6 100644 --- a/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchComponent.java +++ b/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchComponent.java @@ -29,7 +29,7 @@ import org.apache.camel.support.DefaultComponent; */ @Component("file-watch") public class FileWatchComponent extends DefaultComponent { - public static final String EVENT_TYPE_HEADER = "FileEventType"; + public static final String EVENT_TYPE_HEADER = "CamelFileEventType"; protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception { Endpoint endpoint = new FileWatchEndpoint(uri, remaining, this); diff --git a/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchConsumer.java b/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchConsumer.java index f30706b..ece2040 100644 --- a/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchConsumer.java +++ b/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchConsumer.java @@ -112,9 +112,15 @@ public class FileWatchConsumer extends DefaultConsumer { @Override protected void doStop() throws Exception { - this.watcher.close(); - getEndpoint().getCamelContext().getExecutorServiceManager().shutdownNow(watchDirExecutorService); - getEndpoint().getCamelContext().getExecutorServiceManager().shutdownNow(pollExecutorService); + if (this.watcher != null) { + this.watcher.close(); + } + if (watchDirExecutorService != null) { + getEndpoint().getCamelContext().getExecutorServiceManager().shutdownNow(watchDirExecutorService); + } + if (pollExecutorService != null) { + getEndpoint().getCamelContext().getExecutorServiceManager().shutdownNow(pollExecutorService); + } super.doStop(); } @@ -161,7 +167,7 @@ public class FileWatchConsumer extends DefaultConsumer { // On some platforms (eg macOS) is WatchService always recursive, // so we need to filter this out to make this component platform independent try { - if (!Files.isSameFile(fileEvent.getEventPath().getParent(), this.baseDirectory)){ + if (!Files.isSameFile(fileEvent.getEventPath().getParent(), this.baseDirectory)) { return false; } } catch (IOException e) { diff --git a/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/constants/FileEvent.java b/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/constants/FileEvent.java index ed263ec..8eca13a 100644 --- a/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/constants/FileEvent.java +++ b/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/constants/FileEvent.java @@ -24,18 +24,20 @@ import io.methvin.watcher.DirectoryChangeEvent; public class FileEvent { private FileEventEnum eventType; private Path eventPath; - private Date eventDate; + private long eventDate; private FileEvent() { - this.eventDate = new Date(); + this.eventDate = System.currentTimeMillis(); } public FileEvent(FileEventEnum eventType, Path eventPath) { + this(); this.eventType = eventType; this.eventPath = eventPath; } public FileEvent(DirectoryChangeEvent event) { + this(); this.eventType = FileEventEnum.valueOf(event.eventType()); this.eventPath = event.path(); } @@ -48,7 +50,7 @@ public class FileEvent { return eventPath; } - public Date getEventDate() { + public long getEventDate() { return this.eventDate; } } diff --git a/components/camel-file-watch/src/test/java/org/apache/camel/component/file/watch/FileWatchComponentTestBase.java b/components/camel-file-watch/src/test/java/org/apache/camel/component/file/watch/FileWatchComponentTestBase.java index a90b97c..1aca5d3 100644 --- a/components/camel-file-watch/src/test/java/org/apache/camel/component/file/watch/FileWatchComponentTestBase.java +++ b/components/camel-file-watch/src/test/java/org/apache/camel/component/file/watch/FileWatchComponentTestBase.java @@ -64,7 +64,6 @@ public class FileWatchComponentTestBase extends CamelTestSupport { } @Override - @After public void tearDown() throws Exception { super.tearDown(); cleanTestDir(new File(testPath())); diff --git a/components/camel-file-watch/src/test/java/org/apache/camel/component/file/watch/TestHasher.java b/components/camel-file-watch/src/test/java/org/apache/camel/component/file/watch/TestHasher.java index 16857c4..695f2b7 100644 --- a/components/camel-file-watch/src/test/java/org/apache/camel/component/file/watch/TestHasher.java +++ b/components/camel-file-watch/src/test/java/org/apache/camel/component/file/watch/TestHasher.java @@ -22,12 +22,15 @@ import java.nio.file.Path; import io.methvin.watcher.hashing.FileHasher; import io.methvin.watcher.hashing.HashCode; +/** + * For unit test only! + */ public class TestHasher implements FileHasher { @Override public HashCode hash(Path path) throws IOException { // Always return constant // This should cause every event is triggered only once (hashcode remains the same), so we can test this. - // Never use this outside junit + // Never use this in production code return HashCode.fromLong(1L); } }