Repository: james-project Updated Branches: refs/heads/master 269e35915 -> 02d3f17ac
JAMES-2540 Adding deque metrics and metric mailqueue contract Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/2c8c0499 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/2c8c0499 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/2c8c0499 Branch: refs/heads/master Commit: 2c8c04991b0c11f4b79190e81dabe498ef668af6 Parents: 269e359 Author: duc <[email protected]> Authored: Wed Sep 5 15:07:02 2018 +0700 Committer: Antoine Duprat <[email protected]> Committed: Fri Sep 7 08:21:49 2018 +0200 ---------------------------------------------------------------------- .../META-INF/org/apache/james/spring-server.xml | 4 + .../james/queue/activemq/ActiveMQMailQueue.java | 11 +- .../activemq/ActiveMQMailQueueFactory.java | 12 +- .../META-INF/spring/activemq-queue-context.xml | 1 + .../activemq/ActiveMQMailQueueBlobTest.java | 15 ++- .../activemq/ActiveMQMailQueueFactoryTest.java | 7 +- .../queue/activemq/ActiveMQMailQueueTest.java | 15 ++- server/queue/queue-api/pom.xml | 5 + .../org/apache/james/queue/api/MailQueue.java | 6 + .../queue/api/MailQueueMetricContract.java | 110 +++++++++++++++++++ .../queue/api/MailQueueMetricExtension.java | 89 +++++++++++++++ .../apache/james/queue/jms/JMSMailQueue.java | 22 +++- .../james/queue/jms/JMSMailQueueFactory.java | 10 +- .../queue/jms/JMSMailQueueFactoryTest.java | 5 +- .../james/queue/jms/JMSMailQueueTest.java | 14 ++- 15 files changed, 291 insertions(+), 35 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml ---------------------------------------------------------------------- diff --git a/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml b/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml index 78b0d71..fa12ef6 100644 --- a/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml +++ b/server/container/spring/src/main/resources/META-INF/org/apache/james/spring-server.xml @@ -306,6 +306,10 @@ <constructor-arg index="0" ref="metricRegistry"/> </bean> + <bean id="gaugeRegistry" class="org.apache.james.metrics.dropwizard.DropWizardGaugeRegistry"> + <constructor-arg index="0" ref="metricRegistry"/> + </bean> + <bean id="metricRegistry" class="com.codahale.metrics.MetricRegistry"/> <!-- http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/queue/queue-activemq/src/main/java/org/apache/james/queue/activemq/ActiveMQMailQueue.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-activemq/src/main/java/org/apache/james/queue/activemq/ActiveMQMailQueue.java b/server/queue/queue-activemq/src/main/java/org/apache/james/queue/activemq/ActiveMQMailQueue.java index 3247347..5a52f27 100644 --- a/server/queue/queue-activemq/src/main/java/org/apache/james/queue/activemq/ActiveMQMailQueue.java +++ b/server/queue/queue-activemq/src/main/java/org/apache/james/queue/activemq/ActiveMQMailQueue.java @@ -39,6 +39,7 @@ import org.apache.activemq.ActiveMQSession; import org.apache.activemq.BlobMessage; import org.apache.activemq.command.ActiveMQBlobMessage; import org.apache.activemq.util.JMSExceptionSupport; +import org.apache.james.metrics.api.GaugeRegistry; import org.apache.james.metrics.api.MetricFactory; import org.apache.james.queue.api.MailQueue; import org.apache.james.queue.api.MailQueueItemDecoratorFactory; @@ -93,8 +94,9 @@ public class ActiveMQMailQueue extends JMSMailQueue implements ActiveMQSupport { * Construct a {@link ActiveMQMailQueue} which only use {@link BlobMessage} * */ - public ActiveMQMailQueue(ConnectionFactory connectionFactory, MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory, String queuename, MetricFactory metricFactory) { - this(connectionFactory, mailQueueItemDecoratorFactory, queuename, true, metricFactory); + public ActiveMQMailQueue(ConnectionFactory connectionFactory, MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory, String queuename, MetricFactory metricFactory, + GaugeRegistry gaugeRegistry) { + this(connectionFactory, mailQueueItemDecoratorFactory, queuename, true, metricFactory, gaugeRegistry); } /** @@ -104,8 +106,9 @@ public class ActiveMQMailQueue extends JMSMailQueue implements ActiveMQSupport { * @param queuename * @param useBlob */ - public ActiveMQMailQueue(ConnectionFactory connectionFactory, MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory, String queuename, boolean useBlob, MetricFactory metricFactory) { - super(connectionFactory, mailQueueItemDecoratorFactory, queuename, metricFactory); + public ActiveMQMailQueue(ConnectionFactory connectionFactory, MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory, String queuename, boolean useBlob, MetricFactory metricFactory, + GaugeRegistry gaugeRegistry) { + super(connectionFactory, mailQueueItemDecoratorFactory, queuename, metricFactory, gaugeRegistry); this.useBlob = useBlob; } http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/queue/queue-activemq/src/main/java/org/apache/james/queue/activemq/ActiveMQMailQueueFactory.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-activemq/src/main/java/org/apache/james/queue/activemq/ActiveMQMailQueueFactory.java b/server/queue/queue-activemq/src/main/java/org/apache/james/queue/activemq/ActiveMQMailQueueFactory.java index 011143f..5008508 100644 --- a/server/queue/queue-activemq/src/main/java/org/apache/james/queue/activemq/ActiveMQMailQueueFactory.java +++ b/server/queue/queue-activemq/src/main/java/org/apache/james/queue/activemq/ActiveMQMailQueueFactory.java @@ -21,6 +21,7 @@ package org.apache.james.queue.activemq; import javax.inject.Inject; import javax.jms.ConnectionFactory; +import org.apache.james.metrics.api.GaugeRegistry; import org.apache.james.metrics.api.MetricFactory; import org.apache.james.queue.api.MailQueueFactory; import org.apache.james.queue.api.MailQueueItemDecoratorFactory; @@ -35,13 +36,14 @@ public class ActiveMQMailQueueFactory extends JMSMailQueueFactory { private boolean useBlob = true; - public ActiveMQMailQueueFactory(ConnectionFactory connectionFactory, MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory, MetricFactory metricFactory) { - super(connectionFactory, mailQueueItemDecoratorFactory, metricFactory); + public ActiveMQMailQueueFactory(ConnectionFactory connectionFactory, MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory, MetricFactory metricFactory, + GaugeRegistry gaugeRegistry) { + super(connectionFactory, mailQueueItemDecoratorFactory, metricFactory, gaugeRegistry); } @Inject - public ActiveMQMailQueueFactory(EmbeddedActiveMQ embeddedActiveMQ, MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory, MetricFactory metricFactory) { - this(embeddedActiveMQ.getConnectionFactory(), mailQueueItemDecoratorFactory, metricFactory); + public ActiveMQMailQueueFactory(EmbeddedActiveMQ embeddedActiveMQ, MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory, MetricFactory metricFactory, GaugeRegistry gaugeRegistry) { + this(embeddedActiveMQ.getConnectionFactory(), mailQueueItemDecoratorFactory, metricFactory, gaugeRegistry); } public void setUseBlobMessages(boolean useBlob) { @@ -50,6 +52,6 @@ public class ActiveMQMailQueueFactory extends JMSMailQueueFactory { @Override protected ManageableMailQueue createMailQueue(String name) { - return new ActiveMQMailQueue(connectionFactory, mailQueueItemDecoratorFactory, name, useBlob, metricFactory); + return new ActiveMQMailQueue(connectionFactory, mailQueueItemDecoratorFactory, name, useBlob, metricFactory, gaugeRegistry); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/queue/queue-activemq/src/main/resources/META-INF/spring/activemq-queue-context.xml ---------------------------------------------------------------------- diff --git a/server/queue/queue-activemq/src/main/resources/META-INF/spring/activemq-queue-context.xml b/server/queue/queue-activemq/src/main/resources/META-INF/spring/activemq-queue-context.xml index 5f5f086..b82e377 100644 --- a/server/queue/queue-activemq/src/main/resources/META-INF/spring/activemq-queue-context.xml +++ b/server/queue/queue-activemq/src/main/resources/META-INF/spring/activemq-queue-context.xml @@ -25,6 +25,7 @@ <constructor-arg index="0" ref="embeddedActiveMQ"/> <constructor-arg index="1" ref="rawMailQueueItemDecoratorFactory"/> <constructor-arg index="2" ref="metricFactory"/> + <constructor-arg index="3" ref="gaugeRegistry"/> </bean> <bean id="rawMailQueueItemDecoratorFactory" class="org.apache.james.queue.api.RawMailQueueItemDecoratorFactory"/> http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueBlobTest.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueBlobTest.java b/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueBlobTest.java index 3cb606e..0c18d71 100644 --- a/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueBlobTest.java +++ b/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueBlobTest.java @@ -30,10 +30,13 @@ import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.broker.BrokerService; import org.apache.commons.io.FileUtils; import org.apache.james.filesystem.api.FileSystem; -import org.apache.james.metrics.api.NoopMetricFactory; +import org.apache.james.metrics.api.GaugeRegistry; +import org.apache.james.metrics.api.MetricFactory; import org.apache.james.queue.api.DelayedManageableMailQueueContract; import org.apache.james.queue.api.DelayedPriorityMailQueueContract; import org.apache.james.queue.api.MailQueue; +import org.apache.james.queue.api.MailQueueMetricContract; +import org.apache.james.queue.api.MailQueueMetricExtension; import org.apache.james.queue.api.ManageableMailQueue; import org.apache.james.queue.api.PriorityManageableMailQueueContract; import org.apache.james.queue.api.RawMailQueueItemDecoratorFactory; @@ -49,7 +52,8 @@ import org.slf4j.LoggerFactory; @ExtendWith(BrokerExtension.class) @Tag(BrokerExtension.STATISTICS) -public class ActiveMQMailQueueBlobTest implements DelayedManageableMailQueueContract, DelayedPriorityMailQueueContract, PriorityManageableMailQueueContract { +public class ActiveMQMailQueueBlobTest implements DelayedManageableMailQueueContract, DelayedPriorityMailQueueContract, PriorityManageableMailQueueContract, + MailQueueMetricContract { static final String BASE_DIR = "file://target/james-test"; static final boolean USE_BLOB = true; @@ -58,7 +62,7 @@ public class ActiveMQMailQueueBlobTest implements DelayedManageableMailQueueCont MyFileSystem fileSystem; @BeforeEach - public void setUp(BrokerService broker) { + public void setUp(BrokerService broker, MailQueueMetricExtension.MailQueueMetricTestSystem metricTestSystem) { fileSystem = new MyFileSystem(); ActiveMQConnectionFactory connectionFactory = createConnectionFactory(); FileSystemBlobTransferPolicy policy = new FileSystemBlobTransferPolicy(); @@ -67,9 +71,10 @@ public class ActiveMQMailQueueBlobTest implements DelayedManageableMailQueueCont connectionFactory.setBlobTransferPolicy(policy); RawMailQueueItemDecoratorFactory mailQueueItemDecoratorFactory = new RawMailQueueItemDecoratorFactory(); - NoopMetricFactory metricFactory = new NoopMetricFactory(); + MetricFactory metricFactory = metricTestSystem.getSpyMetricFactory(); + GaugeRegistry gaugeRegistry = metricTestSystem.getSpyGaugeRegistry(); String queueName = BrokerExtension.generateRandomQueueName(broker); - mailQueue = new ActiveMQMailQueue(connectionFactory, mailQueueItemDecoratorFactory, queueName, USE_BLOB, metricFactory); + mailQueue = new ActiveMQMailQueue(connectionFactory, mailQueueItemDecoratorFactory, queueName, USE_BLOB, metricFactory, gaugeRegistry); } @AfterEach http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueFactoryTest.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueFactoryTest.java b/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueFactoryTest.java index ef98473..e50e9d4 100644 --- a/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueFactoryTest.java +++ b/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueFactoryTest.java @@ -23,6 +23,7 @@ import javax.jms.ConnectionFactory; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.broker.BrokerService; +import org.apache.james.metrics.api.NoopGaugeRegistry; import org.apache.james.metrics.api.NoopMetricFactory; import org.apache.james.queue.api.MailQueueFactory; import org.apache.james.queue.api.MailQueueFactoryContract; @@ -47,7 +48,8 @@ public class ActiveMQMailQueueFactoryTest { ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?create=false"); RawMailQueueItemDecoratorFactory mailQueueItemDecoratorFactory = new RawMailQueueItemDecoratorFactory(); NoopMetricFactory metricFactory = new NoopMetricFactory(); - mailQueueFactory = new ActiveMQMailQueueFactory(connectionFactory, mailQueueItemDecoratorFactory, metricFactory); + NoopGaugeRegistry gaugeRegistry = new NoopGaugeRegistry(); + mailQueueFactory = new ActiveMQMailQueueFactory(connectionFactory, mailQueueItemDecoratorFactory, metricFactory, gaugeRegistry); mailQueueFactory.setUseJMX(false); mailQueueFactory.setUseBlobMessages(false); } @@ -85,7 +87,8 @@ public class ActiveMQMailQueueFactoryTest { RawMailQueueItemDecoratorFactory mailQueueItemDecoratorFactory = new RawMailQueueItemDecoratorFactory(); NoopMetricFactory metricFactory = new NoopMetricFactory(); - mailQueueFactory = new ActiveMQMailQueueFactory(connectionFactory, mailQueueItemDecoratorFactory, metricFactory); + NoopGaugeRegistry gaugeRegistry = new NoopGaugeRegistry(); + mailQueueFactory = new ActiveMQMailQueueFactory(connectionFactory, mailQueueItemDecoratorFactory, metricFactory, gaugeRegistry); mailQueueFactory.setUseJMX(false); mailQueueFactory.setUseBlobMessages(true); } http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueTest.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueTest.java b/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueTest.java index 4593b60..650eca2 100644 --- a/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueTest.java +++ b/server/queue/queue-activemq/src/test/java/org/apache/james/queue/activemq/ActiveMQMailQueueTest.java @@ -24,10 +24,13 @@ import javax.jms.ConnectionFactory; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.broker.BrokerService; -import org.apache.james.metrics.api.NoopMetricFactory; +import org.apache.james.metrics.api.GaugeRegistry; +import org.apache.james.metrics.api.MetricFactory; import org.apache.james.queue.api.DelayedManageableMailQueueContract; import org.apache.james.queue.api.DelayedPriorityMailQueueContract; import org.apache.james.queue.api.MailQueue; +import org.apache.james.queue.api.MailQueueMetricContract; +import org.apache.james.queue.api.MailQueueMetricExtension; import org.apache.james.queue.api.ManageableMailQueue; import org.apache.james.queue.api.PriorityManageableMailQueueContract; import org.apache.james.queue.api.RawMailQueueItemDecoratorFactory; @@ -41,19 +44,21 @@ import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(BrokerExtension.class) @Tag(BrokerExtension.STATISTICS) -public class ActiveMQMailQueueTest implements DelayedManageableMailQueueContract, DelayedPriorityMailQueueContract, PriorityManageableMailQueueContract { +public class ActiveMQMailQueueTest implements DelayedManageableMailQueueContract, DelayedPriorityMailQueueContract, PriorityManageableMailQueueContract, + MailQueueMetricContract { static final boolean USE_BLOB = true; ActiveMQMailQueue mailQueue; @BeforeEach - public void setUp(BrokerService broker) throws Exception { + public void setUp(BrokerService broker, MailQueueMetricExtension.MailQueueMetricTestSystem metricTestSystem) throws Exception { ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?create=false"); RawMailQueueItemDecoratorFactory mailQueueItemDecoratorFactory = new RawMailQueueItemDecoratorFactory(); - NoopMetricFactory metricFactory = new NoopMetricFactory(); + MetricFactory metricFactory = metricTestSystem.getSpyMetricFactory(); + GaugeRegistry gaugeRegistry = metricTestSystem.getSpyGaugeRegistry(); String queueName = BrokerExtension.generateRandomQueueName(broker); - mailQueue = new ActiveMQMailQueue(connectionFactory, mailQueueItemDecoratorFactory, queueName, !USE_BLOB, metricFactory); + mailQueue = new ActiveMQMailQueue(connectionFactory, mailQueueItemDecoratorFactory, queueName, !USE_BLOB, metricFactory, gaugeRegistry); } @AfterEach http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/queue/queue-api/pom.xml ---------------------------------------------------------------------- diff --git a/server/queue/queue-api/pom.xml b/server/queue/queue-api/pom.xml index cfdc624..3d12198 100644 --- a/server/queue/queue-api/pom.xml +++ b/server/queue/queue-api/pom.xml @@ -64,6 +64,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>${james.groupId}</groupId> + <artifactId>metrics-api</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> </dependency> http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/queue/queue-api/src/main/java/org/apache/james/queue/api/MailQueue.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-api/src/main/java/org/apache/james/queue/api/MailQueue.java b/server/queue/queue-api/src/main/java/org/apache/james/queue/api/MailQueue.java index 4dcf82b..6c74bcd 100644 --- a/server/queue/queue-api/src/main/java/org/apache/james/queue/api/MailQueue.java +++ b/server/queue/queue-api/src/main/java/org/apache/james/queue/api/MailQueue.java @@ -57,6 +57,12 @@ import org.apache.mailet.Mail; */ public interface MailQueue { + String ENQUEUED_METRIC_NAME_PREFIX = "enqueuedMail:"; + String DEQUEUED_METRIC_NAME_PREFIX = "dequeuedMail:"; + String ENQUEUED_TIMER_METRIC_NAME_PREFIX = "enqueueTime:"; + String DEQUEUED_TIMER_METRIC_NAME_PREFIX = "dequeueTime:"; + String QUEUE_SIZE_METRIC_NAME_PREFIX = "mailQueueSize:"; + /** * No delay for queued {@link MailQueueItem} */ http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/queue/queue-api/src/test/java/org/apache/james/queue/api/MailQueueMetricContract.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-api/src/test/java/org/apache/james/queue/api/MailQueueMetricContract.java b/server/queue/queue-api/src/test/java/org/apache/james/queue/api/MailQueueMetricContract.java new file mode 100644 index 0000000..9749456 --- /dev/null +++ b/server/queue/queue-api/src/test/java/org/apache/james/queue/api/MailQueueMetricContract.java @@ -0,0 +1,110 @@ +/**************************************************************** + * 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.api; + +import static org.apache.james.queue.api.Mails.defaultMail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import java.util.stream.IntStream; + +import javax.mail.MessagingException; + +import org.apache.james.metrics.api.Gauge; +import org.apache.mailet.base.test.FakeMail; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; + +import com.github.fge.lambdas.Throwing; + +@ExtendWith(MailQueueMetricExtension.class) +public interface MailQueueMetricContract extends MailQueueContract { + + default FakeMail fakeMail() throws MessagingException { + return defaultMail() + .name("name1") + .build(); + } + + default void enQueueMail(Integer times) throws Exception { + IntStream + .rangeClosed(1, times) + .forEach(Throwing.intConsumer(time -> getMailQueue().enQueue(fakeMail()))); + } + + default void deQueueMail(Integer times) throws Exception { + IntStream + .rangeClosed(1, times) + .forEach(Throwing.intConsumer(time -> getMailQueue().deQueue().done(true))); + } + + @Test + default void constructorShouldRegisterGetQueueSizeGauge(MailQueueMetricExtension.MailQueueMetricTestSystem testSystem) throws Exception { + enQueueMail(3); + + ArgumentCaptor<Gauge> gaugeCaptor = ArgumentCaptor.forClass(Gauge.class); + verify(testSystem.getSpyGaugeRegistry(), times(1)).register(any(), gaugeCaptor.capture()); + Mockito.verifyNoMoreInteractions(testSystem.getSpyGaugeRegistry()); + + Gauge registeredGauge = gaugeCaptor.getValue(); + Assertions.assertThat(registeredGauge.get()).isEqualTo(3L); + } + + @Test + default void enqueueShouldIncreaseEnQueueMetric(MailQueueMetricExtension.MailQueueMetricTestSystem testSystem) throws Exception { + enQueueMail(2); + + verify(testSystem.getMockEnqueuedMailsMetric(), times(2)).increment(); + Mockito.verifyNoMoreInteractions(testSystem.getMockEnqueuedMailsMetric()); + } + + @Test + default void enqueueShouldNotTouchDequeueMetric(MailQueueMetricExtension.MailQueueMetricTestSystem testSystem) throws Exception { + enQueueMail(2); + + verify(testSystem.getMockEnqueuedMailsMetric(), times(2)).increment(); + Mockito.verifyNoMoreInteractions(testSystem.getMockDequeuedMailsMetric()); + } + + @Test + default void dequeueShouldIncreaseDequeueMetric(MailQueueMetricExtension.MailQueueMetricTestSystem testSystem) throws Exception { + enQueueMail(2); + deQueueMail(2); + + verify(testSystem.getMockDequeuedMailsMetric(), times(2)).increment(); + Mockito.verifyNoMoreInteractions(testSystem.getMockDequeuedMailsMetric()); + } + + @Test + default void dequeueShouldNotTouchEnqueueMetric(MailQueueMetricExtension.MailQueueMetricTestSystem testSystem) throws Exception { + enQueueMail(2); + deQueueMail(2); + + verify(testSystem.getMockDequeuedMailsMetric(), times(2)).increment(); + Mockito.verifyNoMoreInteractions(testSystem.getMockDequeuedMailsMetric()); + + verify(testSystem.getMockEnqueuedMailsMetric(), times(2)).increment(); + Mockito.verifyNoMoreInteractions(testSystem.getMockEnqueuedMailsMetric()); + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/queue/queue-api/src/test/java/org/apache/james/queue/api/MailQueueMetricExtension.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-api/src/test/java/org/apache/james/queue/api/MailQueueMetricExtension.java b/server/queue/queue-api/src/test/java/org/apache/james/queue/api/MailQueueMetricExtension.java new file mode 100644 index 0000000..d4ea362 --- /dev/null +++ b/server/queue/queue-api/src/test/java/org/apache/james/queue/api/MailQueueMetricExtension.java @@ -0,0 +1,89 @@ +/**************************************************************** + * 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.api; + +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.apache.james.metrics.api.GaugeRegistry; +import org.apache.james.metrics.api.Metric; +import org.apache.james.metrics.api.MetricFactory; +import org.apache.james.metrics.api.NoopGaugeRegistry; +import org.apache.james.metrics.api.NoopMetricFactory; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolutionException; +import org.junit.jupiter.api.extension.ParameterResolver; +import org.mockito.Mockito; + +public class MailQueueMetricExtension implements BeforeEachCallback, ParameterResolver { + + public class MailQueueMetricTestSystem { + private final Metric mockEnqueuedMailsMetric; + private final Metric mockDequeuedMailsMetric; + private final GaugeRegistry spyGaugeRegistry; + private final MetricFactory spyMetricFactory; + + public MailQueueMetricTestSystem() { + mockEnqueuedMailsMetric = mock(Metric.class); + mockDequeuedMailsMetric = mock(Metric.class); + spyGaugeRegistry = Mockito.spy(new NoopGaugeRegistry()); + spyMetricFactory = Mockito.spy(new NoopMetricFactory()); + } + + public Metric getMockEnqueuedMailsMetric() { + return mockEnqueuedMailsMetric; + } + + public Metric getMockDequeuedMailsMetric() { + return mockDequeuedMailsMetric; + } + + public GaugeRegistry getSpyGaugeRegistry() { + return spyGaugeRegistry; + } + + public MetricFactory getSpyMetricFactory() { + return spyMetricFactory; + } + } + + private MailQueueMetricTestSystem testSystem; + + @Override + public void beforeEach(ExtensionContext extensionContext) throws Exception { + testSystem = new MailQueueMetricTestSystem(); + + when(testSystem.spyMetricFactory.generate(anyString())) + .thenReturn(testSystem.mockEnqueuedMailsMetric, testSystem.mockDequeuedMailsMetric); + } + + @Override + public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { + return parameterContext.getParameter().getType() == MailQueueMetricTestSystem.class; + } + + @Override + public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { + return testSystem; + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java b/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java index a60bde2..94092c2 100644 --- a/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java +++ b/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueue.java @@ -52,6 +52,8 @@ import javax.mail.internet.MimeMessage; import org.apache.commons.collections.iterators.EnumerationIterator; import org.apache.james.core.MailAddress; import org.apache.james.lifecycle.api.Disposable; +import org.apache.james.metrics.api.Gauge; +import org.apache.james.metrics.api.GaugeRegistry; import org.apache.james.metrics.api.Metric; import org.apache.james.metrics.api.MetricFactory; import org.apache.james.metrics.api.TimeMetric; @@ -143,8 +145,9 @@ public class JMSMailQueue implements ManageableMailQueue, JMSSupport, MailPriori protected final Connection connection; protected final MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory; protected final Metric enqueuedMailsMetric; - protected final Metric mailQueueSize; + protected final Metric dequeuedMailsMetric; protected final MetricFactory metricFactory; + protected final GaugeRegistry gaugeRegistry; protected final Session session; protected final Queue queue; @@ -153,7 +156,9 @@ public class JMSMailQueue implements ManageableMailQueue, JMSSupport, MailPriori private final Joiner joiner; private final Splitter splitter; - public JMSMailQueue(ConnectionFactory connectionFactory, MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory, String queueName, MetricFactory metricFactory) { + public JMSMailQueue(ConnectionFactory connectionFactory, MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory, + String queueName, MetricFactory metricFactory, + GaugeRegistry gaugeRegistry) { try { connection = connectionFactory.createConnection(); connection.start(); @@ -164,7 +169,10 @@ public class JMSMailQueue implements ManageableMailQueue, JMSSupport, MailPriori this.queueName = queueName; this.metricFactory = metricFactory; this.enqueuedMailsMetric = metricFactory.generate("enqueuedMail:" + queueName); - this.mailQueueSize = metricFactory.generate("mailQueueSize:" + queueName); + this.dequeuedMailsMetric = metricFactory.generate("dequeuedMail:" + queueName); + + this.gaugeRegistry = gaugeRegistry; + this.gaugeRegistry.register(QUEUE_SIZE_METRIC_NAME_PREFIX + queueName, queueSizeGauge()); this.joiner = Joiner.on(JAMES_MAIL_SEPARATOR).skipNulls(); this.splitter = Splitter.on(JAMES_MAIL_SEPARATOR) @@ -211,7 +219,7 @@ public class JMSMailQueue implements ManageableMailQueue, JMSSupport, MailPriori Message message = consumer.receive(10000); if (message != null) { - mailQueueSize.decrement(); + dequeuedMailsMetric.increment(); return createMailQueueItem(session, consumer, message); } else { session.commit(); @@ -245,11 +253,9 @@ public class JMSMailQueue implements ManageableMailQueue, JMSSupport, MailPriori } Map<String, Object> props = getJMSProperties(mail, nextDeliveryTimestamp); - produceMail(props, msgPrio, mail); enqueuedMailsMetric.increment(); - mailQueueSize.increment(); } catch (Exception e) { throw new MailQueueException("Unable to enqueue mail " + mail, e); } finally { @@ -451,6 +457,10 @@ public class JMSMailQueue implements ManageableMailQueue, JMSSupport, MailPriori } } + private Gauge<Long> queueSizeGauge() { + return () -> Throwing.supplier(this::getSize).get(); + } + @Override public String toString() { return "MailQueue:" + queueName; http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueueFactory.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueueFactory.java b/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueueFactory.java index 12f79c5..051e3c0 100644 --- a/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueueFactory.java +++ b/server/queue/queue-jms/src/main/java/org/apache/james/queue/jms/JMSMailQueueFactory.java @@ -21,6 +21,7 @@ package org.apache.james.queue.jms; import javax.inject.Inject; import javax.jms.ConnectionFactory; +import org.apache.james.metrics.api.GaugeRegistry; import org.apache.james.metrics.api.MetricFactory; import org.apache.james.queue.api.MailQueueFactory; import org.apache.james.queue.api.MailQueueItemDecoratorFactory; @@ -35,17 +36,20 @@ public class JMSMailQueueFactory extends AbstractMailQueueFactory<ManageableMail protected final ConnectionFactory connectionFactory; protected final MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory; protected final MetricFactory metricFactory; - + protected final GaugeRegistry gaugeRegistry; + @Inject - public JMSMailQueueFactory(ConnectionFactory connectionFactory, MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory, MetricFactory metricFactory) { + public JMSMailQueueFactory(ConnectionFactory connectionFactory, MailQueueItemDecoratorFactory mailQueueItemDecoratorFactory, + MetricFactory metricFactory, GaugeRegistry gaugeRegistry) { this.connectionFactory = connectionFactory; this.mailQueueItemDecoratorFactory = mailQueueItemDecoratorFactory; this.metricFactory = metricFactory; + this.gaugeRegistry = gaugeRegistry; } @Override protected ManageableMailQueue createMailQueue(String name) { - return new JMSMailQueue(connectionFactory, mailQueueItemDecoratorFactory, name, metricFactory); + return new JMSMailQueue(connectionFactory, mailQueueItemDecoratorFactory, name, metricFactory, gaugeRegistry); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSMailQueueFactoryTest.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSMailQueueFactoryTest.java b/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSMailQueueFactoryTest.java index 5211ce6..c791d26 100644 --- a/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSMailQueueFactoryTest.java +++ b/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSMailQueueFactoryTest.java @@ -23,6 +23,8 @@ import javax.jms.ConnectionFactory; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.broker.BrokerService; +import org.apache.james.metrics.api.GaugeRegistry; +import org.apache.james.metrics.api.NoopGaugeRegistry; import org.apache.james.metrics.api.NoopMetricFactory; import org.apache.james.queue.api.MailQueueFactory; import org.apache.james.queue.api.MailQueueFactoryContract; @@ -44,7 +46,8 @@ public class JMSMailQueueFactoryTest implements MailQueueFactoryContract<Managea ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?create=false"); RawMailQueueItemDecoratorFactory mailQueueItemDecoratorFactory = new RawMailQueueItemDecoratorFactory(); NoopMetricFactory metricFactory = new NoopMetricFactory(); - mailQueueFactory = new JMSMailQueueFactory(connectionFactory, mailQueueItemDecoratorFactory, metricFactory); + GaugeRegistry gaugeRegistry = new NoopGaugeRegistry(); + mailQueueFactory = new JMSMailQueueFactory(connectionFactory, mailQueueItemDecoratorFactory, metricFactory, gaugeRegistry); mailQueueFactory.setUseJMX(false); } http://git-wip-us.apache.org/repos/asf/james-project/blob/2c8c0499/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSMailQueueTest.java ---------------------------------------------------------------------- diff --git a/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSMailQueueTest.java b/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSMailQueueTest.java index 826f42b..ce98b4a 100644 --- a/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSMailQueueTest.java +++ b/server/queue/queue-jms/src/test/java/org/apache/james/queue/jms/JMSMailQueueTest.java @@ -23,10 +23,14 @@ import javax.jms.ConnectionFactory; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.activemq.broker.BrokerService; +import org.apache.james.metrics.api.GaugeRegistry; +import org.apache.james.metrics.api.MetricFactory; import org.apache.james.metrics.api.NoopMetricFactory; import org.apache.james.queue.api.DelayedManageableMailQueueContract; import org.apache.james.queue.api.DelayedPriorityMailQueueContract; import org.apache.james.queue.api.MailQueue; +import org.apache.james.queue.api.MailQueueMetricContract; +import org.apache.james.queue.api.MailQueueMetricExtension; import org.apache.james.queue.api.ManageableMailQueue; import org.apache.james.queue.api.PriorityManageableMailQueueContract; import org.apache.james.queue.api.RawMailQueueItemDecoratorFactory; @@ -37,17 +41,19 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(BrokerExtension.class) -public class JMSMailQueueTest implements DelayedManageableMailQueueContract, PriorityManageableMailQueueContract, DelayedPriorityMailQueueContract { +public class JMSMailQueueTest implements DelayedManageableMailQueueContract, PriorityManageableMailQueueContract, DelayedPriorityMailQueueContract, + MailQueueMetricContract { private JMSMailQueue mailQueue; @BeforeEach - void setUp(BrokerService broker) { + void setUp(BrokerService broker, MailQueueMetricExtension.MailQueueMetricTestSystem metricTestSystem) { ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("vm://localhost?create=false"); RawMailQueueItemDecoratorFactory mailQueueItemDecoratorFactory = new RawMailQueueItemDecoratorFactory(); - NoopMetricFactory metricFactory = new NoopMetricFactory(); + MetricFactory metricFactory = metricTestSystem.getSpyMetricFactory(); + GaugeRegistry gaugeRegistry = metricTestSystem.getSpyGaugeRegistry(); String queueName = BrokerExtension.generateRandomQueueName(broker); - mailQueue = new JMSMailQueue(connectionFactory, mailQueueItemDecoratorFactory, queueName, metricFactory); + mailQueue = new JMSMailQueue(connectionFactory, mailQueueItemDecoratorFactory, queueName, metricFactory, gaugeRegistry); } @AfterEach --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
