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 f5644bd231ea1c83b2b1d2522951443803a775d3
Author: Benoit Tellier <btell...@linagora.com>
AuthorDate: Thu Jul 4 15:16:45 2019 +0200

    JAMES-2809 Implement a BlobStore based version of the DeletedMessageVault
    
    Not supported operations:
     - retention: will be implemented in JAMES-2811
     - delete: will be implemented later
     - userWithVault: this not generic enough operation will be refactored
     out of the contract
---
 mailbox/plugin/deleted-messages-vault/pom.xml      |   5 +
 .../vault/blob/BlobStoreDeletedMessageVault.java   |  99 +++++++++++++++
 .../james/vault/blob/BucketNameGenerator.java      |  40 ++++++
 .../blob/BlobStoreDeletedMessageVaultTest.java     | 134 +++++++++++++++++++++
 .../james/vault/blob/BucketNameGeneratorTest.java  |  48 ++++++++
 5 files changed, 326 insertions(+)

diff --git a/mailbox/plugin/deleted-messages-vault/pom.xml 
b/mailbox/plugin/deleted-messages-vault/pom.xml
index f7bff9c..8d973c0 100644
--- a/mailbox/plugin/deleted-messages-vault/pom.xml
+++ b/mailbox/plugin/deleted-messages-vault/pom.xml
@@ -82,6 +82,11 @@
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>blob-memory</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-server-core</artifactId>
         </dependency>
         <dependency>
diff --git 
a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/blob/BlobStoreDeletedMessageVault.java
 
