You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/12/01 11:29:32 UTC
(camel) branch main updated: Add checksum feature to camel-file/ftp (#12280)
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new ee5a75e4012 Add checksum feature to camel-file/ftp (#12280)
ee5a75e4012 is described below
commit ee5a75e40124a6ec0802624776bfddd018ddeb03
Author: Benjamin Graf <gr...@users.noreply.github.com>
AuthorDate: Fri Dec 1 12:29:26 2023 +0100
Add checksum feature to camel-file/ftp (#12280)
---
components/camel-file/pom.xml | 4 ++
.../camel/component/file/GenericFileEndpoint.java | 18 ++++++++
.../camel/component/file/GenericFileProducer.java | 29 ++++++++++++
.../FileProducerChecksumFileAlgorithmTest.java | 52 ++++++++++++++++++++++
4 files changed, 103 insertions(+)
diff --git a/components/camel-file/pom.xml b/components/camel-file/pom.xml
index 0aa95240204..5f637d91669 100644
--- a/components/camel-file/pom.xml
+++ b/components/camel-file/pom.xml
@@ -43,6 +43,10 @@
<groupId>org.apache.camel</groupId>
<artifactId>camel-cluster</artifactId>
</dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ </dependency>
</dependencies>
</project>
diff --git a/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java b/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java
index 668dddecb94..9b7d47f25fd 100644
--- a/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java
+++ b/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileEndpoint.java
@@ -162,6 +162,11 @@ public abstract class GenericFileEndpoint<T> extends ScheduledPollEndpoint imple
+ "To specify new-line (slash-n or slash-r) or tab (slash-t) characters then escape with an extra slash, "
+ "eg slash-slash-n.")
protected String appendChars;
+ @UriParam(label = "producer",
+ description = "If provided, then Camel will write a checksum file when the original file has been written. The checksum file "
+ + "will contain the checksum created with the provided algorithm for the original file. The checksum file will "
+ + "always be written in the same folder as the original file.")
+ protected String checksumFileAlgorithm;
// consumer options
@@ -1518,6 +1523,19 @@ public abstract class GenericFileEndpoint<T> extends ScheduledPollEndpoint imple
this.synchronous = synchronous;
}
+ public String getChecksumFileAlgorithm() {
+ return checksumFileAlgorithm;
+ }
+
+ /**
+ * If provided, then Camel will write a checksum file when the original file has been written. The checksum file
+ * will contain the checksum created with the provided algorithm for the original file. The checksum file will
+ * always be written in the same folder as the original file.
+ */
+ public void setChecksumFileAlgorithm(String checksumFileAlgorithm) {
+ this.checksumFileAlgorithm = checksumFileAlgorithm;
+ }
+
/**
* Configures the given message with the file which sets the body to the file object.
*/
diff --git a/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileProducer.java b/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileProducer.java
index ac1f8435b63..417f083b233 100644
--- a/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileProducer.java
+++ b/components/camel-file/src/main/java/org/apache/camel/component/file/GenericFileProducer.java
@@ -17,6 +17,7 @@
package org.apache.camel.component.file;
import java.io.File;
+import java.io.InputStream;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.locks.Lock;
@@ -27,10 +28,12 @@ import org.apache.camel.Expression;
import org.apache.camel.support.DefaultExchange;
import org.apache.camel.support.DefaultProducer;
import org.apache.camel.support.LRUCacheFactory;
+import org.apache.camel.support.MessageHelper;
import org.apache.camel.support.service.ServiceHelper;
import org.apache.camel.util.FileUtil;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.StringHelper;
+import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -212,6 +215,11 @@ public class GenericFileProducer<T> extends DefaultProducer {
}
}
+ // any checksum file to write?
+ if (endpoint.getChecksumFileAlgorithm() != null) {
+ writeChecksumFile(exchange, target);
+ }
+
// any done file to write?
if (endpoint.getDoneFileName() != null) {
String doneFileName = endpoint.createDoneFileName(target);
@@ -242,6 +250,27 @@ public class GenericFileProducer<T> extends DefaultProducer {
postWriteCheck(exchange);
}
+ public void writeChecksumFile(Exchange exchange, String target) throws Exception {
+ String algorithm = endpoint.getChecksumFileAlgorithm();
+ String checksumFileName = target + "." + algorithm;
+
+ // create exchange with checksum as body to write as the checksum file
+ MessageHelper.resetStreamCache(exchange.getIn());
+ InputStream is = exchange.getIn().getMandatoryBody(InputStream.class);
+ Exchange checksumExchange = new DefaultExchange(exchange);
+ checksumExchange.getIn().setBody(new DigestUtils(algorithm).digestAsHex(is));
+
+ LOG.trace("Writing checksum file: [{}]", checksumFileName);
+ // delete any existing done file
+ if (operations.existsFile(checksumFileName)) {
+ if (!operations.deleteFile(checksumFileName)) {
+ throw new GenericFileOperationFailedException(
+ "Cannot delete existing checksum file: " + checksumFileName);
+ }
+ }
+ writeFile(checksumExchange, checksumFileName);
+ }
+
/**
* If we fail writing out a file, we will call this method. This hook is provided to disconnect from servers or
* clean up files we created (if needed).
diff --git a/core/camel-core/src/test/java/org/apache/camel/component/file/FileProducerChecksumFileAlgorithmTest.java b/core/camel-core/src/test/java/org/apache/camel/component/file/FileProducerChecksumFileAlgorithmTest.java
new file mode 100644
index 00000000000..59772d3a1e5
--- /dev/null
+++ b/core/camel-core/src/test/java/org/apache/camel/component/file/FileProducerChecksumFileAlgorithmTest.java
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.Exchange;
+import org.apache.camel.converter.stream.InputStreamCache;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.camel.TestSupport.assertFileExists;
+
+public class FileProducerChecksumFileAlgorithmTest extends ContextTestSupport {
+
+ @Test
+ public void testProducerChecksumFileMd5() throws Exception {
+ template.sendBodyAndHeader(fileUri("?checksumFileAlgorithm=md5"), "Hello World", Exchange.FILE_NAME, "hello.txt");
+
+ assertFileExists(testFile("hello.txt"));
+ assertFileExists(testFile("hello.txt.md5"), "b10a8db164e0754105b7a99be72e3fe5");
+ }
+
+ @Test
+ public void testProducerChecksumFileSha256() throws Exception {
+ template.sendBodyAndHeader(fileUri("?checksumFileAlgorithm=sha256"), "Hello World", Exchange.FILE_NAME, "hello.txt");
+
+ assertFileExists(testFile("hello.txt"));
+ assertFileExists(testFile("hello.txt.sha256"), "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e");
+ }
+
+ @Test
+ public void testProducerChecksumFileSha256WithStreamCaching() throws Exception {
+ InputStreamCache cache = new InputStreamCache("Hello World".getBytes());
+ template.sendBodyAndHeader(fileUri("?checksumFileAlgorithm=sha256"), cache, Exchange.FILE_NAME, "hello.txt");
+
+ assertFileExists(testFile("hello.txt"));
+ assertFileExists(testFile("hello.txt.sha256"), "a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e");
+ }
+}