james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From btell...@apache.org
Subject [3/5] james-project git commit: JAMES-2550 Enable MailQueueView API to support delete
Date Fri, 28 Sep 2018 02:10:44 GMT
JAMES-2550 Enable MailQueueView API to support delete

We define a generic DeleteCondition for this purpose


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/38189c0c
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/38189c0c
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/38189c0c

Branch: refs/heads/master
Commit: 38189c0cc84645d8f89e40b73aec5b2626191750
Parents: 3e7fa65
Author: Benoit Tellier <btellier@linagora.com>
Authored: Thu Sep 13 11:12:25 2018 +0700
Committer: Benoit Tellier <btellier@linagora.com>
Committed: Fri Sep 28 09:07:50 2018 +0700

----------------------------------------------------------------------
 .../apache/james/queue/rabbitmq/Dequeuer.java   |   3 +-
 .../rabbitmq/view/api/DeleteCondition.java      | 171 +++++++++++++
 .../queue/rabbitmq/view/api/MailQueueView.java  |   4 +-
 .../view/cassandra/CassandraMailQueueView.java  |  18 +-
 .../rabbitmq/view/api/DeleteConditionTest.java  | 253 +++++++++++++++++++
 5 files changed, 442 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/38189c0c/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/Dequeuer.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/Dequeuer.java
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/Dequeuer.java
index 81f4c61..4354a50 100644
--- a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/Dequeuer.java
+++ b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/Dequeuer.java
@@ -30,6 +30,7 @@ import java.util.function.Function;
 import org.apache.james.metrics.api.Metric;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.queue.api.MailQueue;
+import org.apache.james.queue.rabbitmq.view.api.DeleteCondition;
 import org.apache.james.queue.rabbitmq.view.api.MailQueueView;
 import org.apache.mailet.Mail;
 