b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/blob/BlobStoreDeletedMessageVault.java
new file mode 100644
index 0000000..4f5aa16
--- /dev/null
+++ 
b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/blob/BlobStoreDeletedMessageVault.java
@@ -0,0 +1,99 @@
+/****************************************************************
+ * 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.blob;
+
+import java.io.InputStream;
+
+import org.apache.commons.lang3.NotImplementedException;
+import org.apache.james.blob.api.BlobStore;
+import org.apache.james.blob.api.BucketName;
+import org.apache.james.core.User;
+import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.task.Task;
+import org.apache.james.vault.DeletedMessage;
+import org.apache.james.vault.DeletedMessageVault;
+import org.apache.james.vault.metadata.DeletedMessageMetadataVault;
+import org.apache.james.vault.metadata.DeletedMessageWithStorageInformation;
+import org.apache.james.vault.metadata.StorageInformation;
+import org.apache.james.vault.search.Query;
+import org.reactivestreams.Publisher;
+
+import com.google.common.base.Preconditions;
+
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+public class BlobStoreDeletedMessageVault implements DeletedMessageVault {
+    private final DeletedMessageMetadataVault messageMetadataVault;
+    private final BlobStore blobStore;
+    private final BucketNameGenerator nameGenerator;
+
+    public BlobStoreDeletedMessageVault(DeletedMessageMetadataVault 
messageMetadataVault, BlobStore blobStore, BucketNameGenerator nameGenerator) {
+        this.messageMetadataVault = messageMetadataVault;
+        this.blobStore = blobStore;
+        this.nameGenerator = nameGenerator;
+    }
+
+    @Override
+    public Publisher<Void> append(User user, DeletedMessage deletedMessage, 
InputStream mimeMessage) {
+        Preconditions.checkNotNull(user);
+        Preconditions.checkNotNull(deletedMessage);
+        Preconditions.checkNotNull(mimeMessage);
+        BucketName bucketName = nameGenerator.currentBucket();
+        return blobStore.save(bucketName, mimeMessage)
+            .map(blobId -> new StorageInformation(bucketName, blobId))
+            .map(storageInformation -> new 
DeletedMessageWithStorageInformation(deletedMessage, storageInformation))
+            .flatMap(message -> Mono.from(messageMetadataVault.store(message)))
+            .then();
+    }
+
+    @Override
+    public Publisher<InputStream> loadMimeMessage(User user, MessageId 
messageId) {
+        Preconditions.checkNotNull(user);
+        Preconditions.checkNotNull(messageId);
+        return Mono.from(messageMetadataVault.retrieveStorageInformation(user, 
messageId))
+            .map(storageInformation -> 
blobStore.read(storageInformation.getBucketName(), 
storageInformation.getBlobId()));
+    }
+
+    @Override
+    public Publisher<DeletedMessage> search(User user, Query query) {
+        Preconditions.checkNotNull(user);
+        Preconditions.checkNotNull(query);
+        return Flux.from(messageMetadataVault.listRelatedBuckets())
+            .concatMap(bucketName -> 
Flux.from(messageMetadataVault.listMessages(bucketName, user)))
+            .map(DeletedMessageWithStorageInformation::getDeletedMessage)
+            .filter(query.toPredicate());
+    }
+
+    @Override
+    public Publisher<Void> delete(User user, MessageId messageId) {
+        throw new NotImplementedException("Will be implemented later");
+    }
+
+    @Override
+    public Publisher<User> usersWithVault() {
+        throw new NotImplementedException("Will be implemented later");
+    }
+
+    @Override
+    public Task deleteExpiredMessagesTask() {
+        throw new NotImplementedException("Will be implemented later");
+    }
+}
diff --git 
a/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/blob/BucketNameGenerator.java
 
b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/blob/BucketNameGenerator.java
new file mode 100644
index 0000000..37931a2
--- /dev/null
+++ 
b/mailbox/plugin/deleted-messages-vault/src/main/java/org/apache/james/vault/blob/BucketNameGenerator.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.vault.blob;
+
+import java.time.Clock;
+import java.time.ZonedDateTime;
+
+import org.apache.james.blob.api.BucketName;
+
+public class BucketNameGenerator {
+    private final Clock clock;
+
+    public BucketNameGenerator(Clock clock) {
+        this.clock = clock;
+    }
+
+    public BucketName currentBucket() {
+        ZonedDateTime now = ZonedDateTime.now(clock);
+        int month = now.getMonthValue();
+        int year = now.getYear();
+        return BucketName.of(String.format("deletedMessages-%d-%02d-01", year, 
month));
+    }
+}
diff --git 
a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/blob/BlobStoreDeletedMessageVaultTest.java
 
b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/blob/BlobStoreDeletedMessageVaultTest.java
new file mode 100644
index 0000000..c4e18f9
--- /dev/null
+++ 
b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/blob/BlobStoreDeletedMessageVaultTest.java
@@ -0,0 +1,134 @@
+/****************************************************************
+ * 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.blob;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneId;
+
+import org.apache.james.blob.api.HashBlobId;
+import org.apache.james.blob.memory.MemoryBlobStore;
+import org.apache.james.vault.DeletedMessageVault;
+import org.apache.james.vault.DeletedMessageVaultContract;
+import 
org.apache.james.vault.memory.metadata.MemoryDeletedMessageMetadataVault;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
+
+class BlobStoreDeletedMessageVaultTest implements DeletedMessageVaultContract {
+    private static final Instant NOW = 
Instant.parse("2007-12-03T10:15:30.00Z");
+    private static final Clock CLOCK = Clock.fixed(NOW, ZoneId.of("UTC"));
+
+    private BlobStoreDeletedMessageVault messageVault;
+
+    @BeforeEach
+    void setUp() {
+        messageVault = new BlobStoreDeletedMessageVault(new 
MemoryDeletedMessageMetadataVault(),
+            new MemoryBlobStore(new HashBlobId.Factory()),
+            new BucketNameGenerator(CLOCK));
+    }
+
+    @Override
+    public DeletedMessageVault getVault() {
+        return messageVault;
+    }
+
+
+    @Disabled("Will be implemented later")
+    public void deleteShouldThrowOnNullMessageId() {
+
+    }
+
+    @Disabled("Will be implemented later")
+    public void deleteShouldThrowOnNullUser() {
+
+    }
+
+    @Disabled("Will be implemented in JAMES-2811")
+    @Override
+    public void deleteExpiredMessagesTaskShouldCompleteWhenNoMail() {
+
+    }
+
+    @Disabled("Will be implemented in JAMES-2811")
+    @Override
+    public void deleteExpiredMessagesTaskShouldCompleteWhenAllMailsDeleted() {
+
+    }
+
+    @Disabled("Will be implemented in JAMES-2811")
+    @Override
+    public void deleteExpiredMessagesTaskShouldCompleteWhenOnlyRecentMails() {
+
+    }
+
+    @Disabled("Will be implemented in JAMES-2811")
+    @Override
+    public void deleteExpiredMessagesTaskShouldDeleteOldMails() {
+
+    }
+
+    @Disabled("Will be implemented in JAMES-2811")
+    @Override
+    public void deleteExpiredMessagesTaskShouldNotDeleteRecentMails() {
+
+    }
+
+    @Disabled("Will be implemented in JAMES-2811")
+    @Override
+    public void deleteExpiredMessagesTaskShouldDoNothingWhenEmpty() {
+
+    }
+
+    @Disabled("Will be implemented in JAMES-2811")
+    @Override
+    public void deleteExpiredMessagesTaskShouldCompleteWhenOnlyOldMails() {
+
+    }
+
+    @Disabled("Will be implemented later")
+    @Override
+    public void deleteShouldRunSuccessfullyInAConcurrentContext() {
+
+    }
+
+    @Disabled("Will be implemented later")
+    @Override
+    public void usersWithVaultShouldReturnEmptyWhenNoItem() {
+
+    }
+
+    @Disabled("Will be implemented later")
+    @Override
+    public void usersWithVaultShouldReturnAllUsers() {
+
+    }
+
+    @Disabled("Will be implemented later")
+    @Override
+    public void searchAllShouldNotReturnDeletedItems() {
+
+    }
+
+    @Disabled("Will be implemented later")
+    @Override
+    public void loadMimeMessageShouldReturnEmptyWhenDeleted() {
+
+    }
+}
\ No newline at end of file
diff --git 
a/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/blob/BucketNameGeneratorTest.java
 
b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/blob/BucketNameGeneratorTest.java
new file mode 100644
index 0000000..b2a2c6a
--- /dev/null
+++ 
b/mailbox/plugin/deleted-messages-vault/src/test/java/org/apache/james/vault/blob/BucketNameGeneratorTest.java
@@ -0,0 +1,48 @@
+/****************************************************************
+ * 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.blob;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.time.ZoneId;
+
+import org.apache.james.blob.api.BucketName;
+import org.junit.jupiter.api.Test;
+
+class BucketNameGeneratorTest {
+    private static final Instant NOW = 
Instant.parse("2007-12-03T10:15:30.00Z");
+    private static final Instant DATE_2 = 
Instant.parse("2007-07-03T10:15:30.00Z");
+    private static final Clock CLOCK = Clock.fixed(NOW, ZoneId.of("UTC"));
+    private static final Clock CLOCK_2 = Clock.fixed(DATE_2, ZoneId.of("UTC"));
+
+    @Test
+    void currentBucketShouldReturnBucketFormattedOnFirstDayOfMonth() {
+        assertThat(new BucketNameGenerator(CLOCK).currentBucket())
+            .isEqualTo(BucketName.of("deletedMessages-2007-12-01"));
+    }
+
+    @Test
+    void monthShouldBeFormattedWithTwoDigits() {
+        assertThat(new BucketNameGenerator(CLOCK_2).currentBucket())
+            .isEqualTo(BucketName.of("deletedMessages-2007-07-01"));
+    }
+}
\ No newline at end of file


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

Reply via email to