This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push:
new 41cb193 CAMEL-14588:New setting to allow mails to be moved after
processing (#3587)
41cb193 is described below
commit 41cb1934fc85239bf2c6fe01e18f63a3e5a6076a
Author: Manuel <[email protected]>
AuthorDate: Wed Feb 19 20:22:44 2020 +0100
CAMEL-14588:New setting to allow mails to be moved after processing (#3587)
---
.../camel-mail/src/main/docs/mail-component.adoc | 1 +
.../camel/component/mail/MailConfiguration.java | 15 +++
.../apache/camel/component/mail/MailConsumer.java | 34 +++---
.../camel/component/mail/MailMoveToTest.java | 119 +++++++++++++++++++++
4 files changed, 157 insertions(+), 12 deletions(-)
diff --git a/components/camel-mail/src/main/docs/mail-component.adoc
b/components/camel-mail/src/main/docs/mail-component.adoc
index 1f3fd34..5c81e46 100644
--- a/components/camel-mail/src/main/docs/mail-component.adoc
+++ b/components/camel-mail/src/main/docs/mail-component.adoc
@@ -144,6 +144,7 @@ with the following path and query parameters:
| *bridgeErrorHandler* (consumer) | 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 be
processed as a message and handled by the routing Error Handler. By default the
consumer will use the org.apache.camel.spi.ExceptionHandler to deal with
exceptions, that will be logged at WARN or ERROR level and ignored. | false |
boolean
| *closeFolder* (consumer) | Whether the consumer should close the folder
after polling. Setting this option to false and having disconnect=false as
well, then the consumer keep the folder open between polls. | true | boolean
| *copyTo* (consumer) | After processing a mail message, it can be copied to a
mail folder with the given name. You can override this configuration value,
with a header with the key copyTo, allowing you to copy messages to folder
names configured at runtime. | | String
+| *moveTo* (consumer) | After processing a mail message, it can be copied to a
mail folder with the given name. You can override this configuration value,
with a header with the key moveTo, allowing you to move messages to folder
names configured at runtime. | | String
| *delete* (consumer) | Deletes the messages after they have been processed.
This is done by setting the DELETED flag on the mail message. If false, the
SEEN flag is set instead. As of Camel 2.10 you can override this configuration
option by setting a header with the key delete to determine if the mail should
be deleted or not. | false | boolean
| *disconnect* (consumer) | Whether the consumer should disconnect after
polling. If enabled this forces Camel to connect on each poll. | false | boolean
| *handleFailedMessage* (consumer) | If the mail consumer cannot retrieve a
given mail message, then this option allows to handle the caused exception by
the consumer's error handler. By enable the bridge error handler on the
consumer, then the Camel routing error handler can handle the exception
instead. The default behavior would be the consumer throws an exception and no
mails from the batch would be able to be routed by Camel. | false | boolean
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 7637168..8e9a334 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
@@ -76,6 +76,8 @@ public class MailConfiguration implements Cloneable {
private boolean delete;
@UriParam @Metadata(label = "consumer")
private String copyTo;
+ @UriParam @Metadata(label = "consumer")
+ private String moveTo;
@UriParam(defaultValue = "true") @Metadata(label = "consumer")
private boolean unseen = true;
@UriParam(label = "advanced")
@@ -675,6 +677,19 @@ public class MailConfiguration implements Cloneable {
return copyTo;
}
+ public String getMoveTo() {
+ return moveTo;
+ }
+
+ /**
+ * After processing a mail message, it can be moved to a mail folder with
the given name.
+ * You can override this configuration value, with a header with the key
moveTo, allowing you to move messages
+ * to folder names configured at runtime.
+ */
+ public void setMoveTo(String moveTo) {
+ this.moveTo = moveTo;
+ }
+
/**
* After processing a mail message, it can be copied to a mail folder with
the given name.
* You can override this configuration value, with a header with the key
copyTo, allowing you to copy messages
diff --git
a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConsumer.java
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConsumer.java
index aad7939..1945180 100644
---
a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConsumer.java
+++
b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailConsumer.java
@@ -472,27 +472,19 @@ public class MailConsumer extends
ScheduledBatchPollingConsumer {
MailConfiguration config = getEndpoint().getConfiguration();
// header values override configuration values
String copyTo = in.getHeader("copyTo", config.getCopyTo(),
String.class);
+ String moveTo = in.getHeader("moveTo", config.getMoveTo(),
String.class);
boolean delete = in.getHeader("delete", config.isDelete(),
boolean.class);
- // Copy message into different imap folder if asked
- if (config.getProtocol().equals(MailUtils.PROTOCOL_IMAP) ||
config.getProtocol().equals(MailUtils.PROTOCOL_IMAPS)) {
- if (copyTo != null) {
- LOG.trace("IMAP message needs to be copied to {}", copyTo);
- Folder destFolder = store.getFolder(copyTo);
- if (!destFolder.exists()) {
- destFolder.create(Folder.HOLDS_MESSAGES);
- }
- folder.copyMessages(new Message[]{mail}, destFolder);
- LOG.trace("IMAP message {} copied to {}", mail, copyTo);
- }
- }
+ copyOrMoveMessageIfRequired(config, mail, copyTo, false);
if (delete) {
LOG.trace("Exchange processed, so flagging message as
DELETED");
+ copyOrMoveMessageIfRequired(config, mail, moveTo, true);
mail.setFlag(Flags.Flag.DELETED, true);
} else {
LOG.trace("Exchange processed, so flagging message as SEEN");
mail.setFlag(Flags.Flag.SEEN, true);
+ copyOrMoveMessageIfRequired(config, mail, moveTo, true);
}
// need to confirm or remove on commit at last
@@ -509,6 +501,24 @@ public class MailConsumer extends
ScheduledBatchPollingConsumer {
}
}
+
+ private void copyOrMoveMessageIfRequired(MailConfiguration config, Message
mail, String destinationFolder, boolean moveMessage) throws MessagingException {
+ if (config.getProtocol().equals(MailUtils.PROTOCOL_IMAP) ||
config.getProtocol().equals(MailUtils.PROTOCOL_IMAPS)) {
+ if (destinationFolder != null) {
+ LOG.trace("IMAP message needs to be {} to {}", moveMessage ?
"moved" : "copied", destinationFolder);
+ Folder destFolder = store.getFolder(destinationFolder);
+ if (!destFolder.exists()) {
+ destFolder.create(Folder.HOLDS_MESSAGES);
+ }
+ folder.copyMessages(new Message[]{mail}, destFolder);
+ if (moveMessage) {
+ mail.setFlag(Flags.Flag.DELETED, true);
+ }
+ LOG.trace("IMAP message {} {} to {}", mail, moveMessage ?
"moved" : "copied", destinationFolder);
+ }
+ }
+ }
+
/**
* Strategy when processing the exchange failed.
*
diff --git
a/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailMoveToTest.java
b/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailMoveToTest.java
new file mode 100644
index 0000000..83daae5
--- /dev/null
+++
b/components/camel-mail/src/test/java/org/apache/camel/component/mail/MailMoveToTest.java
@@ -0,0 +1,119 @@
+/*
+ * 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 javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.Store;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.jvnet.mock_javamail.Mailbox;
+
+/**
+ * Unit test for moveTo.
+ */
+public class MailMoveToTest extends CamelTestSupport {
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ prepareMailbox();
+ super.setUp();
+ }
+
+ @Test
+ public void testMoveToWithMarkAsSeen() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ mock.expectedMessageCount(5);
+ assertMockEndpointsSatisfied();
+
+ Thread.sleep(500);
+
+ assertEquals(0, Mailbox.get("jones@localhost").size());
+ assertEquals(0, Mailbox.get("jones@localhost").getNewMessageCount());
+ assertEquals(5,
Mailbox.get("moveToFolder-jones@localhost").getNewMessageCount());
+
+
Assert.assertTrue(Mailbox.get("moveToFolder-jones@localhost").get(0).getFlags().contains(Flags.Flag.SEEN));
+
Assert.assertTrue(Mailbox.get("moveToFolder-jones@localhost").get(1).getFlags().contains(Flags.Flag.SEEN));
+
Assert.assertTrue(Mailbox.get("moveToFolder-jones@localhost").get(2).getFlags().contains(Flags.Flag.SEEN));
+
Assert.assertTrue(Mailbox.get("moveToFolder-jones@localhost").get(3).getFlags().contains(Flags.Flag.SEEN));
+
Assert.assertTrue(Mailbox.get("moveToFolder-jones@localhost").get(4).getFlags().contains(Flags.Flag.SEEN));
+ }
+
+ @Test
+ public void testMoveToWithDelete() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:result2");
+ mock.expectedMessageCount(5);
+ assertMockEndpointsSatisfied();
+
+ Thread.sleep(500);
+
+ assertEquals(0, Mailbox.get("jones2@localhost").size());
+ assertEquals(0, Mailbox.get("jones2@localhost").getNewMessageCount());
+ assertEquals(5,
Mailbox.get("moveToFolder-jones2@localhost").getNewMessageCount());
+
+
Assert.assertFalse(Mailbox.get("moveToFolder-jones2@localhost").get(0).getFlags().contains(Flags.Flag.SEEN));
+
Assert.assertFalse(Mailbox.get("moveToFolder-jones2@localhost").get(1).getFlags().contains(Flags.Flag.SEEN));
+
Assert.assertFalse(Mailbox.get("moveToFolder-jones2@localhost").get(2).getFlags().contains(Flags.Flag.SEEN));
+
Assert.assertFalse(Mailbox.get("moveToFolder-jones2@localhost").get(3).getFlags().contains(Flags.Flag.SEEN));
+
Assert.assertFalse(Mailbox.get("moveToFolder-jones2@localhost").get(4).getFlags().contains(Flags.Flag.SEEN));
+ }
+
+ private void prepareMailbox() throws Exception {
+ Mailbox.clearAll();
+ String[] mailUser = new String[] {"jones", "jones2"};
+ for (String username : mailUser) {
+ JavaMailSender sender = new DefaultJavaMailSender();
+ Store store = sender.getSession().getStore("pop3");
+ store.connect("localhost", 25, username, "secret");
+ Folder folder = store.getFolder("INBOX");
+ folder.open(Folder.READ_WRITE);
+ folder.expunge();
+
+ // inserts 5 new messages
+ Message[] messages = new Message[5];
+ for (int i = 0; i < 5; i++) {
+ messages[i] = new MimeMessage(sender.getSession());
+ messages[i].setHeader("Message-ID", "" + i);
+ messages[i].setText("Message " + i);
+ }
+ folder.appendMessages(messages);
+ folder.close(true);
+ }
+ }
+
+ @Override
+ protected RoutesBuilder[] createRouteBuilders() {
+ return new RoutesBuilder[] {new RouteBuilder() {
+ public void configure() throws Exception {
+
from("imap://jones@localhost?password=secret&delete=false&moveTo=moveToFolder&initialDelay=100&delay=100").to("mock:result");
+ }
+ }, new RouteBuilder() {
+ public void configure() throws Exception {
+
from("imap://jones2@localhost?password=secret&delete=true&moveTo=moveToFolder&initialDelay=100&delay=100").to("mock:result2");
+ }
+ } };
+ }
+}