JAMES-2285 Move test and fix memory mailqueue to a new module JAMES-2285 Use MailQueue contracts to test FileMailQueue
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/368a5d85 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/368a5d85 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/368a5d85 Branch: refs/heads/master Commit: 368a5d855a80e1674cc59a3dc9af4993495623d6 Parents: 69090be Author: benwa <[email protected]> Authored: Thu Jan 11 14:04:49 2018 +0700 Committer: benwa <[email protected]> Committed: Thu Jan 18 09:48:49 2018 +0700 ---------------------------------------------------------------------- .../org/apache/mailet/PerRecipientHeaders.java | 4 + .../org/apache/mailet/base/test/FakeMail.java | 3 +- pom.xml | 11 ++ .../org/apache/james/server/core/MailImpl.java | 5 + server/container/guice/memory-guice/pom.xml | 4 + .../modules/server/MemoryMailQueueFactory.java | 141 -------------- .../modules/server/MemoryMailQueueModule.java | 1 + .../server/MemoryMailQueueFactoryTest.java | 166 ----------------- server/pom.xml | 1 + server/queue/queue-file/pom.xml | 27 ++- .../james/queue/file/FileMailQueueTest.java | 184 +++++++++++++++++++ server/queue/queue-memory/pom.xml | 73 ++++++++ .../queue/memory/MemoryMailQueueFactory.java | 142 ++++++++++++++ .../memory/MemoryMailQueueFactoryTest.java | 54 ++++++ .../james/queue/memory/MemoryMailQueueTest.java | 40 ++++ 15 files changed, 545 insertions(+), 311 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java ---------------------------------------------------------------------- diff --git a/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java b/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java index 8be1edd..2f2fc83 100644 --- a/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java +++ b/mailet/api/src/main/java/org/apache/mailet/PerRecipientHeaders.java @@ -58,6 +58,10 @@ public class PerRecipientHeaders implements Serializable { headersByRecipient.put(recipient, header); } + public void addAll(PerRecipientHeaders other) { + headersByRecipient.putAll(other.headersByRecipient); + } + public static class Header implements Serializable { private final String name; private final String value; http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMail.java ---------------------------------------------------------------------- diff --git a/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMail.java b/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMail.java index dffd463..0c71c2b 100644 --- a/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMail.java +++ b/mailet/base/src/test/java/org/apache/mailet/base/test/FakeMail.java @@ -416,7 +416,6 @@ public class FakeMail implements Mail, Serializable { FakeMail that = (FakeMail) o; return Objects.equal(this.size, that.size) - && Objects.equal(this.msg, that.msg) && Objects.equal(this.recipients, that.recipients) && Objects.equal(this.name, that.name) && Objects.equal(this.sender, that.sender) @@ -431,7 +430,7 @@ public class FakeMail implements Mail, Serializable { @Override public final int hashCode() { - return Objects.hashCode(msg, name, sender, recipients, state, errorMessage, lastUpdated, attributes, size, recipients, remoteAddr); + return Objects.hashCode(name, sender, recipients, state, errorMessage, lastUpdated, attributes, size, recipients, remoteAddr); } @Override http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index ef865e1..d4988bd 100644 --- a/pom.xml +++ b/pom.xml @@ -1317,6 +1317,17 @@ <version>${project.version}</version> <type>test-jar</type> </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>james-server-queue-memory</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>james-server-queue-memory</artifactId> + <version>${project.version}</version> + <type>test-jar</type> + </dependency> <dependency> <groupId>${project.groupId}</groupId> http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java ---------------------------------------------------------------------- diff --git a/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java b/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java index c586643..4318f3f 100644 --- a/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java +++ b/server/container/core/src/main/java/org/apache/james/server/core/MailImpl.java @@ -243,6 +243,7 @@ public class MailImpl implements Disposable, Mail { setRemoteHost(mail.getRemoteHost()); setRemoteAddr(mail.getRemoteAddr()); setLastUpdated(mail.getLastUpdated()); + setErrorMessage(mail.getErrorMessage()); try { if (mail instanceof MailImpl) { setAttributesRaw((HashMap<String, Object>) cloneSerializableObject(((MailImpl) mail).getAttributesRaw())); @@ -624,4 +625,8 @@ public class MailImpl implements Disposable, Mail { public void addSpecificHeaderForRecipient(Header header, MailAddress recipient) { perRecipientSpecificHeaders.addHeaderForRecipient(header, recipient); } + + public void addAllSpecificHeaderForRecipient(PerRecipientHeaders perRecipientHeaders) { + perRecipientSpecificHeaders.addAll(perRecipientHeaders); + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/server/container/guice/memory-guice/pom.xml ---------------------------------------------------------------------- diff --git a/server/container/guice/memory-guice/pom.xml b/server/container/guice/memory-guice/pom.xml index 828b740..0436ea4 100644 --- a/server/container/guice/memory-guice/pom.xml +++ b/server/container/guice/memory-guice/pom.xml @@ -115,6 +115,10 @@ <artifactId>james-server-guice-webadmin-swagger</artifactId> </dependency> <dependency> + <groupId>org.apache.james</groupId> + <artifactId>james-server-queue-memory</artifactId> + </dependency> + <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</artifactId> </dependency> http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/server/MemoryMailQueueFactory.java ---------------------------------------------------------------------- diff --git a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/server/MemoryMailQueueFactory.java b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/server/MemoryMailQueueFactory.java deleted file mode 100644 index 957c934..0000000 --- a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/server/MemoryMailQueueFactory.java +++ /dev/null @@ -1,141 +0,0 @@ -/**************************************************************** - * 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.james.modules.server; - -import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.TimeUnit; - -import javax.mail.MessagingException; -import javax.mail.internet.MimeMessage; - -import org.apache.james.queue.api.MailQueue; -import org.apache.james.queue.api.MailQueueFactory; -import org.apache.james.queue.api.MailQueueItemDecoratorFactory; -import org.apache.james.server.core.MailImpl; -import org.apache.mailet.Mail; - -import com.github.fge.lambdas.Throwing; -import com.google.common.base.Objects; -import com.google.inject.Inject; - -public class MemoryMailQueueFactory implements MailQueueFactory { - - private final ConcurrentHashMap<String, MailQueue> mailQueues; - private final MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory; - - @Inject - public MemoryMailQueueFactory(MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory) { - this.mailQueues = new ConcurrentHashMap<>(); - this.mailQueueItemDecoratorFactory = mailQueueItemDecoratorFactory; - } - - @Override - public MailQueue getQueue(String name) { - return Optional.ofNullable(mailQueues.get(name)) - .orElseGet(() -> tryInsertNewMailQueue(name)); - } - - private MailQueue tryInsertNewMailQueue(String name) { - MailQueue newMailQueue = new MemoryMailQueue(name, mailQueueItemDecoratorFactory); - return Optional.ofNullable(mailQueues.putIfAbsent(name, newMailQueue)) - .orElse(newMailQueue); - } - - public static class MemoryMailQueue implements MailQueue { - - private final LinkedBlockingDeque<MemoryMailQueueItem> mailItems; - private final MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory; - private final String name; - - public MemoryMailQueue(String name,MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory) { - this.mailItems = new LinkedBlockingDeque<>(); - this.name = name; - this.mailQueueItemDecoratorFactory = mailQueueItemDecoratorFactory; - } - - @Override - public void enQueue(Mail mail, long delay, TimeUnit unit) throws MailQueueException { - enQueue(mail); - } - - @Override - public void enQueue(Mail mail) throws MailQueueException { - try { - mailItems.addFirst(new MemoryMailQueueItem(cloneMail(mail))); - } catch (MessagingException e) { - throw new MailQueueException("Error while copying mail " + mail.getName(), e); - } - } - - private Mail cloneMail(Mail mail) throws MessagingException { - MailImpl mailImpl = MailImpl.duplicate(mail); - mailImpl.setName(mail.getName()); - mailImpl.setState(mail.getState()); - Optional.ofNullable(mail.getMessage()) - .ifPresent(Throwing.consumer(message -> mailImpl.setMessage(new MimeMessage(message)))); - return mailImpl; - } - - @Override - public MailQueueItem deQueue() throws MailQueueException, InterruptedException { - while (true) { - MemoryMailQueueItem item = mailItems.take(); - return mailQueueItemDecoratorFactory.decorate(item); - } - } - - @Override - public boolean equals(Object o) { - if (o == null || getClass() != o.getClass()) { - return false; - } - - MemoryMailQueue that = (MemoryMailQueue) o; - - return Objects.equal(this.name, that.name); - } - - @Override - public int hashCode() { - return Objects.hashCode(name); - } - } - - public static class MemoryMailQueueItem implements MailQueue.MailQueueItem { - - private final Mail mail; - - public MemoryMailQueueItem(Mail mail) { - this.mail = mail; - } - - @Override - public Mail getMail() { - return mail; - } - - @Override - public void done(boolean success) throws MailQueue.MailQueueException { - - } - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/server/MemoryMailQueueModule.java ---------------------------------------------------------------------- diff --git a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/server/MemoryMailQueueModule.java b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/server/MemoryMailQueueModule.java index fe41a1c..c7efca5 100644 --- a/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/server/MemoryMailQueueModule.java +++ b/server/container/guice/memory-guice/src/main/java/org/apache/james/modules/server/MemoryMailQueueModule.java @@ -20,6 +20,7 @@ package org.apache.james.modules.server; import org.apache.james.queue.api.MailQueueFactory; +import org.apache.james.queue.memory.MemoryMailQueueFactory; import com.google.inject.AbstractModule; import com.google.inject.Scopes; http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/server/container/guice/memory-guice/src/test/java/org/apache/james/server/MemoryMailQueueFactoryTest.java ---------------------------------------------------------------------- diff --git a/server/container/guice/memory-guice/src/test/java/org/apache/james/server/MemoryMailQueueFactoryTest.java b/server/container/guice/memory-guice/src/test/java/org/apache/james/server/MemoryMailQueueFactoryTest.java deleted file mode 100644 index 0140f0d..0000000 --- a/server/container/guice/memory-guice/src/test/java/org/apache/james/server/MemoryMailQueueFactoryTest.java +++ /dev/null @@ -1,166 +0,0 @@ -/**************************************************************** - * 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.james.server; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; - -import org.apache.james.modules.server.MemoryMailQueueFactory; -import org.apache.james.queue.api.MailQueue; -import org.apache.james.queue.api.MailQueue.MailQueueItem; -import org.apache.james.queue.api.MailQueueItemDecoratorFactory; -import org.apache.mailet.Mail; -import org.apache.mailet.base.test.FakeMail; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import com.google.common.base.Throwables; - -public class MemoryMailQueueFactoryTest { - - public static final String KEY = "key"; - public static final String BIS = "bis"; - public static final String NAME_1 = "Name1"; - public static final String NAME_2 = "Name2"; - - private MemoryMailQueueFactory memoryMailQueueFactory; - private ExecutorService executorService; - - @Before - public void setUp() { - memoryMailQueueFactory = new MemoryMailQueueFactory(mailQueueItem -> new MailQueueItemDecoratorFactory.MailQueueItemDecorator(mailQueueItem) { - @Override - public Mail getMail() { - return mailQueueItem.getMail(); - } - - @Override - public void done(boolean success) throws MailQueue.MailQueueException { - - } - }); - executorService = Executors.newFixedThreadPool(2); - } - - @After - public void tearDown() { - executorService.shutdownNow(); - } - - @Test - public void getQueueShouldNotReturnNull() { - assertThat(memoryMailQueueFactory.getQueue(KEY)).isNotNull(); - } - - @Test - public void getQueueShouldReturnTwoTimeTheSameResultWhenUsedWithTheSameKey() { - assertThat(memoryMailQueueFactory.getQueue(KEY)).isEqualTo(memoryMailQueueFactory.getQueue(KEY)); - } - - @Test - public void getQueueShouldNotReturnTheSameQueueForTwoDifferentNames() { - assertThat(memoryMailQueueFactory.getQueue(KEY)).isNotEqualTo(memoryMailQueueFactory.getQueue(BIS)); - } - - @Test - public void dequeueShouldWork() throws Exception { - Mail mail = FakeMail.builder() - .name(NAME_1) - .build(); - memoryMailQueueFactory.getQueue(KEY).enQueue(mail); - assertThat(memoryMailQueueFactory.getQueue(KEY).deQueue().getMail().getName()).startsWith(NAME_1); - } - - @Test - public void dequeueShouldPreserveState() throws Exception { - String state = "state"; - Mail mail = FakeMail.builder() - .name(NAME_1) - .state(state) - .build(); - memoryMailQueueFactory.getQueue(KEY).enQueue(mail); - - String newState = memoryMailQueueFactory - .getQueue(KEY) - .deQueue() - .getMail() - .getState(); - - assertThat(newState).isEqualTo(state); - } - - @Test - public void dequeueShouldPreserveName() throws Exception { - Mail mail = FakeMail.builder() - .name(NAME_1) - .build(); - memoryMailQueueFactory.getQueue(KEY).enQueue(mail); - - String newName = memoryMailQueueFactory - .getQueue(KEY) - .deQueue() - .getMail() - .getName(); - - assertThat(newName).isEqualTo(NAME_1); - } - - @Test - public void dequeueShouldWorkWithMultipleMessages() throws Exception { - Mail mail1 = FakeMail.builder() - .name(NAME_1) - .build(); - Mail mail2 = FakeMail.builder() - .name(NAME_2) - .build(); - memoryMailQueueFactory.getQueue(KEY).enQueue(mail1); - memoryMailQueueFactory.getQueue(KEY).enQueue(mail2); - assertThat(memoryMailQueueFactory.getQueue(KEY).deQueue().getMail().getName()).startsWith(NAME_2); - assertThat(memoryMailQueueFactory.getQueue(KEY).deQueue().getMail().getName()).startsWith(NAME_1); - } - - @Test(timeout = 20000) - public void deQueueShouldWaitForAMailToBeEnqueued() throws Exception { - CountDownLatch latch = new CountDownLatch(1); - Mail mail = FakeMail.builder() - .name(NAME_1) - .build(); - executorService.submit(() -> { - try { - latch.await(); - memoryMailQueueFactory.getQueue(KEY).enQueue(mail); - } catch (Exception e) { - throw Throwables.propagate(e); - } - }); - Future<MailQueueItem> tryDequeue = executorService.submit(() -> memoryMailQueueFactory.getQueue(KEY).deQueue()); - assertThatThrownBy(() -> tryDequeue.get(100, TimeUnit.MILLISECONDS)).isInstanceOf(TimeoutException.class); - latch.countDown(); - assertThat(tryDequeue.get().getMail().getName()).startsWith(NAME_1); - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/server/pom.xml ---------------------------------------------------------------------- diff --git a/server/pom.xml b/server/pom.xml index 11693e3..f586a1a 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -99,6 +99,7 @@ <module>queue/queue-api</module> <module>queue/queue-file</module> <module>queue/queue-jms</module> + <module>queue/queue-memory</module> <module>task</module> <module>testing</module> http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/server/queue/queue-file/pom.xml ---------------------------------------------------------------------- diff --git a/server/queue/queue-file/pom.xml b/server/queue/queue-file/pom.xml index 6bf7d66..95015ca 100644 --- a/server/queue/queue-file/pom.xml +++ b/server/queue/queue-file/pom.xml @@ -35,6 +35,12 @@ <dependencies> <dependency> <groupId>${project.groupId}</groupId> + <artifactId>apache-mailet-base</artifactId> + <scope>test</scope> + <type>test-jar</type> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> <artifactId>james-server-core</artifactId> </dependency> <dependency> @@ -43,6 +49,12 @@ </dependency> <dependency> <groupId>${project.groupId}</groupId> + <artifactId>james-server-filesystem-api</artifactId> + <scope>test</scope> + <type>test-jar</type> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> <artifactId>james-server-lifecycle-api</artifactId> </dependency> <dependency> @@ -50,6 +62,12 @@ <artifactId>james-server-queue-api</artifactId> </dependency> <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>james-server-queue-api</artifactId> + <scope>test</scope> + <type>test-jar</type> + </dependency> + <dependency> <groupId>com.sun.mail</groupId> <artifactId>javax.mail</artifactId> </dependency> @@ -58,8 +76,13 @@ <artifactId>javax.inject</artifactId> </dependency> <dependency> - <groupId>org.junit.vintage</groupId> - <artifactId>junit-vintage-engine</artifactId> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> <scope>test</scope> </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/server/queue/queue-file/src/test/java/org/apache/james/queue/file/FileMailQueueTest.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-file/src/test/java/org/apache/james/queue/file/FileMailQueueTest.java b/server/queue/queue-file/src/test/java/org/apache/james/queue/file/FileMailQueueTest.java new file mode 100644 index 0000000..7c2e25e --- /dev/null +++ b/server/queue/queue-file/src/test/java/org/apache/james/queue/file/FileMailQueueTest.java @@ -0,0 +1,184 @@ +/**************************************************************** + * 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.james.queue.file; + +import org.apache.james.queue.api.DelayedManageableMailQueueContract; +import org.apache.james.queue.api.MailQueue; +import org.apache.james.queue.api.ManageableMailQueue; +import org.apache.james.queue.api.RawMailQueueItemDecoratorFactory; +import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; +import org.junit.rules.TemporaryFolder; + +public class FileMailQueueTest implements DelayedManageableMailQueueContract { + private static final boolean SYNC = true; + + private TemporaryFolder temporaryFolder = new TemporaryFolder(); + private FileMailQueue mailQueue; + + @AfterEach + void teardown() { + temporaryFolder.delete(); + } + + @BeforeEach + public void setUp() throws Exception { + temporaryFolder.create(); + mailQueue = new FileMailQueue(new RawMailQueueItemDecoratorFactory(), temporaryFolder.newFolder(), "test", SYNC); + } + + @Override + public MailQueue getMailQueue() { + return mailQueue; + } + + @Override + public ManageableMailQueue getManageableMailQueue() { + return mailQueue; + } + + @Test + @Override + @Disabled("JAMES-2300 No Order") + public void browseShouldReturnElementsInOrder() { + + } + + @Test + @Override + @Disabled("JAMES-2300 No Order") + public void flushShouldPreserveBrowseOrder() { + + } + + @Test + @Override + @Disabled("JAMES-2299 No snapshot isolation") + public void concurrentClearShouldNotAlterBrowsingWhenDequeueWhileIterating() { + + } + + @Test + @Override + @Disabled("JAMES-2299 No snapshot isolation") + public void concurrentClearShouldNotAlterBrowsingWhenDequeue() { + + } + + @Test + @Override + @Disabled("JAMES-2299 No snapshot isolation") + public void concurrentDequeueShouldNotAlterBrowsing() { + + } + + @Test + @Override + @Disabled("JAMES-2299 No snapshot isolation") + public void concurrentEnqueueShouldNotAlterBrowsing() { + + } + + @Test + @Override + @Disabled("JAMES-2299 No snapshot isolation") + public void concurrentDequeueShouldNotAlterBrowsingWhenDequeueWhileIterating() { + + } + + @Test + @Override + @Disabled("JAMES-2299 No snapshot isolation") + public void concurrentEnqueueShouldNotAlterBrowsingWhenDequeueWhileIterating() { + + } + + @Test + @Override + @Disabled("JAMES-2299 No snapshot isolation") + public void concurrentRemoveShouldNotAlterBrowsingWhenDequeueWhileIterating() { + + } + + @Test + @Override + @Disabled("JAMES-2299 No snapshot isolation") + public void concurrentFlushShouldNotAlterBrowsingWhenDequeueWhileIterating() { + + } + + @Test + @Override + @Disabled("JAMES-2299 No snapshot isolation") + public void concurrentFlushShouldNotAlterBrowsing() { + + } + + @Test + @Override + @Disabled("JAMES-2299 No snapshot isolation") + public void concurrentRemoveShouldNotAlterBrowsingWhenDequeue() { + + } + + @Test + @Override + @Disabled("JAMES-2298 Not supported yet") + public void removeBySenderShouldRemoveSpecificEmail() { + + } + + @Test + @Override + @Disabled("JAMES-2298 Not supported yet") + public void removeByNameShouldRemoveSpecificEmail() { + + } + + @Test + @Override + @Disabled("JAMES-2298 Not supported yet") + public void removeByRecipientShouldRemoveSpecificEmail() { + + } + + @Test + @Override + @Disabled("JAMES-2298 Not supported yet") + public void removeByRecipientShouldNotFailWhenQueueIsEmpty() { + + } + + @Test + @Override + @Disabled("JAMES-2298 Not supported yet") + public void removeBySenderShouldNotFailWhenQueueIsEmpty() { + + } + + @Test + @Override + @Disabled("JAMES-2298 Not supported yet") + public void removeByRecipientShouldRemoveSpecificEmailWhenMultipleRecipients() { + + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/server/queue/queue-memory/pom.xml ---------------------------------------------------------------------- diff --git a/server/queue/queue-memory/pom.xml b/server/queue/queue-memory/pom.xml new file mode 100644 index 0000000..9e8af0b --- /dev/null +++ b/server/queue/queue-memory/pom.xml @@ -0,0 +1,73 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <artifactId>james-server</artifactId> + <groupId>org.apache.james</groupId> + <version>3.1.0-SNAPSHOT</version> + <relativePath>../../pom.xml</relativePath> + </parent> + + <artifactId>james-server-queue-memory</artifactId> + + <name>Apache James :: Server :: Mail Queue :: Memory</name> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>apache-mailet-api</artifactId> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>apache-mailet-base</artifactId> + <scope>test</scope> + <type>test-jar</type> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>james-server-core</artifactId> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>james-server-queue-api</artifactId> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>james-server-queue-api</artifactId> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> + <groupId>com.sun.mail</groupId> + <artifactId>javax.mail</artifactId> + </dependency> + <dependency> + <groupId>javax.inject</groupId> + <artifactId>javax.inject</artifactId> + </dependency> + <dependency> + <groupId>org.assertj</groupId> + <artifactId>assertj-core</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.junit.vintage</groupId> + <artifactId>junit-vintage-engine</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + +</project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/server/queue/queue-memory/src/main/java/org/apache/james/queue/memory/MemoryMailQueueFactory.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-memory/src/main/java/org/apache/james/queue/memory/MemoryMailQueueFactory.java b/server/queue/queue-memory/src/main/java/org/apache/james/queue/memory/MemoryMailQueueFactory.java new file mode 100644 index 0000000..3a81099 --- /dev/null +++ b/server/queue/queue-memory/src/main/java/org/apache/james/queue/memory/MemoryMailQueueFactory.java @@ -0,0 +1,142 @@ +/**************************************************************** + * 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.james.queue.memory; + +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.TimeUnit; + +import javax.inject.Inject; +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; + +import org.apache.james.queue.api.MailQueue; +import org.apache.james.queue.api.MailQueueFactory; +import org.apache.james.queue.api.MailQueueItemDecoratorFactory; +import org.apache.james.server.core.MailImpl; +import org.apache.mailet.Mail; + +import com.github.fge.lambdas.Throwing; +import com.google.common.base.Objects; + +public class MemoryMailQueueFactory implements MailQueueFactory { + + private final ConcurrentHashMap<String, MailQueue> mailQueues; + private final MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory; + + @Inject + public MemoryMailQueueFactory(MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory) { + this.mailQueues = new ConcurrentHashMap<>(); + this.mailQueueItemDecoratorFactory = mailQueueItemDecoratorFactory; + } + + @Override + public MailQueue getQueue(String name) { + return Optional.ofNullable(mailQueues.get(name)) + .orElseGet(() -> tryInsertNewMailQueue(name)); + } + + private MailQueue tryInsertNewMailQueue(String name) { + MailQueue newMailQueue = new MemoryMailQueue(name, mailQueueItemDecoratorFactory); + return Optional.ofNullable(mailQueues.putIfAbsent(name, newMailQueue)) + .orElse(newMailQueue); + } + + public static class MemoryMailQueue implements MailQueue { + + private final LinkedBlockingDeque<MemoryMailQueueItem> mailItems; + private final MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory; + private final String name; + + public MemoryMailQueue(String name,MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory) { + this.mailItems = new LinkedBlockingDeque<>(); + this.name = name; + this.mailQueueItemDecoratorFactory = mailQueueItemDecoratorFactory; + } + + @Override + public void enQueue(Mail mail, long delay, TimeUnit unit) throws MailQueueException { + enQueue(mail); + } + + @Override + public void enQueue(Mail mail) throws MailQueueException { + try { + mailItems.addFirst(new MemoryMailQueueItem(cloneMail(mail))); + } catch (MessagingException e) { + throw new MailQueueException("Error while copying mail " + mail.getName(), e); + } + } + + private Mail cloneMail(Mail mail) throws MessagingException { + MailImpl mailImpl = MailImpl.duplicate(mail); + mailImpl.setName(mail.getName()); + mailImpl.setState(mail.getState()); + mailImpl.addAllSpecificHeaderForRecipient(mail.getPerRecipientSpecificHeaders()); + Optional.ofNullable(mail.getMessage()) + .ifPresent(Throwing.consumer(message -> mailImpl.setMessage(new MimeMessage(message)))); + return mailImpl; + } + + @Override + public MailQueueItem deQueue() throws MailQueueException, InterruptedException { + while (true) { + MemoryMailQueueItem item = mailItems.takeLast(); + return mailQueueItemDecoratorFactory.decorate(item); + } + } + + @Override + public boolean equals(Object o) { + if (o == null || getClass() != o.getClass()) { + return false; + } + + MemoryMailQueue that = (MemoryMailQueue) o; + + return Objects.equal(this.name, that.name); + } + + @Override + public int hashCode() { + return Objects.hashCode(name); + } + } + + public static class MemoryMailQueueItem implements MailQueue.MailQueueItem { + + private final Mail mail; + + public MemoryMailQueueItem(Mail mail) { + this.mail = mail; + } + + @Override + public Mail getMail() { + return mail; + } + + @Override + public void done(boolean success) throws MailQueue.MailQueueException { + + } + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/server/queue/queue-memory/src/test/java/org/apache/james/queue/memory/MemoryMailQueueFactoryTest.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-memory/src/test/java/org/apache/james/queue/memory/MemoryMailQueueFactoryTest.java b/server/queue/queue-memory/src/test/java/org/apache/james/queue/memory/MemoryMailQueueFactoryTest.java new file mode 100644 index 0000000..e4fa1e3 --- /dev/null +++ b/server/queue/queue-memory/src/test/java/org/apache/james/queue/memory/MemoryMailQueueFactoryTest.java @@ -0,0 +1,54 @@ +/**************************************************************** + * 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.james.queue.memory; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.apache.james.queue.api.RawMailQueueItemDecoratorFactory; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class MemoryMailQueueFactoryTest { + + private static final String KEY = "key"; + private static final String BIS = "keyBis"; + + private MemoryMailQueueFactory memoryMailQueueFactory; + + @BeforeEach + public void setUp() { + memoryMailQueueFactory = new MemoryMailQueueFactory(new RawMailQueueItemDecoratorFactory()); + } + + @Test + public void getQueueShouldNotReturnNull() { + assertThat(memoryMailQueueFactory.getQueue(KEY)).isNotNull(); + } + + @Test + public void getQueueShouldReturnTwoTimeTheSameResultWhenUsedWithTheSameKey() { + assertThat(memoryMailQueueFactory.getQueue(KEY)).isEqualTo(memoryMailQueueFactory.getQueue(KEY)); + } + + @Test + public void getQueueShouldNotReturnTheSameQueueForTwoDifferentNames() { + assertThat(memoryMailQueueFactory.getQueue(KEY)).isNotEqualTo(memoryMailQueueFactory.getQueue(BIS)); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/368a5d85/server/queue/queue-memory/src/test/java/org/apache/james/queue/memory/MemoryMailQueueTest.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-memory/src/test/java/org/apache/james/queue/memory/MemoryMailQueueTest.java b/server/queue/queue-memory/src/test/java/org/apache/james/queue/memory/MemoryMailQueueTest.java new file mode 100644 index 0000000..0c798a3 --- /dev/null +++ b/server/queue/queue-memory/src/test/java/org/apache/james/queue/memory/MemoryMailQueueTest.java @@ -0,0 +1,40 @@ +/**************************************************************** + * 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.james.queue.memory; + +import org.apache.james.queue.api.MailQueue; +import org.apache.james.queue.api.MailQueueContract; +import org.apache.james.queue.api.RawMailQueueItemDecoratorFactory; +import org.junit.jupiter.api.BeforeEach; + +public class MemoryMailQueueTest implements MailQueueContract { + + private MemoryMailQueueFactory.MemoryMailQueue mailQueue; + + @BeforeEach + public void setUp() { + mailQueue = new MemoryMailQueueFactory.MemoryMailQueue("test", new RawMailQueueItemDecoratorFactory()); + } + + @Override + public MailQueue getMailQueue() { + return mailQueue; + } +} --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
