james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From adup...@apache.org
Subject [1/8] james-project git commit: JAMES-2541 start implementing MailQueueFactoryContract with RabbitMQ
Date Thu, 06 Sep 2018 12:34:45 GMT
Repository: james-project
Updated Branches:
  refs/heads/master e6ef1744d -> 9d086021c


JAMES-2541 start implementing MailQueueFactoryContract with RabbitMQ


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

Branch: refs/heads/master
Commit: 7afbf302b1bc21eb230ef43e471cd5d7474c6c78
Parents: e6ef174
Author: Matthieu Baechler <matthieu@apache.org>
Authored: Tue Sep 4 18:00:58 2018 +0200
Committer: Antoine Duprat <aduprat@linagora.com>
Committed: Thu Sep 6 14:29:20 2018 +0200

----------------------------------------------------------------------
 server/queue/queue-rabbitmq/pom.xml             |  43 ++++-
 .../james/queue/rabbitmq/MailQueueName.java     | 165 +++++++++++++++++++
 .../james/queue/rabbitmq/RabbitMQMailQueue.java |  53 ++++++
 .../rabbitmq/RabbitMQMailQueueFactory.java      |  92 +++++++++++
 .../queue/rabbitmq/RabbitMQManagementApi.java   |  73 ++++++++
 .../rabbitmq/RabbitMQManagementCredentials.java |  40 +++++
 .../james/queue/rabbitmq/DockerRabbitMQ.java    |  31 +++-
 .../james/queue/rabbitmq/MailQueueNameTest.java |  93 +++++++++++
 .../rabbitmq/RabbitMqMailQueueFactoryTest.java  |  54 ++++++
 .../src/test/resources/logback-test.xml         |  14 +-
 .../org/apache/james/util/docker/Images.java    |   2 +-
 11 files changed, 646 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/7afbf302/server/queue/queue-rabbitmq/pom.xml
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/pom.xml b/server/queue/queue-rabbitmq/pom.xml
index 8d61023..045c786 100644
--- a/server/queue/queue-rabbitmq/pom.xml
+++ b/server/queue/queue-rabbitmq/pom.xml
@@ -32,18 +32,35 @@
 
     <name>Apache James :: Server :: Mail Queue :: RabbitMQ</name>
 
+    <properties>
+        <feign.version>10.0.1</feign.version>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>${james.groupId}</groupId>
-            <artifactId>james-server-util</artifactId>
+            <artifactId>james-server-queue-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-queue-api</artifactId>
+            <type>test-jar</type>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-util</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
             <artifactId>james-server-testing</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+        <dependency>
             <groupId>com.github.fge</groupId>
             <artifactId>throwing-lambdas</artifactId>
         </dependency>
@@ -60,6 +77,30 @@
             <artifactId>amqp-client</artifactId>
         </dependency>
         <dependency>
