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/06/10 04:15:53 UTC

[james-project] branch master updated (f9fe42c -> 54c31be)

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

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


    from f9fe42c  JAMES-2279 Write a WithPriority mailet and HasPriority matchers
     new 0b89091  JAMES-2171 Fasten ElasticSearchIntegrationTest
     new 4a2ec3a  JAMES-2782 A component to generate exported file names
     new b266d75  JAMES-2782 one more stage of adding file prefix for exporting operation
     new 7852f95  JAMES-2782 LocalFileExport with custom file prefix
     new 2d5f4e3  JAMES-2782 LinshareBlobExport with custom file prefix
     new 54c31be  JAMES-2551 Starting James before rabbitMQ should be supported

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../james/backends/es/DockerElasticSearch.java     |  2 +
 .../james/backend/rabbitmq/DockerRabbitMQ.java     | 13 ++--
 server/blob/blob-export-api/pom.xml                |  6 ++
 .../james/blob/export/api/BlobExportMechanism.java | 11 ++-
 .../export/api/ExportedFileNamesGenerator.java     | 27 ++++----
 .../export/api/ExportedFileNamesGeneratorTest.java | 79 ++++++++++++++++++++++
 .../export/file/LocalFileBlobExportMechanism.java  | 25 +++----
 .../file/LocalFileBlobExportMechanismTest.java     | 31 +++++++++
 .../james/CassandraRabbitMQJamesServerFixture.java |  6 +-
 ...RabbitMQJamesServerWithRetryConnectionTest.java | 76 +++++++++++++++++++++
 .../apache/james/modules/RabbitMQExtension.java    |  5 ++
 .../james/webadmin/vault/routes/ExportService.java |  2 +
 .../routes/DeletedMessagesVaultRoutesTest.java     |  2 +-
 .../james/util/docker/DockerGenericContainer.java  |  8 ++-
 .../linshare/LinshareBlobExportMechanism.java      | 21 +++---
 .../linshare/LinshareBlobExportMechanismTest.java  | 25 ++++++-
 16 files changed, 288 insertions(+), 51 deletions(-)
 copy mailbox/event/event-rabbitmq/src/main/java/org/apache/james/mailbox/events/RegistrationQueueName.java => server/blob/blob-export-api/src/main/java/org/apache/james/blob/export/api/ExportedFileNamesGenerator.java (65%)
 create mode 100644 server/blob/blob-export-api/src/test/java/org/apache/james/blob/export/api/ExportedFileNamesGeneratorTest.java
 create mode 100644 server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/RabbitMQJamesServerWithRetryConnectionTest.java


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


[james-project] 01/06: JAMES-2171 Fasten ElasticSearchIntegrationTest

Posted by bt...@apache.org.
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 0b89091342821451291d30afbc6ba03c70fc7d4b
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri Jun 7 12:11:41 2019 +0700

    JAMES-2171 Fasten ElasticSearchIntegrationTest
    
    Each of the 111 test case creates 13 messages that are then parsed by Tika
    and indexed sequentially (InVmEventBus).
    
    Using a TMPFS based file system showed a x6 indexation time improvement
    locally and significantly improved indexation time for mailbox/elasticsearch
---
 .../org/apache/james/backends/es/DockerElasticSearch.java   |  2 ++
 .../org/apache/james/backend/rabbitmq/DockerRabbitMQ.java   | 13 ++++++-------
 .../apache/james/util/docker/DockerGenericContainer.java    |  8 +++++++-
 3 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearch.java b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearch.java
index c40fb36..518aab4 100644
--- a/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearch.java
+++ b/backends-common/elasticsearch/src/test/java/org/apache/james/backends/es/DockerElasticSearch.java
@@ -31,6 +31,7 @@ import org.apache.james.util.docker.RateLimiters;
 import org.testcontainers.containers.wait.strategy.HostPortWaitStrategy;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 
 import feign.Feign;
 import feign.Logger;