@@ -100,7 +101,7 @@ class Dequeuer {
                 if (success) {
                     dequeueMetric.increment();
                     rabbitClient.ack(deliveryTag);
-                    mailQueueView.deleteMail(mail).join();
+                    mailQueueView.delete(DeleteCondition.withName(mail.getName())).join();
                 } else {
                     rabbitClient.nack(deliveryTag);
                 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/38189c0c/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/api/DeleteCondition.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/api/DeleteCondition.java
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/api/DeleteCondition.java
new file mode 100644
index 0000000..33ad227
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/api/DeleteCondition.java
@@ -0,0 +1,171 @@
+/****************************************************************
+ * 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.rabbitmq.view.api;
+
+import java.util.Objects;
+
+import org.apache.commons.lang3.NotImplementedException;
+import org.apache.james.queue.api.ManageableMailQueue;
+import org.apache.mailet.Mail;
+
+import com.google.common.base.Preconditions;
+
+public interface DeleteCondition {
+    boolean shouldBeDeleted(Mail mail);
+
+    class All implements DeleteCondition {
+        @Override
+        public boolean shouldBeDeleted(Mail mail) {
+            Preconditions.checkNotNull(mail);
+            return true;
+        }
+
+        @Override
+        public final boolean equals(Object obj) {
+            return obj instanceof All;
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hashCode(All.class);
+        }
+    }
+
+    class WithSender implements DeleteCondition {
+        private final String senderAsString;
+
+        private WithSender(String senderAsString) {
+            this.senderAsString = senderAsString;
+        }
+
+        @Override
+        public boolean shouldBeDeleted(Mail mail) {
+            Preconditions.checkNotNull(mail);
+            return mail.getSender().asString().equals(senderAsString);
+        }
+
+        @Override
+        public final boolean equals(Object obj) {
+            if (obj instanceof WithSender) {
+                WithSender that = (WithSender) obj;
+
+                return Objects.equals(this.senderAsString, that.senderAsString);
+            }
+            return false;
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hashCode(senderAsString);
+        }
+    }
+
+    class WithName implements DeleteCondition {
+        private final String name;
+
+        private WithName(String name) {
+            this.name = name;
+        }
+
+        @Override
+        public boolean shouldBeDeleted(Mail mail) {
+            Preconditions.checkNotNull(mail);
+            return mail.getName().equals(name);
+        }
+
+        @Override
+        public final boolean equals(Object obj) {
+            if (obj instanceof WithName) {
+                WithName that = (WithName) obj;
+
+                return Objects.equals(this.name, that.name);
+            }
+            return false;
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hashCode(name);
+        }
+    }
+
+    class WithRecipient implements DeleteCondition {
+        private final String recipientAsString;
+
+        private WithRecipient(String recipientAsString) {
+            this.recipientAsString = recipientAsString;
+        }
+
+        @Override
+        public boolean shouldBeDeleted(Mail mail) {
+            Preconditions.checkNotNull(mail);
+            return mail.getRecipients()
+                .stream()
+                .anyMatch(mailAddress -> mailAddress.asString().equals(recipientAsString));
+        }
+
+        @Override
+        public final boolean equals(Object obj) {
+            if (obj instanceof WithRecipient) {
+                WithRecipient that = (WithRecipient) obj;
+
+                return Objects.equals(this.recipientAsString, that.recipientAsString);
+            }
+            return false;
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hashCode(recipientAsString);
+        }
+    }
+
+    static DeleteCondition from(ManageableMailQueue.Type deletionType, String value) {
+        switch (deletionType) {
+            case Name:
+                return withName(value);
+            case Sender:
+                return withSender(value);
+            case Recipient:
+                return withRecipient(value);
+            default:
+                throw new NotImplementedException(deletionType + " is not handled");
+        }
+    }
+
+    static WithRecipient withRecipient(String value) {
+        Preconditions.checkNotNull(value);
+        return new WithRecipient(value);
+    }
+
+    static WithSender withSender(String value) {
+        Preconditions.checkNotNull(value);
+        return new WithSender(value);
+    }
+
+    static WithName withName(String value) {
+        Preconditions.checkNotNull(value);
+        return new WithName(value);
+    }
+
+    static DeleteCondition all() {
+        return new All();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/38189c0c/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/api/MailQueueView.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/api/MailQueueView.java
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/api/MailQueueView.java
index 0455ff8..35740d7 100644
--- a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/api/MailQueueView.java
+++ b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/api/MailQueueView.java
@@ -32,7 +32,9 @@ public interface MailQueueView {
 
     CompletableFuture<Void> storeMail(Instant enqueuedTime, Mail mail);
 
-    CompletableFuture<Void> deleteMail(Mail mail);
+    CompletableFuture<Long> delete(DeleteCondition deleteCondition);
+
+    CompletableFuture<Boolean> isPresent(Mail mail);
 
     ManageableMailQueue.MailQueueIterator browse();
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/38189c0c/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/CassandraMailQueueView.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/CassandraMailQueueView.java
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/CassandraMailQueueView.java
index 1876f88..5cd37c6 100644
--- a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/CassandraMailQueueView.java
+++ b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/view/cassandra/CassandraMailQueueView.java
@@ -24,8 +24,10 @@ import java.util.concurrent.CompletableFuture;
 
 import javax.inject.Inject;
 
+import org.apache.commons.lang.NotImplementedException;
 import org.apache.james.queue.api.ManageableMailQueue;
 import org.apache.james.queue.rabbitmq.MailQueueName;
+import org.apache.james.queue.rabbitmq.view.api.DeleteCondition;
 import org.apache.james.queue.rabbitmq.view.api.MailQueueView;
 import org.apache.mailet.Mail;
 
@@ -78,11 +80,6 @@ public class CassandraMailQueueView implements MailQueueView {
     }
 
     @Override
-    public CompletableFuture<Void> deleteMail(Mail mail) {
-        return cassandraMailQueueMailDelete.considerDeleted(mail, mailQueueName);
-    }
-
-    @Override
     public ManageableMailQueue.MailQueueIterator browse() {
         return new CassandraMailQueueBrowser.CassandraMailQueueIterator(
             cassandraMailQueueBrowser.browse(mailQueueName)
@@ -94,4 +91,15 @@ public class CassandraMailQueueView implements MailQueueView {
     public long getSize() {
         return Iterators.size(browse());
     }
+
+    @Override
+    public CompletableFuture<Long> delete(DeleteCondition deleteCondition) {
+        throw new NotImplementedException("Not implemented yet");
+    }
+
+
+    @Override
+    public CompletableFuture<Boolean> isDeleted(Mail mail) {
+        throw new NotImplementedException("Not implemented yet");
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/38189c0c/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/api/DeleteConditionTest.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/api/DeleteConditionTest.java
b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/api/DeleteConditionTest.java
new file mode 100644
index 0000000..8e743b6
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/view/api/DeleteConditionTest.java
@@ -0,0 +1,253 @@
+/****************************************************************
+ * 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.rabbitmq.view.api;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.apache.james.core.MailAddress;
+import org.apache.james.queue.api.ManageableMailQueue;
+import org.apache.mailet.base.test.FakeMail;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+class DeleteConditionTest {
+    private static final String ADDRESS = "any@toto.com";
+    private static final String ADDRESS_2 = "any2@toto.com";
+    private static final String NAME = "name";
+    private static final String VALUE = "value";
+
+    @Nested
+    class AllTest {
+        @Test
+        void allShouldReturnTrue() throws Exception {
+            assertThat(
+                DeleteCondition.all()
+                    .shouldBeDeleted(FakeMail.builder().build()))
+                .isTrue();
+        }
+
+        @Test
+        void allShouldThrowWhenNull() {
+            assertThatThrownBy(() ->
+                DeleteCondition.all()
+                    .shouldBeDeleted(null))
+                .isInstanceOf(NullPointerException.class);
+        }
+
+        @Test
+        void shouldMatchBeanContract() {
+            EqualsVerifier.forClass(DeleteCondition.All.class).verify();
+        }
+    }
+
+    @Nested
+    class WithSenderTest {
+        @Test
+        void withSenderShouldThrowOnNullCondition() {
+            assertThatThrownBy(() ->
+                DeleteCondition.withSender(null))
+                .isInstanceOf(NullPointerException.class);
+        }
+
+        @Test
+        void withSenderShouldThrowOnNullMail() {
+            assertThatThrownBy(() ->
+                DeleteCondition.withSender(ADDRESS)
+                    .shouldBeDeleted(null))
+                .isInstanceOf(NullPointerException.class);
+        }
+
+        @Test
+        void withSenderShouldReturnTrueWhenSameAddress() throws Exception {
+            assertThat(
+                DeleteCondition.withSender(ADDRESS)
+                    .shouldBeDeleted(FakeMail.builder()
+                        .sender(ADDRESS)
+                        .build()))
+                .isTrue();
+        }
+
+        @Test
+        void withSenderShouldReturnFalseWhenDifferentAddress() throws Exception {
+            assertThat(
+                DeleteCondition.withSender(ADDRESS)
+                    .shouldBeDeleted(FakeMail.builder()
+                        .sender(ADDRESS_2)
+                        .recipient(ADDRESS)
+                        .build()))
+                .isFalse();
+        }
+
+        @Test
+        void withSenderShouldNotThrowOnNullSender() throws Exception {
+            assertThat(
+                DeleteCondition.withSender(ADDRESS)
+                    .shouldBeDeleted(FakeMail.builder()
+                        .sender(MailAddress.nullSender())
+                        .build()))
+                .isFalse();
+        }
+
+        @Test
+        void withSenderShouldAllowNullSenderMatchingNullSender() throws Exception {
+            assertThat(
+                DeleteCondition.withSender(MailAddress.NULL_SENDER_AS_STRING)
+                    .shouldBeDeleted(FakeMail.builder()
+                        .sender(MailAddress.nullSender())
+                        .build()))
+                .isTrue();
+        }
+
+        @Test
+        void shouldMatchBeanContract() {
+            EqualsVerifier.forClass(DeleteCondition.WithSender.class).verify();
+        }
+    }
+
+    @Nested
+    class WithNameTest {
+        @Test
+        void withNameShouldThrowOnNullCondition() {
+            assertThatThrownBy(() ->
+                DeleteCondition.withName(null))
+                .isInstanceOf(NullPointerException.class);
+        }
+
+        @Test
+        void withNameShouldThrowOnNullMail() {
+            assertThatThrownBy(() ->
+                DeleteCondition.withName(NAME)
+                    .shouldBeDeleted(null))
+                .isInstanceOf(NullPointerException.class);
+        }
+
+        @Test
+        void withNameShouldReturnTrueWhenSameName() throws Exception {
+            assertThat(
+                DeleteCondition.withName(NAME)
+                    .shouldBeDeleted(FakeMail.builder()
+                        .name(NAME)
+                        .build()))
+                .isTrue();
+        }
+
+        @Test
+        void withSenderShouldReturnFalseWhenDifferentAddress() throws Exception {
+            assertThat(
+                DeleteCondition.withName(NAME)
+                    .shouldBeDeleted(FakeMail.builder()
+                        .name("other")
+                        .build()))
+                .isFalse();
+        }
+
+        @Test
+        void shouldMatchBeanContract() {
+            EqualsVerifier.forClass(DeleteCondition.WithName.class).verify();
+        }
+    }
+
+    @Nested
+    class WithRecipientTest {
+        @Test
+        void withRecipientShouldThrowOnNullCondition() {
+            assertThatThrownBy(() ->
+                DeleteCondition.withRecipient(null))
+                .isInstanceOf(NullPointerException.class);
+        }
+
+        @Test
+        void withRecipientShouldThrowOnNullMail() {
+            assertThatThrownBy(() ->
+                DeleteCondition.withRecipient(ADDRESS)
+                    .shouldBeDeleted(null))
+                .isInstanceOf(NullPointerException.class);
+        }
+
+        @Test
+        void withRecipientShouldReturnTrueWhenSameAddress() throws Exception {
+            assertThat(
+                DeleteCondition.withRecipient(ADDRESS)
+                    .shouldBeDeleted(FakeMail.builder()
+                        .recipient(ADDRESS)
+                        .build()))
+                .isTrue();
+        }
+
+        @Test
+        void withRecipientShouldReturnTrueWhenAtListOneMatches() throws Exception {
+            assertThat(
+                DeleteCondition.withRecipient(ADDRESS)
+                    .shouldBeDeleted(FakeMail.builder()
+                        .recipients(ADDRESS, ADDRESS_2)
+                        .build()))
+                .isTrue();
+        }
+
+        @Test
+        void withRecipientShouldReturnFalseWhenDifferentAddress() throws Exception {
+            assertThat(
+                DeleteCondition.withRecipient(ADDRESS)
+                    .shouldBeDeleted(FakeMail.builder()
+                        .sender(ADDRESS)
+                        .recipient(ADDRESS_2)
+                        .build()))
+                .isFalse();
+        }
+
+        @Test
+        void withRecipientShouldReturnFalseWhenNoRecipient() throws Exception {
+            assertThat(
+                DeleteCondition.withRecipient(ADDRESS)
+                    .shouldBeDeleted(FakeMail.builder()
+                        .build()))
+                .isFalse();
+        }
+
+        @Test
+        void shouldMatchBeanContract() {
+            EqualsVerifier.forClass(DeleteCondition.WithRecipient.class).verify();
+        }
+    }
+
+    @Nested
+    class ConvertTest {
+        @Test
+        void senderShouldBeConvertedToWithSender() {
+            assertThat(DeleteCondition.from(ManageableMailQueue.Type.Sender, VALUE))
+                .isEqualTo(DeleteCondition.withSender(VALUE));
+        }
+
+        @Test
+        void recipientShouldBeConvertedToWithRecipient() {
+            assertThat(DeleteCondition.from(ManageableMailQueue.Type.Recipient, VALUE))
+                .isEqualTo(DeleteCondition.withRecipient(VALUE));
+        }
+
+        @Test
+        void nameShouldBeConvertedToWithName() {
+            assertThat(DeleteCondition.from(ManageableMailQueue.Type.Name, VALUE))
+                .isEqualTo(DeleteCondition.withName(VALUE));
+        }
+    }
+}
\ No newline at end of file


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Mime
View raw message