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 bf26c4e561b CAMEL-17586: camel-mail - Add option to either warn or 
exception on duplicate file attachments. Thanks to Manuel Shenavai for unit 
test.
bf26c4e561b is described below

commit bf26c4e561b2be3646821cb0a465dbd0b3944824
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Mon Sep 5 20:47:23 2022 +0200

    CAMEL-17586: camel-mail - Add option to either warn or exception on 
duplicate file attachments. Thanks to Manuel Shenavai for unit test.
---
 .../component/mail/MailComponentConfigurer.java    |  6 ++
 .../component/mail/MailEndpointConfigurer.java     |  6 ++
 .../component/mail/MailEndpointUriFactory.java     |  3 +-
 .../org/apache/camel/component/mail/imap.json      |  2 +
 .../org/apache/camel/component/mail/imaps.json     |  2 +
 .../org/apache/camel/component/mail/pop3.json      |  2 +
 .../org/apache/camel/component/mail/pop3s.json     |  2 +
 .../org/apache/camel/component/mail/smtp.json      |  2 +
 .../org/apache/camel/component/mail/smtps.json     |  2 +
 .../apache/camel/component/mail/MailBinding.java   | 34 +++++++-
 .../camel/component/mail/MailConfiguration.java    | 15 ++++
 .../apache/camel/component/mail/MailEndpoint.java  |  3 +-
 ...MailBindingAttachmentDuplicateFileNameTest.java | 98 ++++++++++++++++++++++
 13 files changed, 173 insertions(+), 4 deletions(-)

diff --git 
a/components/camel-mail/src/generated/java/org/apache/camel/component/mail/MailComponentConfigurer.java
 
b/components/camel-mail/src/generated/java/org/apache/camel/component/mail/MailComponentConfigurer.java
index fdbef1121b3..9fb5fb10496 100644
--- 
a/components/camel-mail/src/generated/java/org/apache/camel/component/mail/MailComponentConfigurer.java
+++ 
b/components/camel-mail/src/generated/java/org/apache/camel/component/mail/MailComponentConfigurer.java
@@ -58,6 +58,8 @@ public class MailComponentConfigurer extends 
PropertyConfigurerSupport implement
         case "decodeFilename": 
getOrCreateConfiguration(target).setDecodeFilename(property(camelContext, 
boolean.class, value)); return true;
         case "delete": 
getOrCreateConfiguration(target).setDelete(property(camelContext, 
boolean.class, value)); return true;
         case "disconnect": 
getOrCreateConfiguration(target).setDisconnect(property(camelContext, 
boolean.class, value)); return true;
+        case "failonduplicatefileattachment":
+        case "failOnDuplicateFileAttachment": 
getOrCreateConfiguration(target).setFailOnDuplicateFileAttachment(property(camelContext,
 boolean.class, value)); return true;
         case "fetchsize":
         case "fetchSize": 
getOrCreateConfiguration(target).setFetchSize(property(camelContext, int.class, 
value)); return true;
         case "foldername":
@@ -137,6 +139,8 @@ public class MailComponentConfigurer extends 
PropertyConfigurerSupport implement
         case "decodeFilename": return boolean.class;
         case "delete": return boolean.class;
         case "disconnect": return boolean.class;
+        case "failonduplicatefileattachment":
+        case "failOnDuplicateFileAttachment": return boolean.class;
         case "fetchsize":
         case "fetchSize": return int.class;
         case "foldername":
@@ -217,6 +221,8 @@ public class MailComponentConfigurer extends 
PropertyConfigurerSupport implement
         case "decodeFilename": return 
getOrCreateConfiguration(target).isDecodeFilename();
         case "delete": return getOrCreateConfiguration(target).isDelete();
         case "disconnect": return 
getOrCreateConfiguration(target).isDisconnect();
+        case "failonduplicatefileattachment":
+        case "failOnDuplicateFileAttachment": return 
getOrCreateConfiguration(target).isFailOnDuplicateFileAttachment();
         case "fetchsize":
         case "fetchSize": return 
getOrCreateConfiguration(target).getFetchSize();
         case "foldername":
diff --git 
a/components/camel-mail/src/generated/java/org/apache/camel/component/mail/MailEndpointConfigurer.java
 
