You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/03/01 08:46:51 UTC

[james-project] 03/04: MAILBOX-381 Default DeletedMessagesVault implementation on top of MailRepository

This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit fe27b1332b5e1946bd3b85ad98eb7b2e32f6f91d
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon Feb 25 16:29:41 2019 +0700

    MAILBOX-381 Default DeletedMessagesVault implementation on top of MailRepository
---
 .../vault/MailRepositoryDeletedMessageVault.java   | 129 +++++++++++++++++++++
 .../MailRepositoryDeletedMessageVaultTest.java     |  63 ++++++++++
 2 files changed, 192 insertions(+)

diff --git a/server/mailrepository/deleted-messages-vault-repository/src/main/java/org/apache/james/vault/MailRepositoryDeletedMessageVault.java b/server/mailrepository/deleted-messages-vault-repository/src/main/java/org/apache/james/vault/MailRepositoryDeletedMessageVault.java
new file mode 100644
index 0000000..ff0bf48
--- /dev/null
+++ b/server/mailrepository/deleted-messages-vault-repository/src/main/java/org/apache/james/vault/MailRepositoryDeletedMessageVault.java
@@ -0,0 +1,129 @@
+/****************************************************************
+ * 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.vault;
+
+import java.io.InputStream;
+
+import javax.mail.MessagingException;
+
+import org.apache.james.core.User;
+import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailrepository.api.MailKey;
+import org.apache.james.mailrepository.api.MailRepository;
+import org.apache.james.mailrepository.api.MailRepositoryStore;
+import org.apache.james.mailrepository.api.MailRepositoryUrl;
+import org.apache.james.server.core.MimeMessageInputStream;
+import org.apache.james.util.streams.Iterators;
+import org.apache.james.vault.search.Query;
+import org.reactivestreams.Publisher;
+
+import com.github.fge.lambdas.Throwing;
+import com.google.common.base.Preconditions;
+
+import reactor.core.publisher.Mono;
+import reactor.core.scheduler.Schedulers;
+
+public class MailRepositoryDeletedMessageVault implements DeletedMessageVault {
+    public static class Configuration {
+        private final MailRepositoryUrl urlPrefix;
+
+        public Configuration(MailRepositoryUrl urlPrefix) {
+            this.urlPrefix = urlPrefix;
+        }
+    }
+
+    private final MailRepositoryStore mailRepositoryStore;
+    private final Configuration configuration;
+    private final MailConverter mailConverter;
+
+    public MailRepositoryDeletedMessageVault(MailRepositoryStore mailRepositoryStore, Configuration configuration, MailConverter mailConverter) {
+        this.mailRepositoryStore = mailRepositoryStore;
+        this.configuration = configuration;
+        this.mailConverter = mailConverter;
+    }
+
+    @Override
+    public Publisher<Void> append(User user, DeletedMessage deletedMessage, InputStream inputStream) {
+        Preconditions.checkNotNull(user);
+        Preconditions.checkNotNull(deletedMessage);
+        Preconditions.checkNotNull(inputStream);
+
+        MailRepository mailRepository = repositoryForUser(user);
+
+        return Mono.fromCallable(() -> mailRepository.store(mailConverter.toMail(deletedMessage, inputStream)))
+            .subscribeOn(Schedulers.elastic())
+            .then();
+    }
+
+    @Override
+    public Publisher<Void> delete(User user, MessageId messageId) {
+        Preconditions.checkNotNull(user);
+        Preconditions.checkNotNull(messageId);
+
+        MailRepository mailRepository = repositoryForUser(user);
+        MailKey mailKey = new MailKey(messageId.serialize());
+
+        return Mono.fromRunnable(Throwing.runnable(() -> mailRepository.remove(mailKey)))
+            .subscribeOn(Schedulers.elastic())
+            .then();
+    }
+
+    @Override
+    public Publisher<InputStream> loadMimeMessage(User user, MessageId messageId) {
+        Preconditions.checkNotNull(user);
+        Preconditions.checkNotNull(messageId);
+
+        MailRepository mailRepository = repositoryForUser(user);
+        MailKey mailKey = new MailKey(messageId.serialize());
+
+        return Mono.fromCallable(() -> mailRepository.retrieve(mailKey))
+            .subscribeOn(Schedulers.elastic())
+            .map(Throwing.function(mail -> new MimeMessageInputStream(mail.getMessage())));
+    }
+
+    @Override
+    public Publisher<DeletedMessage> search(User user, Query query) {
+        Preconditions.checkNotNull(user);
+        Preconditions.checkNotNull(query);
+
+        MailRepository mailRepository = repositoryForUser(user);
+
+        try {
+            return Iterators.toFlux(mailRepository.list())
+                .publishOn(Schedulers.elastic())
+                .map(Throwing.function(mailRepository::retrieve))
+                .publishOn(Schedulers.parallel())
+                .map(mailConverter::fromMail)
+                .filter(query.toPredicate());
+        } catch (MessagingException e) {
+            return Mono.error(e);
+        }
+    }
+
+    private MailRepository repositoryForUser(User user) {
+        MailRepositoryUrl mailRepositoryUrl = configuration.urlPrefix.subUrl(user.asString());
+
+        try {
+            return mailRepositoryStore.select(mailRepositoryUrl);
+        } catch (MailRepositoryStore.MailRepositoryStoreException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/server/mailrepository/deleted-messages-vault-repository/src/test/java/org/apache/james/vault/MailRepositoryDeletedMessageVaultTest.java b/server/mailrepository/deleted-messages-vault-repository/src/test/java/org/apache/james/vault/MailRepositoryDeletedMessageVaultTest.java
new file mode 100644
index 0000000..1b83686
--- /dev/null
+++ b/server/mailrepository/deleted-messages-vault-repository/src/test/java/org/apache/james/vault/MailRepositoryDeletedMessageVaultTest.java
@@ -0,0 +1,63 @@
+/****************************************************************
+ * 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.vault;
+
+import org.apache.commons.configuration.HierarchicalConfiguration;
+import org.apache.james.mailbox.inmemory.InMemoryId;
+import org.apache.james.mailbox.inmemory.InMemoryMessageId;
+import org.apache.james.mailrepository.api.MailRepositoryUrl;
+import org.apache.james.mailrepository.api.Protocol;
+import org.apache.james.mailrepository.memory.MailRepositoryStoreConfiguration;
+import org.apache.james.mailrepository.memory.MemoryMailRepository;
+import org.apache.james.mailrepository.memory.MemoryMailRepositoryProvider;
+import org.apache.james.mailrepository.memory.MemoryMailRepositoryStore;
+import org.apache.james.mailrepository.memory.MemoryMailRepositoryUrlStore;
+import org.junit.jupiter.api.BeforeEach;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
+
+public class MailRepositoryDeletedMessageVaultTest implements DeletedMessageVaultContract, DeletedMessageVaultSearchContract.AllContracts {
+
+    private DeletedMessageVault testee;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        MemoryMailRepositoryUrlStore urlStore = new MemoryMailRepositoryUrlStore();
+        MemoryMailRepositoryStore mailRepositoryStore = new MemoryMailRepositoryStore(urlStore, Sets.newHashSet(new MemoryMailRepositoryProvider()));
+
+        mailRepositoryStore.configure(new MailRepositoryStoreConfiguration(
+            ImmutableList.of(new MailRepositoryStoreConfiguration.Item(
+                ImmutableList.of(new Protocol("memory")),
+                MemoryMailRepository.class.getName(),
+                new HierarchicalConfiguration()))));
+        mailRepositoryStore.init();
+
+        testee = new MailRepositoryDeletedMessageVault(
+            mailRepositoryStore,
+            new MailRepositoryDeletedMessageVault.Configuration(MailRepositoryUrl.from("memory://deletedMessages/vault/")),
+            new MailConverter(new InMemoryId.Factory(), new InMemoryMessageId.Factory()));
+    }
+
+    @Override
+    public DeletedMessageVault getVault() {
+        return testee;
+    }
+}
\ 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