@@ -66,6 +67,7 @@ public class DockerElasticSearch {
 
     public DockerElasticSearch(String imageName) {
         this.eSContainer = new DockerGenericContainer(imageName)
+            .withTmpFs(ImmutableMap.of("/usr/share/elasticsearch/data", "rw,size=200m"))
             .withExposedPorts(ES_HTTP_PORT)
             .withEnv("discovery.type", "single-node")
             .withAffinityToContainer()
diff --git a/backends-common/rabbitmq/src/test/java/org/apache/james/backend/rabbitmq/DockerRabbitMQ.java b/backends-common/rabbitmq/src/test/java/org/apache/james/backend/rabbitmq/DockerRabbitMQ.java
index 6cec712..9843fd3 100644
--- a/backends-common/rabbitmq/src/test/java/org/apache/james/backend/rabbitmq/DockerRabbitMQ.java
+++ b/backends-common/rabbitmq/src/test/java/org/apache/james/backend/rabbitmq/DockerRabbitMQ.java
@@ -80,13 +80,12 @@ public class DockerRabbitMQ {
         this.hostNameSuffix = clusterIdentity.orElse(UUID.randomUUID().toString());
         this.rabbitHostName = hostName(hostNamePrefix);
         this.container = new GenericContainer<>(Images.RABBITMQ)
-                .withCreateContainerCmdModifier(cmd -> cmd.withName(this.rabbitHostName))
-                .withCreateContainerCmdModifier(cmd -> cmd.withHostName(this.rabbitHostName))
-                .withExposedPorts(DEFAULT_RABBITMQ_PORT, DEFAULT_RABBITMQ_ADMIN_PORT)
-                .waitingFor(waitStrategy())
-                .withLogConsumer(frame -> LOGGER.debug(frame.getUtf8String()))
-                .withCreateContainerCmdModifier(cmd -> cmd.getHostConfig()
-                    .withTmpFs(ImmutableMap.of("/var/lib/rabbitmq/mnesia", "rw,noexec,nosuid,size=100m")));
+            .withCreateContainerCmdModifier(cmd -> cmd.withName(this.rabbitHostName))
+            .withCreateContainerCmdModifier(cmd -> cmd.withHostName(this.rabbitHostName))
+            .withExposedPorts(DEFAULT_RABBITMQ_PORT, DEFAULT_RABBITMQ_ADMIN_PORT)
+            .waitingFor(waitStrategy())
+            .withLogConsumer(frame -> LOGGER.debug(frame.getUtf8String()))
+            .withTmpFs(ImmutableMap.of("/var/lib/rabbitmq/mnesia", "rw,noexec,nosuid,size=100m"));
         net.ifPresent(this.container::withNetwork);
         erlangCookie.ifPresent(cookie -> this.container.withEnv(RABBITMQ_ERLANG_COOKIE, cookie));
         this.nodeName = DEFAULT_RABBIT_NODE_NAME_PREFIX + "@" + this.rabbitHostName;
diff --git a/server/testing/src/main/java/org/apache/james/util/docker/DockerGenericContainer.java b/server/testing/src/main/java/org/apache/james/util/docker/DockerGenericContainer.java
index 8502745..46b1de8 100644
--- a/server/testing/src/main/java/org/apache/james/util/docker/DockerGenericContainer.java
+++ b/server/testing/src/main/java/org/apache/james/util/docker/DockerGenericContainer.java
@@ -23,6 +23,7 @@ import java.io.IOException;
 import java.net.Socket;
 import java.time.Duration;
 import java.util.List;
+import java.util.Map;
 
 import javax.net.SocketFactory;
 
@@ -65,7 +66,7 @@ public class DockerGenericContainer implements TestRule {
             logAndCheckSkipTest(e);
         }
     }
-    
+
     private void logAndCheckSkipTest(IllegalStateException e) {
         LOGGER.error("Cannot initial a docker container", e);
         if (e.getMessage().startsWith(NO_DOCKER_ENVIRONMENT)) {
@@ -90,6 +91,11 @@ public class DockerGenericContainer implements TestRule {
         return this;
     }
 
+    public DockerGenericContainer withTmpFs(Map<String, String> mapping) {
+        container.withTmpFs(mapping);
+        return this;
+    }
+
     public DockerGenericContainer withExposedPorts(Integer... ports) {
         container.withExposedPorts(ports);
         return this;


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


[james-project] 05/06: JAMES-2782 LinshareBlobExport with custom file prefix

Posted by bt...@apache.org.
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 2d5f4e3e1bb490f9dbf4b693568fcce4e2987e39
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Thu Jun 6 17:40:49 2019 +0700

    JAMES-2782 LinshareBlobExport with custom file prefix
---
 .../linshare/LinshareBlobExportMechanism.java      | 21 ++++++++++--------
 .../linshare/LinshareBlobExportMechanismTest.java  | 25 +++++++++++++++++++++-
 2 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/third-party/linshare/src/main/java/org/apache/james/linshare/LinshareBlobExportMechanism.java b/third-party/linshare/src/main/java/org/apache/james/linshare/LinshareBlobExportMechanism.java
index 3af2261..d86dabb 100644
--- a/third-party/linshare/src/main/java/org/apache/james/linshare/LinshareBlobExportMechanism.java
+++ b/third-party/linshare/src/main/java/org/apache/james/linshare/LinshareBlobExportMechanism.java
@@ -29,35 +29,43 @@ import org.apache.commons.io.FileUtils;
 import org.apache.james.blob.api.BlobId;
 import org.apache.james.blob.api.BlobStore;
 import org.apache.james.blob.export.api.BlobExportMechanism;
+import org.apache.james.blob.export.api.ExportedFileNamesGenerator;
 import org.apache.james.blob.export.api.FileExtension;
 import org.apache.james.core.MailAddress;
 import org.apache.james.linshare.client.Document;
 import org.apache.james.linshare.client.LinshareAPI;
 import org.apache.james.linshare.client.ShareRequest;
 
+import com.google.common.io.Files;
+
 public class LinshareBlobExportMechanism implements BlobExportMechanism {
+
     private final LinshareAPI linshareAPI;
     private final BlobStore blobStore;
+    private final File tempDir;
 
     @Inject
     LinshareBlobExportMechanism(LinshareAPI linshareAPI, BlobStore blobStore) {
         this.linshareAPI = linshareAPI;
         this.blobStore = blobStore;
+        this.tempDir = Files.createTempDir();
     }
 
     @Override
     public ShareeStage blobId(BlobId blobId) {
-        return mailAddress -> explanation -> fileExtension -> () ->  {
+        return mailAddress -> explanation -> fileCustomPrefix -> fileExtension -> () ->  {
             try {
-                exportBlob(blobId, mailAddress, fileExtension, explanation);
+                exportBlob(blobId, mailAddress, fileCustomPrefix, fileExtension, explanation);
             } catch (Exception e) {
                 throw new BlobExportException("Error while exporting blob " + blobId.asString() + " to " + mailAddress.asString(), e);
             }
         };
     }
 
-    private void exportBlob(BlobId blobId, MailAddress mailAddress, Optional<FileExtension> fileExtension, String explanation) throws IOException {
-        File tempFile = createTempFile(blobId, fileExtension);
+    private void exportBlob(BlobId blobId, MailAddress mailAddress, Optional<String> fileCustomPrefix,
+                            Optional<FileExtension> fileExtension, String explanation) throws IOException {
+        String fileName = ExportedFileNamesGenerator.generateFileName(fileCustomPrefix, blobId, fileExtension);
+        File tempFile = new File(tempDir, fileName);
         try {
             FileUtils.copyInputStreamToFile(blobStore.read(blobId), tempFile);
             uploadAndShare(mailAddress, tempFile, explanation);
@@ -74,9 +82,4 @@ public class LinshareBlobExportMechanism implements BlobExportMechanism {
             .addRecipient(mailAddress)
             .build());
     }
-
-    private File createTempFile(BlobId blobId, Optional<FileExtension> fileExtension) throws IOException {
-        String suffix = fileExtension.map(FileExtension::asFileSuffix).orElse("");
-        return File.createTempFile(blobId.asString() + "_", suffix);
-    }
 }
diff --git a/third-party/linshare/src/test/java/org/apache/james/linshare/LinshareBlobExportMechanismTest.java b/third-party/linshare/src/test/java/org/apache/james/linshare/LinshareBlobExportMechanismTest.java
index 51150c4..9af73cb 100644
--- a/third-party/linshare/src/test/java/org/apache/james/linshare/LinshareBlobExportMechanismTest.java
+++ b/third-party/linshare/src/test/java/org/apache/james/linshare/LinshareBlobExportMechanismTest.java
@@ -29,6 +29,7 @@ import static org.hamcrest.Matchers.hasItem;
 import static org.hamcrest.Matchers.hasSize;
 
 import java.nio.charset.StandardCharsets;
+import java.util.Optional;
 
 import org.apache.james.blob.api.BlobId;
 import org.apache.james.blob.api.HashBlobId;
@@ -74,17 +75,19 @@ class LinshareBlobExportMechanismTest {
     @Test
     void exportShouldShareTheDocumentViaLinshare() throws Exception {
         BlobId blobId = blobStore.save(FILE_CONTENT).block();
+        String filePrefix = "deleted-message-of-bob@james.org-";
 
         testee.blobId(blobId)
             .with(new MailAddress(USER_2.getUsername()))
             .explanation(EXPLANATION)
+            .filePrefix(Optional.of(filePrefix))
             .fileExtension(FILE_TEXT_EXTENSION)
             .export();
 
         assertThat(user2API.receivedShares())
             .hasSize(1)
             .allSatisfy(receivedShare -> assertThat(receivedShare.getDocument().getName()).endsWith(".txt"))
-            .allSatisfy(receivedShare -> assertThat(receivedShare.getDocument().getName()).startsWith(blobId.asString()))
+            .allSatisfy(receivedShare -> assertThat(receivedShare.getDocument().getName()).startsWith(filePrefix))
             .allSatisfy(receivedShare -> assertThat(receivedShare.getSender().getMail()).isEqualTo(USER_1.getUsername()));
     }
 
@@ -95,6 +98,7 @@ class LinshareBlobExportMechanismTest {
         testee.blobId(blobId)
             .with(new MailAddress(USER_2.getUsername()))
             .explanation(EXPLANATION)
+            .noFileCustomPrefix()
             .fileExtension(FILE_TEXT_EXTENSION)
             .export();
 
@@ -123,6 +127,7 @@ class LinshareBlobExportMechanismTest {
         testee.blobId(blobId)
             .with(new MailAddress(USER_2.getUsername()))
             .explanation(EXPLANATION)
+            .noFileCustomPrefix()
             .fileExtension(FILE_TEXT_EXTENSION)
             .export();
 
@@ -139,8 +144,26 @@ class LinshareBlobExportMechanismTest {
             () -> testee.blobId(blobId)
                 .with(new MailAddress(USER_2.getUsername()))
                 .explanation(EXPLANATION)
+                .noFileCustomPrefix()
                 .fileExtension(FILE_TEXT_EXTENSION)
                 .export())
             .isInstanceOf(BlobExportMechanism.BlobExportException.class);
     }
+
+    @Test
+    void exportWithFilePrefixShouldCreateFileWithCustomPrefix() throws Exception {
+        BlobId blobId = blobStore.save(FILE_CONTENT).block();
+        String filePrefix = "deleted-message-of-bob@james.org";
+
+        testee.blobId(blobId)
+            .with(new MailAddress(USER_2.getUsername()))
+            .explanation(EXPLANATION)
+            .filePrefix(Optional.of(filePrefix))
+            .fileExtension(FILE_TEXT_EXTENSION)
+            .export();
+
+        Document sharedDoc = user2API.receivedShares().get(0).getDocument();
+        assertThat(sharedDoc.getName())
+            .startsWith(filePrefix);
+    }
 }
\ 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


[james-project] 04/06: JAMES-2782 LocalFileExport with custom file prefix

Posted by bt...@apache.org.
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 7852f95f0db7cb711fbbff78fe01bfc924bbd701
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Thu Jun 6 17:32:38 2019 +0700

    JAMES-2782 LocalFileExport with custom file prefix
---
 .../export/file/LocalFileBlobExportMechanism.java  | 25 ++++++-----------
 .../file/LocalFileBlobExportMechanismTest.java     | 31 ++++++++++++++++++++++
 2 files changed, 39 insertions(+), 17 deletions(-)

diff --git a/server/blob/blob-export-file/src/main/java/org/apache/james/blob/export/file/LocalFileBlobExportMechanism.java b/server/blob/blob-export-file/src/main/java/org/apache/james/blob/export/file/LocalFileBlobExportMechanism.java
index 32e899b..15add95 100644
--- a/server/blob/blob-export-file/src/main/java/org/apache/james/blob/export/file/LocalFileBlobExportMechanism.java
+++ b/server/blob/blob-export-file/src/main/java/org/apache/james/blob/export/file/LocalFileBlobExportMechanism.java
@@ -28,10 +28,10 @@ import java.util.Optional;
 import javax.inject.Inject;
 
 import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.james.blob.api.BlobId;
 import org.apache.james.blob.api.BlobStore;
 import org.apache.james.blob.export.api.BlobExportMechanism;
+import org.apache.james.blob.export.api.ExportedFileNamesGenerator;
 import org.apache.james.blob.export.api.FileExtension;
 import org.apache.james.core.MailAddress;
 import org.apache.james.core.builder.MimeMessageBuilder;
@@ -44,9 +44,6 @@ import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 
 public class LocalFileBlobExportMechanism implements BlobExportMechanism {
-    private static final int STRING_LENGTH = 32;
-    private static final boolean WITH_LETTERS = true;
-    private static final boolean WITH_NUMBERS = true;
     private static final String SUBJECT = "Some content had had just been exported";
     static final String CORRESPONDING_FILE_HEADER = "corresponding-file";
 
@@ -107,18 +104,21 @@ public class LocalFileBlobExportMechanism implements BlobExportMechanism {
 
     @Override
     public ShareeStage blobId(BlobId blobId) {
-        return mailAddress -> explanation -> fileExtension -> () ->  {
-            String fileUrl = copyBlobToFile(blobId, fileExtension);
+        return mailAddress -> explanation -> fileCustomPrefix -> fileExtension -> () ->  {
+            String fileUrl = copyBlobToFile(blobId, fileCustomPrefix, fileExtension);
             sendMail(mailAddress, fileUrl, explanation);
         };
     }
 
-    private String copyBlobToFile(BlobId blobId, Optional<FileExtension> fileExtension) {
+    private String copyBlobToFile(BlobId blobId,
+                                  Optional<String> fileCustomPrefix,
+                                  Optional<FileExtension> fileExtension) {
         try {
             File exportingDirectory = fileSystem.getFile(configuration.exportDirectory);
             FileUtils.forceMkdir(exportingDirectory);
 
-            String fileURL = generateFileUrl(fileExtension);
+            String fileName = ExportedFileNamesGenerator.generateFileName(fileCustomPrefix, blobId, fileExtension);
+            String fileURL = configuration.exportDirectory + "/" + fileName;
             File file = fileSystem.getFile(fileURL);
             FileUtils.copyToFile(blobStore.read(blobId), file);
 
@@ -128,15 +128,6 @@ public class LocalFileBlobExportMechanism implements BlobExportMechanism {
         }
     }
 
-    private String generateFileUrl(Optional<FileExtension> fileExtension) {
-        String fileName = RandomStringUtils.random(STRING_LENGTH, WITH_LETTERS, !WITH_NUMBERS);
-        String filePathWithoutExtension = configuration.exportDirectory + "/" + fileName;
-
-        return fileExtension
-            .map(extension -> extension.appendExtension(filePathWithoutExtension))
-            .orElse(filePathWithoutExtension);
-    }
-
     private void sendMail(MailAddress mailAddress, String fileUrl, String explanation) {
         try {
             MimeMessageBuilder mimeMessage = MimeMessageBuilder.mimeMessageBuilder()
diff --git a/server/blob/blob-export-file/src/test/java/org/apache/james/blob/export/file/LocalFileBlobExportMechanismTest.java b/server/blob/blob-export-file/src/test/java/org/apache/james/blob/export/file/LocalFileBlobExportMechanismTest.java
index 2b91681..522f9d8 100644
--- a/server/blob/blob-export-file/src/test/java/org/apache/james/blob/export/file/LocalFileBlobExportMechanismTest.java
+++ b/server/blob/blob-export-file/src/test/java/org/apache/james/blob/export/file/LocalFileBlobExportMechanismTest.java
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.when;
 import java.io.FileInputStream;
 import java.net.InetAddress;
 import java.nio.charset.StandardCharsets;
+import java.util.Optional;
 
 import javax.mail.Message;
 import javax.mail.internet.InternetAddress;
@@ -84,6 +85,7 @@ class LocalFileBlobExportMechanismTest {
         testee.blobId(blobId)
             .with(MailAddressFixture.RECIPIENT1)
             .explanation(explanation)
+            .noFileCustomPrefix()
             .noFileExtension()
             .export();
 
@@ -115,6 +117,7 @@ class LocalFileBlobExportMechanismTest {
         testee.blobId(blobId)
             .with(MailAddressFixture.RECIPIENT1)
             .explanation("The content of a deleted message vault had been shared with you.")
+            .noFileCustomPrefix()
             .noFileExtension()
             .export();
 
@@ -139,6 +142,7 @@ class LocalFileBlobExportMechanismTest {
             testee.blobId(blobId)
                 .with(MailAddressFixture.RECIPIENT1)
                 .explanation("The content of a deleted message vault had been shared with you.")
+                .noFileCustomPrefix()
                 .noFileExtension()
                 .export())
             .isInstanceOf(ObjectStoreException.class);
@@ -151,6 +155,7 @@ class LocalFileBlobExportMechanismTest {
         testee.blobId(blobId)
             .with(MailAddressFixture.RECIPIENT1)
             .explanation("The content of a deleted message vault had been shared with you.")
+            .noFileCustomPrefix()
             .noFileExtension()
             .export();
 
@@ -174,6 +179,7 @@ class LocalFileBlobExportMechanismTest {
         testee.blobId(blobId)
             .with(MailAddressFixture.RECIPIENT1)
             .explanation("The content of a deleted message vault had been shared with you.")
+            .noFileCustomPrefix()
             .fileExtension(FileExtension.ZIP)
             .export();
 
@@ -191,6 +197,31 @@ class LocalFileBlobExportMechanismTest {
             });
     }
 
+    @Test
+    void exportingBlobShouldCreateAFileWithPrefixWhenDeclaringPrefix() {
+        BlobId blobId = blobStore.save(BLOB_CONTENT).block();
+        String filePrefix = "deleted-message-of-bob@james.org";
+
+        testee.blobId(blobId)
+            .with(MailAddressFixture.RECIPIENT1)
+            .explanation("The content of a deleted message vault had been shared with you.")
+            .filePrefix(Optional.of(filePrefix))
+            .fileExtension(FileExtension.ZIP)
+            .export();
+
+        assertThat(mailetContext.getSentMails())
+            .element(0)
+            .satisfies(sentMail -> {
+                try {
+                    String fileUrl = sentMail.getMsg().getHeader(LocalFileBlobExportMechanism.CORRESPONDING_FILE_HEADER)[0];
+                    assertThat(FilenameUtils.getName(fileUrl))
+                        .startsWith(filePrefix);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            });
+    }
+
     @Nested
     class ConfigurationTest {
         @Test


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


[james-project] 06/06: JAMES-2551 Starting James before rabbitMQ should be supported

Posted by bt...@apache.org.
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 54c31bec2679a4e84256294f72207a97ddfb86e4
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Fri May 24 10:31:55 2019 +0700

    JAMES-2551 Starting James before rabbitMQ should be supported
    
    James should await RabbitMQ start
---
 .../james/CassandraRabbitMQJamesServerFixture.java |  6 +-
 ...RabbitMQJamesServerWithRetryConnectionTest.java | 76 ++++++++++++++++++++++
 .../apache/james/modules/RabbitMQExtension.java    |  5 ++
 3 files changed, 86 insertions(+), 1 deletion(-)

diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQJamesServerFixture.java b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQJamesServerFixture.java
index bc5836c..b351172 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQJamesServerFixture.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/CassandraRabbitMQJamesServerFixture.java
@@ -34,10 +34,14 @@ public class CassandraRabbitMQJamesServerFixture {
             .overrideWith(JmapJamesServerContract.DOMAIN_LIST_CONFIGURATION_MODULE);
 
     public static JamesServerBuilder baseExtensionBuilder() {
+        return baseExtensionBuilder(new RabbitMQExtension());
+    }
+
+    public static JamesServerBuilder baseExtensionBuilder(RabbitMQExtension rabbitMQExtension) {
         return new JamesServerBuilder()
             .extension(new DockerElasticSearchExtension())
             .extension(new CassandraExtension())
-            .extension(new RabbitMQExtension())
+            .extension(rabbitMQExtension)
             .server(CONFIGURATION_BUILDER);
     }
 }
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/RabbitMQJamesServerWithRetryConnectionTest.java b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/RabbitMQJamesServerWithRetryConnectionTest.java
new file mode 100644
index 0000000..e44138e
--- /dev/null
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/RabbitMQJamesServerWithRetryConnectionTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.time.Duration;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.james.modules.RabbitMQExtension;
+import org.apache.james.util.concurrent.NamedThreadFactory;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+class RabbitMQJamesServerWithRetryConnectionTest {
+    private static final long WAITING_TIME = Duration.ofSeconds(10).toMillis();
+
+    private RabbitMQExtension rabbitMQExtension = new RabbitMQExtension();
+    private ScheduledExecutorService executorService;
+
+    @RegisterExtension
+    JamesServerExtension jamesServerExtension = CassandraRabbitMQJamesServerFixture
+        .baseExtensionBuilder(rabbitMQExtension)
+        .disableAutoStart()
+        .build();
+
+    @BeforeEach
+    void setUp() {
+        ThreadFactory threadFactory = NamedThreadFactory.withClassName(getClass());
+        executorService = Executors.newSingleThreadScheduledExecutor(threadFactory);
+    }
+
+    @AfterEach
+    void tearDown() {
+        executorService.shutdownNow();
+    }
+
+    @Test
+    void serverShouldStartAtDefault(GuiceJamesServer server) throws Exception {
+        server.start();
+
+        assertThat(server.isStarted()).isTrue();
+    }
+
+    @Test
+    void serverShouldRetryToConnectToRabbitMQWhenStartService(GuiceJamesServer server) throws Exception {
+        rabbitMQExtension.dockerRabbitMQ().pause();
+        executorService.schedule(() -> rabbitMQExtension.dockerRabbitMQ().unpause(), WAITING_TIME, TimeUnit.MILLISECONDS);
+
+        server.start();
+
+        assertThat(server.isStarted()).isTrue();
+    }
+}
diff --git a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/RabbitMQExtension.java b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/RabbitMQExtension.java
index 095baca..6651549 100644
--- a/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/RabbitMQExtension.java
+++ b/server/container/guice/cassandra-rabbitmq-guice/src/test/java/org/apache/james/modules/RabbitMQExtension.java
@@ -20,6 +20,7 @@
 package org.apache.james.modules;
 
 import org.apache.james.GuiceModuleTestExtension;
+import org.apache.james.backend.rabbitmq.DockerRabbitMQ;
 import org.junit.jupiter.api.extension.ExtensionContext;
 
 import com.google.inject.Module;
@@ -42,4 +43,8 @@ public class RabbitMQExtension implements GuiceModuleTestExtension {
     public Module getModule() {
         return new TestRabbitMQModule(rabbitMQRule.dockerRabbitMQ());
     }
+
+    public DockerRabbitMQ dockerRabbitMQ() {
+        return rabbitMQRule.dockerRabbitMQ();
+    }
 }


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


[james-project] 03/06: JAMES-2782 one more stage of adding file prefix for exporting operation

Posted by bt...@apache.org.
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 b266d75e3a8e20cff424576ffeae48e5f7a33738
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Thu Jun 6 17:29:37 2019 +0700

    JAMES-2782 one more stage of adding file prefix for exporting operation
---
 .../org/apache/james/blob/export/api/BlobExportMechanism.java | 11 ++++++++++-
 .../org/apache/james/webadmin/vault/routes/ExportService.java |  2 ++
 .../webadmin/vault/routes/DeletedMessagesVaultRoutesTest.java |  2 +-
 3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/server/blob/blob-export-api/src/main/java/org/apache/james/blob/export/api/BlobExportMechanism.java b/server/blob/blob-export-api/src/main/java/org/apache/james/blob/export/api/BlobExportMechanism.java
index e88aba1..d9fffa5 100644
--- a/server/blob/blob-export-api/src/main/java/org/apache/james/blob/export/api/BlobExportMechanism.java
+++ b/server/blob/blob-export-api/src/main/java/org/apache/james/blob/export/api/BlobExportMechanism.java
@@ -39,7 +39,16 @@ public interface BlobExportMechanism {
 
     @FunctionalInterface
     interface ExplanationStage {
-        FileExtensionStage explanation(String explanation);
+        FilePrefixStage explanation(String explanation);
+    }
+
+    @FunctionalInterface
+    interface FilePrefixStage {
+        FileExtensionStage filePrefix(Optional<String> prefix);
+
+        default FileExtensionStage noFileCustomPrefix() {
+            return filePrefix(Optional.empty());
+        }
     }
 
     @FunctionalInterface
diff --git a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/ExportService.java b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/ExportService.java
index 14c100c..9e12fcf 100644
--- a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/ExportService.java
+++ b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/main/java/org/apache/james/webadmin/vault/routes/ExportService.java
@@ -20,6 +20,7 @@
 package org.apache.james.webadmin.vault.routes;
 
 import java.io.IOException;
+import java.util.Optional;
 
 import javax.inject.Inject;
 
@@ -66,6 +67,7 @@ class ExportService {
         blobExport.blobId(blobId)
             .with(exportToAddress)
             .explanation(exportMessage(user))
+            .filePrefix(Optional.of("deleted-message-of-" + user.asString() + "_"))
             .fileExtension(FileExtension.ZIP)
             .export();
     }
diff --git a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRoutesTest.java
index 9375a6d..adb1e8c 100644
--- a/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox-deleted-message-vault/src/test/java/org/apache/james/webadmin/vault/routes/DeletedMessagesVaultRoutesTest.java
@@ -135,7 +135,7 @@ class DeletedMessagesVaultRoutesTest {
     private class NoopBlobExporting implements BlobExportMechanism {
         @Override
         public ShareeStage blobId(BlobId blobId) {
-            return exportTo -> explanation -> fileExtension -> () -> export(exportTo, explanation);
+            return exportTo -> explanation -> fileCustomPrefix -> fileExtension -> () -> export(exportTo, explanation);
         }
 
         void export(MailAddress exportTo, String explanation) {


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


[james-project] 02/06: JAMES-2782 A component to generate exported file names

Posted by bt...@apache.org.
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 4a2ec3a19e9a5b5ae38294270baa6d4810655d3d
Author: Tran Tien Duc <dt...@linagora.com>
AuthorDate: Thu Jun 6 17:28:53 2019 +0700

    JAMES-2782 A component to generate exported file names
    
    And will be used by LocalFileExport & LinshareExport mechanism
---
 server/blob/blob-export-api/pom.xml                |  6 ++
 .../export/api/ExportedFileNamesGenerator.java     | 43 ++++++++++++
 .../export/api/ExportedFileNamesGeneratorTest.java | 79 ++++++++++++++++++++++
 3 files changed, 128 insertions(+)

diff --git a/server/blob/blob-export-api/pom.xml b/server/blob/blob-export-api/pom.xml
index a3336bd..408d522 100644
--- a/server/blob/blob-export-api/pom.xml
+++ b/server/blob/blob-export-api/pom.xml
@@ -42,6 +42,12 @@
             <artifactId>blob-api</artifactId>
         </dependency>
         <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>blob-api</artifactId>
+            <scope>test</scope>
+            <type>test-jar</type>
+        </dependency>
+        <dependency>
             <groupId>nl.jqno.equalsverifier</groupId>
             <artifactId>equalsverifier</artifactId>
             <scope>test</scope>
diff --git a/server/blob/blob-export-api/src/main/java/org/apache/james/blob/export/api/ExportedFileNamesGenerator.java b/server/blob/blob-export-api/src/main/java/org/apache/james/blob/export/api/ExportedFileNamesGenerator.java
new file mode 100644
index 0000000..501196b
--- /dev/null
+++ b/server/blob/blob-export-api/src/main/java/org/apache/james/blob/export/api/ExportedFileNamesGenerator.java
@@ -0,0 +1,43 @@
+/****************************************************************
+ * 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.blob.export.api;
+
+import java.util.Optional;
+
+import org.apache.james.blob.api.BlobId;
+
+import com.google.common.base.Preconditions;
+
+public interface ExportedFileNamesGenerator {
+
+    static String generateFileName(Optional<String> fileCustomPrefix,
+                                   BlobId blobId,
+                                   Optional<FileExtension> fileExtension) {
+        Preconditions.checkNotNull(blobId);
+
+        String fileNameWithPrefix = fileCustomPrefix
+            .map(prefix -> prefix + blobId.asString())
+            .orElse(blobId.asString());
+
+        return fileExtension
+            .map(extension -> extension.appendExtension(fileNameWithPrefix))
+            .orElse(fileNameWithPrefix);
+    }
+}
diff --git a/server/blob/blob-export-api/src/test/java/org/apache/james/blob/export/api/ExportedFileNamesGeneratorTest.java b/server/blob/blob-export-api/src/test/java/org/apache/james/blob/export/api/ExportedFileNamesGeneratorTest.java
new file mode 100644
index 0000000..35cfb1f
--- /dev/null
+++ b/server/blob/blob-export-api/src/test/java/org/apache/james/blob/export/api/ExportedFileNamesGeneratorTest.java
@@ -0,0 +1,79 @@
+/****************************************************************
+ * 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.blob.export.api;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.util.Optional;
+
+import org.apache.james.blob.api.BlobId;
+import org.apache.james.blob.api.TestBlobId;
+import org.junit.jupiter.api.Test;
+
+class ExportedFileNamesGeneratorTest {
+
+    private static final TestBlobId.Factory BLOB_ID_FACTORY = new TestBlobId.Factory();
+    private static final BlobId BLOB_ID = BLOB_ID_FACTORY.from("blobId");
+
+    @Test
+    void generateFileNameShouldNotHavePrefixWhenEmptyPrefix() {
+        Optional<String> prefix = Optional.empty();
+        Optional<FileExtension> extension = Optional.of(FileExtension.ZIP);
+
+        assertThat(ExportedFileNamesGenerator.generateFileName(prefix, BLOB_ID, extension))
+            .isEqualTo("blobId.zip");
+    }
+
+    @Test
+    void generateFileNameShouldNotHaveSuffixWhenEmptySuffix() {
+        Optional<FileExtension> extension = Optional.empty();
+
+        assertThat(ExportedFileNamesGenerator.generateFileName(Optional.of("prefix-"), BLOB_ID, extension))
+            .isEqualTo("prefix-blobId");
+    }
+
+    @Test
+    void generateFileNameShouldNotHaveSuffixAndPrefixWhenNotSpecifying() {
+        Optional<String> prefix = Optional.empty();
+        Optional<FileExtension> extension = Optional.empty();
+
+        assertThat(ExportedFileNamesGenerator.generateFileName(prefix, BLOB_ID, extension))
+            .isEqualTo("blobId");
+    }
+
+    @Test
+    void generateFileNameShouldHaveSuffixAndPrefixWhenSpecified() {
+        Optional<FileExtension> extension = Optional.of(FileExtension.ZIP);
+
+        assertThat(ExportedFileNamesGenerator.generateFileName(Optional.of("prefix-"), BLOB_ID, extension))
+            .isEqualTo("prefix-blobId.zip");
+    }
+
+    @Test
+    void generateFileNameShouldThrowWhenNullBlobId() {
+        BlobId nullBlobId = null;
+        assertThatThrownBy(() -> ExportedFileNamesGenerator.generateFileName(
+                Optional.empty(),
+                nullBlobId,
+                Optional.empty()))
+            .isInstanceOf(NullPointerException.class);
+    }
+}
\ 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