b/components/camel-mail/src/generated/java/org/apache/camel/component/mail/MailEndpointConfigurer.java
index b47422ecc24..eece4ac83c6 100644
--- 
a/components/camel-mail/src/generated/java/org/apache/camel/component/mail/MailEndpointConfigurer.java
+++ 
b/components/camel-mail/src/generated/java/org/apache/camel/component/mail/MailEndpointConfigurer.java
@@ -60,6 +60,8 @@ public class MailEndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "exceptionHandler": 
target.setExceptionHandler(property(camelContext, 
org.apache.camel.spi.ExceptionHandler.class, value)); return true;
         case "exchangepattern":
         case "exchangePattern": 
target.setExchangePattern(property(camelContext, 
org.apache.camel.ExchangePattern.class, value)); return true;
+        case "failonduplicatefileattachment":
+        case "failOnDuplicateFileAttachment": 
target.getConfiguration().setFailOnDuplicateFileAttachment(property(camelContext,
 boolean.class, value)); return true;
         case "fetchsize":
         case "fetchSize": 
target.getConfiguration().setFetchSize(property(camelContext, int.class, 
value)); return true;
         case "foldername":
@@ -182,6 +184,8 @@ public class MailEndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "exceptionHandler": return 
org.apache.camel.spi.ExceptionHandler.class;
         case "exchangepattern":
         case "exchangePattern": return org.apache.camel.ExchangePattern.class;
+        case "failonduplicatefileattachment":
+        case "failOnDuplicateFileAttachment": return boolean.class;
         case "fetchsize":
         case "fetchSize": return int.class;
         case "foldername":
@@ -305,6 +309,8 @@ public class MailEndpointConfigurer extends 
PropertyConfigurerSupport implements
         case "exceptionHandler": return target.getExceptionHandler();
         case "exchangepattern":
         case "exchangePattern": return target.getExchangePattern();
+        case "failonduplicatefileattachment":
+        case "failOnDuplicateFileAttachment": return 
target.getConfiguration().isFailOnDuplicateFileAttachment();
         case "fetchsize":
         case "fetchSize": return target.getConfiguration().getFetchSize();
         case "foldername":
diff --git 
a/components/camel-mail/src/generated/java/org/apache/camel/component/mail/MailEndpointUriFactory.java
 
