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 <matth...@apache.org> Authored: Tue Sep 4 18:00:58 2018 +0200 Committer: Antoine Duprat <adup...@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-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org