+            <groupId>io.github.openfeign</groupId>
+            <artifactId>feign-core</artifactId>
+            <version>${feign.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.github.openfeign</groupId>
+            <artifactId>feign-jackson</artifactId>
+            <version>${feign.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.github.openfeign</groupId>
+            <artifactId>feign-slf4j</artifactId>
+            <version>${feign.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.inject</groupId>
+            <artifactId>javax.inject</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>nl.jqno.equalsverifier</groupId>
+            <artifactId>equalsverifier</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.assertj</groupId>
             <artifactId>assertj-core</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/7afbf302/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/MailQueueName.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/MailQueueName.java
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/MailQueueName.java
new file mode 100644
index 0000000..e059e3f
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/MailQueueName.java
@@ -0,0 +1,165 @@
+/****************************************************************
+ * 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;
+
+import java.util.Objects;
+import java.util.Optional;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Preconditions;
+
+final class MailQueueName {
+
+    static class WorkQueueName {
+        static Optional<WorkQueueName> fromString(String name) {
+            Preconditions.checkNotNull(name);
+            return Optional.of(name)
+                .filter(WorkQueueName::isJamesWorkQueueName)
+                .map(s -> s.substring(WORKQUEUE_PREFIX.length()))
+                .map(WorkQueueName::new);
+        }
+
+        static boolean isJamesWorkQueueName(String name) {
+            return name.startsWith(WORKQUEUE_PREFIX);
+        }
+
+        private final String name;
+
+        private WorkQueueName(String name) {
+            this.name = name;
+        }
+
+        String asString() {
+            return WORKQUEUE_PREFIX + name;
+        }
+
+        MailQueueName toMailQueueName() {
+            return MailQueueName.fromString(name);
+        }
+
+        @Override
+        public final boolean equals(Object o) {
+            if (o instanceof WorkQueueName) {
+                WorkQueueName that = (WorkQueueName) o;
+                return Objects.equals(name, that.name);
+            }
+            return false;
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hash(name);
+        }
+
+        @Override
+        public String toString() {
+            return MoreObjects.toStringHelper(this)
+                .add("name", name)
+                .toString();
+        }
+    }
+
+    static class ExchangeName {
+        private final String name;
+
+        private ExchangeName(String name) {
+            this.name = name;
+        }
+
+        String asString() {
+            return EXCHANGE_PREFIX + name;
+        }
+
+        @Override
+        public final boolean equals(Object o) {
+            if (o instanceof ExchangeName) {
+                ExchangeName that = (ExchangeName) o;
+                return Objects.equals(name, that.name);
+            }
+            return false;
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hash(name);
+        }
+
+        @Override
+        public String toString() {
+            return MoreObjects.toStringHelper(this)
+                .add("name", name)
+                .toString();
+        }
+    }
+
+    private static final String PREFIX = "JamesMailQueue";
+    private static final String EXCHANGE_PREFIX = PREFIX + "-exchange-";
+    @VisibleForTesting static final String WORKQUEUE_PREFIX = PREFIX + "-workqueue-";
+
+    static MailQueueName fromString(String name) {
+        Preconditions.checkNotNull(name);
+        return new MailQueueName(name);
+    }
+
+    static Optional<MailQueueName> fromRabbitWorkQueueName(String workQueueName) {
+        return WorkQueueName.fromString(workQueueName)
+            .map(WorkQueueName::toMailQueueName);
+    }
+
+    private final String name;
+
+    private MailQueueName(String name) {
+        this.name = name;
+    }
+
+    String asString() {
+        return name;
+    }
+
+    ExchangeName toRabbitExchangeName() {
+        return new ExchangeName(name);
+    }
+
+    WorkQueueName toWorkQueueName() {
+        return new WorkQueueName(name);
+    }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof MailQueueName) {
+            MailQueueName that = (MailQueueName) o;
+            return Objects.equals(name, that.name);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(name);
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+            .add("name", name)
+            .toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/7afbf302/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueue.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueue.java
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueue.java
new file mode 100644
index 0000000..3058444
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueue.java
@@ -0,0 +1,53 @@
+/****************************************************************
+ * 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;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.james.queue.api.MailQueue;
+import org.apache.mailet.Mail;
+
+public class RabbitMQMailQueue implements MailQueue {
+    private final MailQueueName name;
+
+    public RabbitMQMailQueue(MailQueueName name) {
+        this.name = name;
+    }
+
+    @Override
+    public String getName() {
+        return name.asString();
+    }
+
+    @Override
+    public void enQueue(Mail mail, long delay, TimeUnit unit) throws MailQueueException {
+
+    }
+
+    @Override
+    public void enQueue(Mail mail) throws MailQueueException {
+
+    }
+
+    @Override
+    public MailQueueItem deQueue() throws MailQueueException, InterruptedException {
+        return null;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/7afbf302/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueueFactory.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueueFactory.java
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueueFactory.java
new file mode 100644
index 0000000..30b0555
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueueFactory.java
@@ -0,0 +1,92 @@
+/****************************************************************
+ * 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;
+
+import java.io.IOException;
+import java.util.Optional;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.james.queue.api.MailQueueFactory;
+
+import com.github.steveash.guavate.Guavate;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableMap;
+import com.rabbitmq.client.Channel;
+import com.rabbitmq.client.Connection;
+
+
+public class RabbitMQMailQueueFactory implements MailQueueFactory<RabbitMQMailQueue>
{
+
+    private static final String ROUTING_KEY = "";
+    private static final boolean RABBIT_OPTION_DURABLE = true;
+    private static final boolean RABBIT_OPTION_EXCLUSIVE = true;
+    private static final boolean RABBIT_OPTION_AUTO_DELETE = true;
+    private static final ImmutableMap<String, Object> RABBIT_OPTION_NO_ARGUMENTS =
ImmutableMap.of();
+
+    private final Channel channel;
+    private final RabbitMQManagementApi mqManagementApi;
+
+    @VisibleForTesting
+    @Inject
+    RabbitMQMailQueueFactory(Connection connection, RabbitMQManagementApi mqManagementApi)
throws IOException {
+        this.channel = connection.createChannel();
+        this.mqManagementApi = mqManagementApi;
+    }
+
+    @Override
+    public Optional<RabbitMQMailQueue> getQueue(String name) {
+        return getQueue(MailQueueName.fromString(name));
+    }
+
+    @Override
+    public RabbitMQMailQueue createQueue(String name) {
+        MailQueueName mailQueueName = MailQueueName.fromString(name);
+        return getQueue(mailQueueName)
+            .orElseGet(() -> attemptQueueCreation(mailQueueName));
+    }
+
+    @Override
+    public Set<RabbitMQMailQueue> listCreatedMailQueues() {
+        return mqManagementApi.listCreatedMailQueueNames()
+            .map(RabbitMQMailQueue::new)
+            .collect(Guavate.toImmutableSet());
+    }
+
+    private Optional<RabbitMQMailQueue> getQueue(MailQueueName name) {
+        return mqManagementApi.listCreatedMailQueueNames()
+            .filter(name::equals)
+            .map(RabbitMQMailQueue::new)
+            .findFirst();
+    }
+
+    private RabbitMQMailQueue attemptQueueCreation(MailQueueName name) {
+        try {
+            channel.exchangeDeclare(name.toRabbitExchangeName().asString(), "direct", RABBIT_OPTION_DURABLE);
+            channel.queueDeclare(name.toWorkQueueName().asString(), RABBIT_OPTION_DURABLE,
!RABBIT_OPTION_EXCLUSIVE, !RABBIT_OPTION_AUTO_DELETE, RABBIT_OPTION_NO_ARGUMENTS);
+            channel.queueBind(name.toWorkQueueName().asString(), name.toRabbitExchangeName().asString(),
ROUTING_KEY);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return new RabbitMQMailQueue(name);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/7afbf302/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQManagementApi.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQManagementApi.java
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQManagementApi.java
new file mode 100644
index 0000000..6822aab
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQManagementApi.java
@@ -0,0 +1,73 @@
+/****************************************************************
+ * 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;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.apache.james.util.OptionalUtils;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import feign.Feign;
+import feign.Logger;
+import feign.RequestLine;
+import feign.auth.BasicAuthRequestInterceptor;
+import feign.jackson.JacksonDecoder;
+import feign.jackson.JacksonEncoder;
+import feign.slf4j.Slf4jLogger;
+
+class RabbitMQManagementApi {
+
+    public interface Api {
+
+        class MessageQueue {
+            @JsonProperty("name")
+            String name;
+        }
+
+        @RequestLine("GET /api/queues")
+        List<MessageQueue> listQueues();
+    }
+
+
+    private final Api api;
+
+    RabbitMQManagementApi(URI rabbitManagementUri, RabbitMQManagementCredentials credentials)
throws MalformedURLException {
+        api = Feign.builder()
+            .requestInterceptor(new BasicAuthRequestInterceptor(credentials.getUser(), new
String(credentials.getPassword())))
+            .logger(new Slf4jLogger(RabbitMQManagementApi.class))
+            .logLevel(Logger.Level.FULL)
+            .encoder(new JacksonEncoder())
+            .decoder(new JacksonDecoder())
+            .target(Api.class, rabbitManagementUri.toString());
+
+    }
+
+    Stream<MailQueueName> listCreatedMailQueueNames() {
+        return api.listQueues()
+            .stream()
+            .map(x -> x.name)
+            .map(MailQueueName::fromRabbitWorkQueueName)
+            .flatMap(OptionalUtils::toStream);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/7afbf302/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQManagementCredentials.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQManagementCredentials.java
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQManagementCredentials.java
new file mode 100644
index 0000000..145767b
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQManagementCredentials.java
@@ -0,0 +1,40 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.queue.rabbitmq;
+
+public class RabbitMQManagementCredentials {
+
+    private final String user;
+    private final char[] password;
+
+    RabbitMQManagementCredentials(String user, char[] password) {
+        this.user = user;
+        this.password = password;
+    }
+
+    public String getUser() {
+        return user;
+    }
+
+    public char[] getPassword() {
+        return password;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/7afbf302/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/DockerRabbitMQ.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/DockerRabbitMQ.java
b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/DockerRabbitMQ.java
index a6aed4c..bba3315 100644
--- a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/DockerRabbitMQ.java
+++ b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/DockerRabbitMQ.java
@@ -19,6 +19,7 @@
 package org.apache.james.queue.rabbitmq;
 
 import java.util.Optional;
+import java.util.UUID;
 
 import org.apache.james.util.docker.Images;
 import org.slf4j.Logger;
@@ -26,6 +27,8 @@ import org.slf4j.LoggerFactory;
 import org.testcontainers.DockerClientFactory;
 import org.testcontainers.containers.GenericContainer;
 import org.testcontainers.containers.Network;
+import org.testcontainers.containers.wait.strategy.Wait;
+import org.testcontainers.containers.wait.strategy.WaitAllStrategy;
 
 import com.google.common.collect.ImmutableMap;
 import com.rabbitmq.client.ConnectionFactory;
@@ -35,6 +38,7 @@ public class DockerRabbitMQ {
 
     private static final String DEFAULT_RABBIT_NODE = "my-rabbit";
     private static final int DEFAULT_RABBITMQ_PORT = 5672;
+    private static final int DEFAULT_RABBITMQ_ADMIN_PORT = 15672;
     private static final String DEFAULT_RABBITMQ_USERNAME = "guest";
     private static final String DEFAULT_RABBITMQ_PASSWORD = "guest";
     private static final String RABBITMQ_ERLANG_COOKIE = "RABBITMQ_ERLANG_COOKIE";
@@ -55,10 +59,12 @@ public class DockerRabbitMQ {
     @SuppressWarnings("resource")
     private DockerRabbitMQ(Optional<String> hostName, Optional<String> erlangCookie,
Optional<String> nodeName, Optional<Network> net) {
         container = new GenericContainer<>(Images.RABBITMQ)
-                .withCreateContainerCmdModifier(cmd -> cmd.withName(hostName.orElse("localhost")))
+                .withCreateContainerCmdModifier(cmd -> cmd.withName(hostName.orElse(randomName())))
                 .withCreateContainerCmdModifier(cmd -> cmd.withHostName(hostName.orElse(DEFAULT_RABBIT_NODE)))
-                .withExposedPorts(DEFAULT_RABBITMQ_PORT)
-                .waitingFor(RabbitMQWaitStrategy.withDefaultTimeout(this))
+                .withExposedPorts(DEFAULT_RABBITMQ_PORT, DEFAULT_RABBITMQ_ADMIN_PORT)
+                .waitingFor(new WaitAllStrategy()
+                    .withStrategy(Wait.forHttp("").forPort(DEFAULT_RABBITMQ_ADMIN_PORT))
+                    .withStrategy(RabbitMQWaitStrategy.withDefaultTimeout(this)))
                 .withLogConsumer(frame -> LOGGER.debug(frame.getUtf8String()))
                 .withCreateContainerCmdModifier(cmd -> cmd.getHostConfig()
                     .withTmpFs(ImmutableMap.of("/var/lib/rabbitmq/mnesia", "rw,noexec,nosuid,size=100m")));
@@ -68,6 +74,10 @@ public class DockerRabbitMQ {
         this.nodeName = nodeName;
     }
 
+    private String randomName() {
+        return UUID.randomUUID().toString();
+    }
+
     public String getHostIp() {
         return container.getContainerIpAddress();
     }
@@ -76,6 +86,10 @@ public class DockerRabbitMQ {
         return container.getMappedPort(DEFAULT_RABBITMQ_PORT);
     }
 
+    public Integer getAdminPort() {
+        return container.getMappedPort(DEFAULT_RABBITMQ_ADMIN_PORT);
+    }
+
     public String getUsername() {
         return DEFAULT_RABBITMQ_USERNAME;
     }
@@ -139,4 +153,15 @@ public class DockerRabbitMQ {
                 .getStdout();
         LOGGER.debug("start_app: {}", stdout);
     }
+
+    public void reset() throws Exception {
+        stopApp();
+
+        String stdout = container()
+            .execInContainer("rabbitmqctl", "reset")
+            .getStdout();
+        LOGGER.debug("reset: {}", stdout);
+
+        startApp();
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/7afbf302/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/MailQueueNameTest.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/MailQueueNameTest.java
b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/MailQueueNameTest.java
new file mode 100644
index 0000000..ec1e67c
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/MailQueueNameTest.java
@@ -0,0 +1,93 @@
+/****************************************************************
+ * 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;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import org.junit.jupiter.api.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+class MailQueueNameTest {
+
+    @Test
+    void fromStringShouldThrowWhenNull() {
+        assertThatThrownBy(() -> MailQueueName.fromString(null))
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    void fromStringShouldReturnInstanceWhenEmptyString() {
+        assertThat(MailQueueName.fromString("")).isNotNull();
+    }
+
+    @Test
+    void fromStringShouldReturnInstanceWhenArbitraryString() {
+        assertThat(MailQueueName.fromString("whatever")).isNotNull();
+    }
+
+    @Test
+    void fromRabbitWorkQueueNameShouldThrowWhenNull() {
+        assertThatThrownBy(() -> MailQueueName.fromRabbitWorkQueueName(null))
+            .isInstanceOf(NullPointerException.class);
+    }
+
+    @Test
+    void fromRabbitWorkQueueNameShouldReturnEmptyWhenArbitraryString() {
+        assertThat(MailQueueName.fromRabbitWorkQueueName("whatever"))
+            .isEmpty();
+    }
+
+    @Test
+    void fromRabbitWorkQueueNameShouldReturnInstanceWhenPrefixOnlyString() {
+        assertThat(MailQueueName.fromRabbitWorkQueueName(MailQueueName.WORKQUEUE_PREFIX))
+            .contains(MailQueueName.fromString(""));
+    }
+
+    @Test
+    void fromRabbitWorkQueueNameShouldReturnInstanceWhenValidQueueName() {
+        assertThat(MailQueueName.fromRabbitWorkQueueName(MailQueueName.WORKQUEUE_PREFIX +
"myQueue"))
+            .contains(MailQueueName.fromString("myQueue"));
+    }
+
+    @Test
+    void shouldConformToBeanContract() {
+        EqualsVerifier.forClass(MailQueueName.class).verify();
+    }
+
+    @Test
+    void exchangeNameShouldConformToBeanContract() {
+        EqualsVerifier.forClass(MailQueueName.ExchangeName.class).verify();
+    }
+
+    @Test
+    void workQueueNameShouldConformToBeanContract() {
+        EqualsVerifier.forClass(MailQueueName.WorkQueueName.class).verify();
+    }
+
+    @Test
+    void fromRabbitWorkQueueNameShouldReturnIdentityWhenToRabbitWorkQueueName() {
+        MailQueueName myQueue = MailQueueName.fromString("myQueue");
+        assertThat(MailQueueName.fromRabbitWorkQueueName(myQueue.toWorkQueueName().asString()))
+            .contains(myQueue);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/7afbf302/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/RabbitMqMailQueueFactoryTest.java
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/RabbitMqMailQueueFactoryTest.java
b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/RabbitMqMailQueueFactoryTest.java
new file mode 100644
index 0000000..028d125
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/RabbitMqMailQueueFactoryTest.java
@@ -0,0 +1,54 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.queue.rabbitmq;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.http.client.utils.URIBuilder;
+import org.apache.james.queue.api.MailQueueFactory;
+import org.apache.james.queue.api.MailQueueFactoryContract;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(DockerRabbitMQExtension.class)
+class RabbitMqMailQueueFactoryTest implements MailQueueFactoryContract<RabbitMQMailQueue>
{
+
+    private RabbitMQMailQueueFactory mailQueueFactory;
+
+    @BeforeEach
+    void setup(DockerRabbitMQ rabbitMQ) throws IOException, TimeoutException, URISyntaxException
{
+        URI rabbitManagementUri = new URIBuilder()
+            .setScheme("http")
+            .setHost(rabbitMQ.getHostIp())
+            .setPort(rabbitMQ.getAdminPort())
+            .build();
+        mailQueueFactory = new RabbitMQMailQueueFactory(
+            rabbitMQ.connectionFactory().newConnection(),
+            new RabbitMQManagementApi(rabbitManagementUri, new RabbitMQManagementCredentials("guest",
"guest".toCharArray())));
+    }
+
+    @Override
+    public MailQueueFactory<RabbitMQMailQueue> getMailQueueFactory() {
+        return mailQueueFactory;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/7afbf302/server/queue/queue-rabbitmq/src/test/resources/logback-test.xml
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/test/resources/logback-test.xml b/server/queue/queue-rabbitmq/src/test/resources/logback-test.xml
index 5486d86..fc25fca 100644
--- a/server/queue/queue-rabbitmq/src/test/resources/logback-test.xml
+++ b/server/queue/queue-rabbitmq/src/test/resources/logback-test.xml
@@ -1,23 +1,19 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <configuration>
-
-        <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
-                <resetJUL>true</resetJUL>
-        </contextListener>
-
         <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+                <immediateFlush>false</immediateFlush>
                 <encoder>
                         <pattern>%d{HH:mm:ss.SSS} [%-5level] %logger{15} - %msg%n%rEx</pattern>
-                        <immediateFlush>false</immediateFlush>
                 </encoder>
         </appender>
 
+        <logger name="org.testcontainers" level="ERROR"/>
+        <logger name="org.apache.james" level="WARN"/>
+        <logger name="org.apache.james.queue.rabbitmq.DockerRabbitMQ" level="WARN"/>
+
         <root level="ERROR">
                 <appender-ref ref="CONSOLE" />
         </root>
 
-        <logger name="org.testcontainers" level="ERROR"/>
-        <logger name="org.apache.james" level="WARN"/>
-        <logger name="org.apache.james.queue.rabbitmq.DockerRabbitMQ" level="WARN"/>
 
 </configuration>

http://git-wip-us.apache.org/repos/asf/james-project/blob/7afbf302/server/testing/src/main/java/org/apache/james/util/docker/Images.java
----------------------------------------------------------------------
diff --git a/server/testing/src/main/java/org/apache/james/util/docker/Images.java b/server/testing/src/main/java/org/apache/james/util/docker/Images.java
index c252f1a..78d57ad 100644
--- a/server/testing/src/main/java/org/apache/james/util/docker/Images.java
+++ b/server/testing/src/main/java/org/apache/james/util/docker/Images.java
@@ -21,7 +21,7 @@ package org.apache.james.util.docker;
 
 public interface Images {
     String FAKE_SMTP = "weave/rest-smtp-sink:latest";
-    String RABBITMQ = "rabbitmq:3.7.7";
+    String RABBITMQ = "rabbitmq:3.7.7-management";
     String ELASTICSEARCH = "elasticsearch:2.4.6";
     String NGINX = "nginx:1.15.1";
     String TIKA = "linagora/docker-tikaserver:1.18-SNAPSHOT-plus-TIKA-2520";


---------------------------------------------------------------------
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