b/components/camel-mail/src/generated/java/org/apache/camel/component/mail/MailEndpointUriFactory.java
index 290084a9809..a19f3fa6010 100644
--- 
a/components/camel-mail/src/generated/java/org/apache/camel/component/mail/MailEndpointUriFactory.java
+++ 
b/components/camel-mail/src/generated/java/org/apache/camel/component/mail/MailEndpointUriFactory.java
@@ -22,7 +22,7 @@ public class MailEndpointUriFactory extends 
org.apache.camel.support.component.E
     private static final Set<String> SECRET_PROPERTY_NAMES;
     private static final Set<String> MULTI_VALUE_PREFIXES;
     static {
-        Set<String> props = new HashSet<>(68);
+        Set<String> props = new HashSet<>(69);
         props.add("additionalJavaMailProperties");
         props.add("alternativeBodyHeader");
         props.add("attachmentsContentTransferEncodingResolver");
@@ -46,6 +46,7 @@ public class MailEndpointUriFactory extends 
org.apache.camel.support.component.E
         props.add("disconnect");
         props.add("exceptionHandler");
         props.add("exchangePattern");
+        props.add("failOnDuplicateFileAttachment");
         props.add("fetchSize");
         props.add("folderName");
         props.add("from");
diff --git 
a/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/imap.json
 
b/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/imap.json
index 51acff65522..b81465232b8 100644
--- 
a/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/imap.json
+++ 
b/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/imap.json
@@ -36,6 +36,7 @@
     "peek": { "kind": "property", "displayName": "Peek", "group": "consumer", 
"label": "consumer", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Will mark the javax.mail.Message as peeked 
before processing the mail message. This applies to IMAP [...]
     "skipFailedMessage": { "kind": "property", "displayName": "Skip Failed 
Message", "group": "consumer", "label": "consumer", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "If the mail consumer 
cannot retrieve a given mail message, then this o [...]
     "unseen": { "kind": "property", "displayName": "Unseen", "group": 
"consumer", "label": "consumer", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to limit by unseen mails only." },
+    "failOnDuplicateFileAttachment": { "kind": "property", "displayName": 
"Fail On Duplicate File Attachment", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to fail processing the mail if the 
mail [...]
     "fetchSize": { "kind": "property", "displayName": "Fetch Size", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": -1, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Sets the maximum number of messages to consume 
during a poll. This can be  [...]
     "folderName": { "kind": "property", "displayName": "Folder Name", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "INBOX", "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The folder to poll." },
     "mapMailMessage": { "kind": "property", "displayName": "Map Mail Message", 
"group": "consumer (advanced)", "label": "consumer,advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "Specifies whether Camel 
should map the received mail message to Camel body\/head [...]
@@ -100,6 +101,7 @@
     "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "Allows for bridging the consumer to the Camel routing Error 
Handler, which mean any exceptions occurred while the consumer is trying to 
pickup incoming messages, or the likes, will now [...]
     "exceptionHandler": { "kind": "parameter", "displayName": "Exception 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By default the 
con [...]
     "exchangePattern": { "kind": "parameter", "displayName": "Exchange 
Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", 
"InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, 
"description": "Sets the exchange pattern when the consumer creates an 
exchange." },
+    "failOnDuplicateFileAttachment": { "kind": "parameter", "displayName": 
"Fail On Duplicate File Attachment", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to fail processing the mail if the mai 
[...]
     "fetchSize": { "kind": "parameter", "displayName": "Fetch Size", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": -1, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Sets the maximum number of messages to consume 
during a poll. This can be [...]
     "folderName": { "kind": "parameter", "displayName": "Folder Name", 
"group": "consumer (advanced)", "label": "consumer,advanced", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "INBOX", 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "The folder to poll." },
     "mailUidGenerator": { "kind": "parameter", "displayName": "Mail Uid 
Generator", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.component.mail.MailUidGenerator", "deprecated": false, 
"autowired": false, "secret": false, "description": "A pluggable 
MailUidGenerator that allows to use custom logic to generate UUID of the mail 
message." },
diff --git 
a/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/imaps.json
 
b/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/imaps.json
index cd871152d17..25c4119fc4b 100644
--- 
a/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/imaps.json
+++ 
b/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/imaps.json
@@ -36,6 +36,7 @@
     "peek": { "kind": "property", "displayName": "Peek", "group": "consumer", 
"label": "consumer", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Will mark the javax.mail.Message as peeked 
before processing the mail message. This applies to IMAP [...]
     "skipFailedMessage": { "kind": "property", "displayName": "Skip Failed 
Message", "group": "consumer", "label": "consumer", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "If the mail consumer 
cannot retrieve a given mail message, then this o [...]
     "unseen": { "kind": "property", "displayName": "Unseen", "group": 
"consumer", "label": "consumer", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to limit by unseen mails only." },
+    "failOnDuplicateFileAttachment": { "kind": "property", "displayName": 
"Fail On Duplicate File Attachment", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to fail processing the mail if the 
mail [...]
     "fetchSize": { "kind": "property", "displayName": "Fetch Size", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": -1, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Sets the maximum number of messages to consume 
during a poll. This can be  [...]
     "folderName": { "kind": "property", "displayName": "Folder Name", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "INBOX", "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The folder to poll." },
     "mapMailMessage": { "kind": "property", "displayName": "Map Mail Message", 
"group": "consumer (advanced)", "label": "consumer,advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "Specifies whether Camel 
should map the received mail message to Camel body\/head [...]
@@ -100,6 +101,7 @@
     "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "Allows for bridging the consumer to the Camel routing Error 
Handler, which mean any exceptions occurred while the consumer is trying to 
pickup incoming messages, or the likes, will now [...]
     "exceptionHandler": { "kind": "parameter", "displayName": "Exception 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By default the 
con [...]
     "exchangePattern": { "kind": "parameter", "displayName": "Exchange 
Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", 
"InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, 
"description": "Sets the exchange pattern when the consumer creates an 
exchange." },
+    "failOnDuplicateFileAttachment": { "kind": "parameter", "displayName": 
"Fail On Duplicate File Attachment", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to fail processing the mail if the mai 
[...]
     "fetchSize": { "kind": "parameter", "displayName": "Fetch Size", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": -1, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Sets the maximum number of messages to consume 
during a poll. This can be [...]
     "folderName": { "kind": "parameter", "displayName": "Folder Name", 
"group": "consumer (advanced)", "label": "consumer,advanced", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "INBOX", 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "The folder to poll." },
     "mailUidGenerator": { "kind": "parameter", "displayName": "Mail Uid 
Generator", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.component.mail.MailUidGenerator", "deprecated": false, 
"autowired": false, "secret": false, "description": "A pluggable 
MailUidGenerator that allows to use custom logic to generate UUID of the mail 
message." },
diff --git 
a/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/pop3.json
 
b/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/pop3.json
index b89e9bb3d9e..4713c9095ab 100644
--- 
a/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/pop3.json
+++ 
b/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/pop3.json
@@ -36,6 +36,7 @@
     "peek": { "kind": "property", "displayName": "Peek", "group": "consumer", 
"label": "consumer", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Will mark the javax.mail.Message as peeked 
before processing the mail message. This applies to IMAP [...]
     "skipFailedMessage": { "kind": "property", "displayName": "Skip Failed 
Message", "group": "consumer", "label": "consumer", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "If the mail consumer 
cannot retrieve a given mail message, then this o [...]
     "unseen": { "kind": "property", "displayName": "Unseen", "group": 
"consumer", "label": "consumer", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to limit by unseen mails only." },
+    "failOnDuplicateFileAttachment": { "kind": "property", "displayName": 
"Fail On Duplicate File Attachment", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to fail processing the mail if the 
mail [...]
     "fetchSize": { "kind": "property", "displayName": "Fetch Size", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": -1, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Sets the maximum number of messages to consume 
during a poll. This can be  [...]
     "folderName": { "kind": "property", "displayName": "Folder Name", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "INBOX", "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The folder to poll." },
     "mapMailMessage": { "kind": "property", "displayName": "Map Mail Message", 
"group": "consumer (advanced)", "label": "consumer,advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "Specifies whether Camel 
should map the received mail message to Camel body\/head [...]
@@ -100,6 +101,7 @@
     "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "Allows for bridging the consumer to the Camel routing Error 
Handler, which mean any exceptions occurred while the consumer is trying to 
pickup incoming messages, or the likes, will now [...]
     "exceptionHandler": { "kind": "parameter", "displayName": "Exception 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By default the 
con [...]
     "exchangePattern": { "kind": "parameter", "displayName": "Exchange 
Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", 
"InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, 
"description": "Sets the exchange pattern when the consumer creates an 
exchange." },
+    "failOnDuplicateFileAttachment": { "kind": "parameter", "displayName": 
"Fail On Duplicate File Attachment", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to fail processing the mail if the mai 
[...]
     "fetchSize": { "kind": "parameter", "displayName": "Fetch Size", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": -1, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Sets the maximum number of messages to consume 
during a poll. This can be [...]
     "folderName": { "kind": "parameter", "displayName": "Folder Name", 
"group": "consumer (advanced)", "label": "consumer,advanced", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "INBOX", 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "The folder to poll." },
     "mailUidGenerator": { "kind": "parameter", "displayName": "Mail Uid 
Generator", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.component.mail.MailUidGenerator", "deprecated": false, 
"autowired": false, "secret": false, "description": "A pluggable 
MailUidGenerator that allows to use custom logic to generate UUID of the mail 
message." },
diff --git 
a/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/pop3s.json
 
b/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/pop3s.json
index b6cdb0f759c..94b90a645b4 100644
--- 
a/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/pop3s.json
+++ 
b/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/pop3s.json
@@ -36,6 +36,7 @@
     "peek": { "kind": "property", "displayName": "Peek", "group": "consumer", 
"label": "consumer", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Will mark the javax.mail.Message as peeked 
before processing the mail message. This applies to IMAP [...]
     "skipFailedMessage": { "kind": "property", "displayName": "Skip Failed 
Message", "group": "consumer", "label": "consumer", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "If the mail consumer 
cannot retrieve a given mail message, then this o [...]
     "unseen": { "kind": "property", "displayName": "Unseen", "group": 
"consumer", "label": "consumer", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to limit by unseen mails only." },
+    "failOnDuplicateFileAttachment": { "kind": "property", "displayName": 
"Fail On Duplicate File Attachment", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to fail processing the mail if the 
mail [...]
     "fetchSize": { "kind": "property", "displayName": "Fetch Size", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": -1, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Sets the maximum number of messages to consume 
during a poll. This can be  [...]
     "folderName": { "kind": "property", "displayName": "Folder Name", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "INBOX", "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The folder to poll." },
     "mapMailMessage": { "kind": "property", "displayName": "Map Mail Message", 
"group": "consumer (advanced)", "label": "consumer,advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "Specifies whether Camel 
should map the received mail message to Camel body\/head [...]
@@ -100,6 +101,7 @@
     "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "Allows for bridging the consumer to the Camel routing Error 
Handler, which mean any exceptions occurred while the consumer is trying to 
pickup incoming messages, or the likes, will now [...]
     "exceptionHandler": { "kind": "parameter", "displayName": "Exception 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By default the 
con [...]
     "exchangePattern": { "kind": "parameter", "displayName": "Exchange 
Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", 
"InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, 
"description": "Sets the exchange pattern when the consumer creates an 
exchange." },
+    "failOnDuplicateFileAttachment": { "kind": "parameter", "displayName": 
"Fail On Duplicate File Attachment", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to fail processing the mail if the mai 
[...]
     "fetchSize": { "kind": "parameter", "displayName": "Fetch Size", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": -1, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Sets the maximum number of messages to consume 
during a poll. This can be [...]
     "folderName": { "kind": "parameter", "displayName": "Folder Name", 
"group": "consumer (advanced)", "label": "consumer,advanced", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "INBOX", 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "The folder to poll." },
     "mailUidGenerator": { "kind": "parameter", "displayName": "Mail Uid 
Generator", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.component.mail.MailUidGenerator", "deprecated": false, 
"autowired": false, "secret": false, "description": "A pluggable 
MailUidGenerator that allows to use custom logic to generate UUID of the mail 
message." },
diff --git 
a/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/smtp.json
 
b/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/smtp.json
index 28b5e913297..8463308c410 100644
--- 
a/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/smtp.json
+++ 
b/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/smtp.json
@@ -36,6 +36,7 @@
     "peek": { "kind": "property", "displayName": "Peek", "group": "consumer", 
"label": "consumer", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Will mark the javax.mail.Message as peeked 
before processing the mail message. This applies to IMAP [...]
     "skipFailedMessage": { "kind": "property", "displayName": "Skip Failed 
Message", "group": "consumer", "label": "consumer", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "If the mail consumer 
cannot retrieve a given mail message, then this o [...]
     "unseen": { "kind": "property", "displayName": "Unseen", "group": 
"consumer", "label": "consumer", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to limit by unseen mails only." },
+    "failOnDuplicateFileAttachment": { "kind": "property", "displayName": 
"Fail On Duplicate File Attachment", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to fail processing the mail if the 
mail [...]
     "fetchSize": { "kind": "property", "displayName": "Fetch Size", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": -1, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Sets the maximum number of messages to consume 
during a poll. This can be  [...]
     "folderName": { "kind": "property", "displayName": "Folder Name", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "INBOX", "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The folder to poll." },
     "mapMailMessage": { "kind": "property", "displayName": "Map Mail Message", 
"group": "consumer (advanced)", "label": "consumer,advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "Specifies whether Camel 
should map the received mail message to Camel body\/head [...]
@@ -100,6 +101,7 @@
     "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "Allows for bridging the consumer to the Camel routing Error 
Handler, which mean any exceptions occurred while the consumer is trying to 
pickup incoming messages, or the likes, will now [...]
     "exceptionHandler": { "kind": "parameter", "displayName": "Exception 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By default the 
con [...]
     "exchangePattern": { "kind": "parameter", "displayName": "Exchange 
Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", 
"InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, 
"description": "Sets the exchange pattern when the consumer creates an 
exchange." },
+    "failOnDuplicateFileAttachment": { "kind": "parameter", "displayName": 
"Fail On Duplicate File Attachment", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to fail processing the mail if the mai 
[...]
     "fetchSize": { "kind": "parameter", "displayName": "Fetch Size", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": -1, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Sets the maximum number of messages to consume 
during a poll. This can be [...]
     "folderName": { "kind": "parameter", "displayName": "Folder Name", 
"group": "consumer (advanced)", "label": "consumer,advanced", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "INBOX", 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "The folder to poll." },
     "mailUidGenerator": { "kind": "parameter", "displayName": "Mail Uid 
Generator", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.component.mail.MailUidGenerator", "deprecated": false, 
"autowired": false, "secret": false, "description": "A pluggable 
MailUidGenerator that allows to use custom logic to generate UUID of the mail 
message." },
diff --git 
a/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/smtps.json
 
b/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/smtps.json
index d0a5fe7818f..a52cc773d9b 100644
--- 
a/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/smtps.json
+++ 
b/components/camel-mail/src/generated/resources/org/apache/camel/component/mail/smtps.json
@@ -36,6 +36,7 @@
     "peek": { "kind": "property", "displayName": "Peek", "group": "consumer", 
"label": "consumer", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Will mark the javax.mail.Message as peeked 
before processing the mail message. This applies to IMAP [...]
     "skipFailedMessage": { "kind": "property", "displayName": "Skip Failed 
Message", "group": "consumer", "label": "consumer", "required": false, "type": 
"boolean", "javaType": "boolean", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": false, 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "If the mail consumer 
cannot retrieve a given mail message, then this o [...]
     "unseen": { "kind": "property", "displayName": "Unseen", "group": 
"consumer", "label": "consumer", "required": false, "type": "boolean", 
"javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": 
false, "secret": false, "defaultValue": true, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to limit by unseen mails only." },
+    "failOnDuplicateFileAttachment": { "kind": "property", "displayName": 
"Fail On Duplicate File Attachment", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to fail processing the mail if the 
mail [...]
     "fetchSize": { "kind": "property", "displayName": "Fetch Size", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": -1, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Sets the maximum number of messages to consume 
during a poll. This can be  [...]
     "folderName": { "kind": "property", "displayName": "Folder Name", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"string", "javaType": "java.lang.String", "deprecated": false, "autowired": 
false, "secret": false, "defaultValue": "INBOX", "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "The folder to poll." },
     "mapMailMessage": { "kind": "property", "displayName": "Map Mail Message", 
"group": "consumer (advanced)", "label": "consumer,advanced", "required": 
false, "type": "boolean", "javaType": "boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": true, 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "Specifies whether Camel 
should map the received mail message to Camel body\/head [...]
@@ -100,6 +101,7 @@
     "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "boolean", "javaType": "boolean", "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": false, 
"description": "Allows for bridging the consumer to the Camel routing Error 
Handler, which mean any exceptions occurred while the consumer is trying to 
pickup incoming messages, or the likes, will now [...]
     "exceptionHandler": { "kind": "parameter", "displayName": "Exception 
Handler", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", 
"deprecated": false, "autowired": false, "secret": false, "description": "To 
let the consumer use a custom ExceptionHandler. Notice if the option 
bridgeErrorHandler is enabled then this option is not in use. By default the 
con [...]
     "exchangePattern": { "kind": "parameter", "displayName": "Exchange 
Pattern", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.ExchangePattern", "enum": [ "InOnly", "InOut", 
"InOptionalOut" ], "deprecated": false, "autowired": false, "secret": false, 
"description": "Sets the exchange pattern when the consumer creates an 
exchange." },
+    "failOnDuplicateFileAttachment": { "kind": "parameter", "displayName": 
"Fail On Duplicate File Attachment", "group": "consumer (advanced)", "label": 
"consumer,advanced", "required": false, "type": "boolean", "javaType": 
"boolean", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": false, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Whether to fail processing the mail if the mai 
[...]
     "fetchSize": { "kind": "parameter", "displayName": "Fetch Size", "group": 
"consumer (advanced)", "label": "consumer,advanced", "required": false, "type": 
"integer", "javaType": "int", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "defaultValue": -1, "configurationClass": 
"org.apache.camel.component.mail.MailConfiguration", "configurationField": 
"configuration", "description": "Sets the maximum number of messages to consume 
during a poll. This can be [...]
     "folderName": { "kind": "parameter", "displayName": "Folder Name", 
"group": "consumer (advanced)", "label": "consumer,advanced", "required": 
false, "type": "string", "javaType": "java.lang.String", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": "INBOX", 
"configurationClass": "org.apache.camel.component.mail.MailConfiguration", 
"configurationField": "configuration", "description": "The folder to poll." },
     "mailUidGenerator": { "kind": "parameter", "displayName": "Mail Uid 
Generator", "group": "consumer (advanced)", "label": "consumer,advanced", 
"required": false, "type": "object", "javaType": 
"org.apache.camel.component.mail.MailUidGenerator", "deprecated": false, 
"autowired": false, "secret": false, "description": "A pluggable 
MailUidGenerator that allows to use custom logic to generate UUID of the mail 
message." },
diff --git 
a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailBinding.java
 
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailBinding.java
index becccec0985..5d26399ec35 100644
--- 
a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailBinding.java
+++ 
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailBinding.java
@@ -72,6 +72,7 @@ public class MailBinding {
     private ContentTypeResolver contentTypeResolver;
     private boolean decodeFilename;
     private boolean mapMailMessage = true;
+    private boolean failOnDuplicateAttachment;
 
     public MailBinding() {
         headerFilterStrategy = new DefaultHeaderFilterStrategy();
@@ -80,15 +81,29 @@ public class MailBinding {
     @Deprecated
     public MailBinding(HeaderFilterStrategy headerFilterStrategy, 
ContentTypeResolver contentTypeResolver,
                        boolean decodeFilename) {
-        this(headerFilterStrategy, contentTypeResolver, decodeFilename, true);
+        this(headerFilterStrategy, contentTypeResolver, decodeFilename, true, 
false);
     }
 
     public MailBinding(HeaderFilterStrategy headerFilterStrategy, 
ContentTypeResolver contentTypeResolver,
                        boolean decodeFilename, boolean mapMailMessage) {
+        this(headerFilterStrategy, contentTypeResolver, decodeFilename, 
mapMailMessage, false);
+    }
+
+    public MailBinding(HeaderFilterStrategy headerFilterStrategy, 
ContentTypeResolver contentTypeResolver,
+                       boolean decodeFilename, boolean mapMailMessage, boolean 
failOnDuplicateAttachment) {
         this.headerFilterStrategy = headerFilterStrategy;
         this.contentTypeResolver = contentTypeResolver;
         this.decodeFilename = decodeFilename;
         this.mapMailMessage = mapMailMessage;
+        this.failOnDuplicateAttachment = failOnDuplicateAttachment;
+    }
+
+    public boolean isFailOnDuplicateAttachment() {
+        return failOnDuplicateAttachment;
+    }
+
+    public void setFailOnDuplicateAttachment(boolean 
failOnDuplicateAttachment) {
+        this.failOnDuplicateAttachment = failOnDuplicateAttachment;
     }
 
     public void populateMailMessage(MailEndpoint endpoint, MimeMessage 
mimeMessage, Exchange exchange)
@@ -370,13 +385,28 @@ public class MailBinding {
                         }
                         map.put(fileName, camelAttachment);
                     } else {
-                        LOG.warn("Cannot extract duplicate file attachment: 
{}.", fileName);
+                        handleDuplicateFileAttachment(mp, fileName);
                     }
                 }
             }
         }
     }
 
+    /**
+     * Strategy for handling extracting mail message that has duplicate file 
attachments
+     *
+     * @param mp  the multipart entity
+     * @param duplicateFileName the duplicated file name
+     * @throws MessagingException is thrown, failing with an error
+     */
+    protected void handleDuplicateFileAttachment(Multipart mp, String 
duplicateFileName) throws MessagingException {
+        if (failOnDuplicateAttachment) {
+            throw new MessagingException("Duplicate file attachment: " + 
duplicateFileName);
+        } else {
+            LOG.warn("Cannot extract duplicate file attachment: {}.", 
duplicateFileName);
+        }
+    }
+
     private boolean validDisposition(String disposition, String fileName) {
         if (fileName == null || fileName.isEmpty()) {
             return false;
diff --git 
a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConfiguration.java
 
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConfiguration.java
index 0ed8de6a505..328603d9297 100644
--- 
a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConfiguration.java
+++ 
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConfiguration.java
@@ -138,6 +138,8 @@ public class MailConfiguration implements Cloneable {
     private Properties javaMailProperties;
     @UriParam(label = "advanced")
     private MailAuthenticator authenticator;
+    @UriParam(label = "consumer,advanced")
+    private boolean failOnDuplicateFileAttachment;
 
     public MailConfiguration() {
     }
@@ -828,4 +830,17 @@ public class MailConfiguration implements Cloneable {
     public void setDecodeFilename(boolean decodeFilename) {
         this.decodeFilename = decodeFilename;
     }
+
+    public boolean isFailOnDuplicateFileAttachment() {
+        return failOnDuplicateFileAttachment;
+    }
+
+    /**
+     * Whether to fail processing the mail if the mail message contains 
attachments with duplicate file names. If set to
+     * false, then the duplicate attachment is skipped and a WARN is logged. 
If set to true then an exception is thrown
+     * failing to process the mail message.
+     */
+    public void setFailOnDuplicateFileAttachment(boolean 
failOnDuplicateFileAttachment) {
+        this.failOnDuplicateFileAttachment = failOnDuplicateFileAttachment;
+    }
 }
diff --git 
a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java
 
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java
index 2396fc68212..4c8a186365b 100644
--- 
a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java
+++ 
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java
@@ -140,7 +140,8 @@ public class MailEndpoint extends ScheduledPollEndpoint 
implements HeaderFilterS
         if (binding == null) {
             boolean decode = getConfiguration() != null && 
getConfiguration().isDecodeFilename();
             boolean mapMailMessage = getConfiguration() != null && 
getConfiguration().isMapMailMessage();
-            binding = new MailBinding(headerFilterStrategy, 
contentTypeResolver, decode, mapMailMessage);
+            boolean failDuplicate = getConfiguration() != null && 
getConfiguration().isFailOnDuplicateFileAttachment();
+            binding = new MailBinding(headerFilterStrategy, 
contentTypeResolver, decode, mapMailMessage, failDuplicate);
         }
         return binding;
     }
diff --git 
a/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailBindingAttachmentDuplicateFileNameTest.java
 
b/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailBindingAttachmentDuplicateFileNameTest.java
new file mode 100644
index 00000000000..0db6b55d98b
--- /dev/null
+++ 
b/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailBindingAttachmentDuplicateFileNameTest.java
@@ -0,0 +1,98 @@
+/*
+ * 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.mail;
+
+import java.util.HashMap;
+import java.util.Properties;
+
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+import javax.mail.Session;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class MailBindingAttachmentDuplicateFileNameTest {
+
+    private final MailBinding binding = new MailBinding();
+
+    @Test
+    public void shouldFailOnDuplicateFilenames() throws Exception {
+        binding.setFailOnDuplicateAttachment(true);
+
+        final Session session = Session.getInstance(new Properties());
+        final Message message = new MimeMessage(session);
+
+        String filename = "file.txt";
+        String filename2 = "file.txt";
+        setAttachments(message, filename, filename2);
+        extractAttachmentsAndValidate(message, filename, filename2);
+
+        filename = "file.txt";
+        filename2 = "../file.txt";
+        setAttachments(message, filename, filename2);
+        extractAttachmentsAndValidate(message, filename, filename2);
+
+        filename = "file.txt";
+        filename2 = "..\\file.txt";
+        setAttachments(message, filename, filename2);
+        extractAttachmentsAndValidate(message, filename, filename2);
+
+        filename = "file.txt";
+        filename2 = "/absolute/file.txt";
+        setAttachments(message, filename, filename2);
+        extractAttachmentsAndValidate(message, filename, filename2);
+
+        filename = "file.txt";
+        filename2 = "c:\\absolute\\file.txt";
+        setAttachments(message, filename, filename2);
+        extractAttachmentsAndValidate(message, filename, filename2);
+
+        filename = "..\\file.txt";
+        filename2 = "c:\\absolute\\file.txt";
+        setAttachments(message, filename, filename2);
+        extractAttachmentsAndValidate(message, filename, filename2);
+    }
+
+    private void extractAttachmentsAndValidate(Message message, String 
filename, String filename2) throws Exception {
+        MessagingException thrown;
+        setAttachments(message, filename, filename2);
+        thrown = assertThrows(MessagingException.class, () -> 
binding.extractAttachmentsFromMail(message, new HashMap<>()),
+                "Duplicate attachment names should cause an exception");
+        assertTrue(thrown.getMessage().contains("Duplicate file attachment"));
+    }
+
+    private void setAttachments(Message message, String name1, String name2) 
throws Exception {
+        Multipart multipart = new MimeMultipart();
+        MimeBodyPart part = new MimeBodyPart();
+        part.attachFile(name1);
+        multipart.addBodyPart(part);
+
+        part = new MimeBodyPart();
+        part.attachFile(name2);
+        multipart.addBodyPart(part);
+
+        message.setContent(multipart);
+    }
+
+}

Reply via email to