You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2020/04/29 01:14:45 UTC
[james-project] 11/27: JAMES-3138 Task for recomputing current
quotas
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit ab4e4e3b1df2b4be221dfd233990582b0801a606
Author: Rene Cordier <rc...@linagora.com>
AuthorDate: Mon Apr 13 17:12:02 2020 +0700
JAMES-3138 Task for recomputing current quotas
---
.../org/apache/james/mailbox/model/QuotaRoot.java | 5 +
mailbox/tools/quota-recompute/pom.xml | 20 ++++
.../quota/task/RecomputeCurrentQuotasTask.java | 101 +++++++++++++++++++++
...eCurrentQuotasTaskAdditionalInformationDTO.java | 87 ++++++++++++++++++
.../quota/task/RecomputeCurrentQuotasTaskDTO.java | 57 ++++++++++++
...ecomputeCurrentQuotasTaskSerializationTest.java | 61 +++++++++++++
6 files changed, 331 insertions(+)
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/QuotaRoot.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/QuotaRoot.java
index c7a825a..1ad8d20 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/QuotaRoot.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/QuotaRoot.java
@@ -73,4 +73,9 @@ public class QuotaRoot {
.add("domain", domain)
.toString();
}
+
+ public String asString() {
+ return domain.map(domainValue -> value + "@" + domainValue.asString())
+ .orElse(value);
+ }
}
diff --git a/mailbox/tools/quota-recompute/pom.xml b/mailbox/tools/quota-recompute/pom.xml
index 34c21a7..2c59165 100644
--- a/mailbox/tools/quota-recompute/pom.xml
+++ b/mailbox/tools/quota-recompute/pom.xml
@@ -38,13 +38,33 @@
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
+ <artifactId>james-json</artifactId>
+ <scope>test</scope>
+ <type>test-jar</type>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
<artifactId>james-server-data-api</artifactId>
</dependency>
<dependency>
<groupId>${james.groupId}</groupId>
+ <artifactId>james-server-task-json</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>${james.groupId}</groupId>
<artifactId>testing-base</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>net.javacrumbs.json-unit</groupId>
+ <artifactId>json-unit-assertj</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git a/mailbox/tools/quota-recompute/src/main/java/org/apache/james/mailbox/quota/task/RecomputeCurrentQuotasTask.java b/mailbox/tools/quota-recompute/src/main/java/org/apache/james/mailbox/quota/task/RecomputeCurrentQuotasTask.java
new file mode 100644
index 0000000..050737b
--- /dev/null
+++ b/mailbox/tools/quota-recompute/src/main/java/org/apache/james/mailbox/quota/task/RecomputeCurrentQuotasTask.java
@@ -0,0 +1,101 @@
+/****************************************************************
+ * 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.mailbox.quota.task;
+
+import java.time.Clock;
+import java.time.Instant;
+import java.util.Optional;
+
+import org.apache.james.mailbox.model.QuotaRoot;
+import org.apache.james.mailbox.quota.task.RecomputeCurrentQuotasService.Context;
+import org.apache.james.mailbox.quota.task.RecomputeCurrentQuotasService.Context.Snapshot;
+import org.apache.james.task.Task;
+import org.apache.james.task.TaskExecutionDetails;
+import org.apache.james.task.TaskType;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.github.steveash.guavate.Guavate;
+import com.google.common.collect.ImmutableList;
+
+import reactor.core.scheduler.Schedulers;
+
+public class RecomputeCurrentQuotasTask implements Task {
+ static final TaskType RECOMPUTE_CURRENT_QUOTAS = TaskType.of("recompute-current-quotas");
+
+ public static class Details implements TaskExecutionDetails.AdditionalInformation {
+ private final Instant instant;
+ private final long processedQuotaRoots;
+ private final ImmutableList<String> failedQuotaRoots;
+
+ Details(Instant instant, long processedQuotaRoots, ImmutableList<String> failedQuotaRoots) {
+ this.instant = instant;
+ this.processedQuotaRoots = processedQuotaRoots;
+ this.failedQuotaRoots = failedQuotaRoots;
+ }
+
+ @Override
+ public Instant timestamp() {
+ return instant;
+ }
+
+ @JsonProperty("processedQuotaRoots")
+ long getProcessedQuotaRoots() {
+ return processedQuotaRoots;
+ }
+
+ @JsonProperty("failedQuotaRoots")
+ ImmutableList<String> getFailedQuotaRoots() {
+ return failedQuotaRoots;
+ }
+ }
+
+ private final RecomputeCurrentQuotasService service;
+
+ private Context context;
+
+ public RecomputeCurrentQuotasTask(RecomputeCurrentQuotasService service) {
+ this.service = service;
+ this.context = new Context();
+ }
+
+ @Override
+ public Task.Result run() {
+ return service.recomputeCurrentQuotas(context)
+ .subscribeOn(Schedulers.elastic())
+ .block();
+ }
+
+ @Override
+ public TaskType type() {
+ return RECOMPUTE_CURRENT_QUOTAS;
+ }
+
+ @Override
+ public Optional<TaskExecutionDetails.AdditionalInformation> details() {
+ Snapshot snapshot = context.snapshot();
+
+ return Optional.of(new Details(Clock.systemUTC().instant(),
+ snapshot.getProcessedQuotaRootCount(),
+ snapshot.getFailedQuotaRoots()
+ .stream()
+ .map(QuotaRoot::asString)
+ .collect(Guavate.toImmutableList())));
+ }
+}
diff --git a/mailbox/tools/quota-recompute/src/main/java/org/apache/james/mailbox/quota/task/RecomputeCurrentQuotasTaskAdditionalInformationDTO.java b/mailbox/tools/quota-recompute/src/main/java/org/apache/james/mailbox/quota/task/RecomputeCurrentQuotasTaskAdditionalInformationDTO.java
new file mode 100644
index 0000000..5bebcee
--- /dev/null
+++ b/mailbox/tools/quota-recompute/src/main/java/org/apache/james/mailbox/quota/task/RecomputeCurrentQuotasTaskAdditionalInformationDTO.java
@@ -0,0 +1,87 @@
+/****************************************************************
+ * 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.mailbox.quota.task;
+
+import java.time.Instant;
+
+import org.apache.james.json.DTOModule;
+import org.apache.james.server.task.json.dto.AdditionalInformationDTO;
+import org.apache.james.server.task.json.dto.AdditionalInformationDTOModule;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.collect.ImmutableList;
+
+public class RecomputeCurrentQuotasTaskAdditionalInformationDTO implements AdditionalInformationDTO {
+ private static RecomputeCurrentQuotasTaskAdditionalInformationDTO fromDomainObject(RecomputeCurrentQuotasTask.Details details, String type) {
+ return new RecomputeCurrentQuotasTaskAdditionalInformationDTO(
+ type,
+ details.getProcessedQuotaRoots(),
+ details.getFailedQuotaRoots(),
+ details.timestamp());
+ }
+
+ public static final AdditionalInformationDTOModule<RecomputeCurrentQuotasTask.Details, RecomputeCurrentQuotasTaskAdditionalInformationDTO> MODULE =
+ DTOModule
+ .forDomainObject(RecomputeCurrentQuotasTask.Details.class)
+ .convertToDTO(RecomputeCurrentQuotasTaskAdditionalInformationDTO.class)
+ .toDomainObjectConverter(RecomputeCurrentQuotasTaskAdditionalInformationDTO::toDomainObject)
+ .toDTOConverter(RecomputeCurrentQuotasTaskAdditionalInformationDTO::fromDomainObject)
+ .typeName(RecomputeCurrentQuotasTask.RECOMPUTE_CURRENT_QUOTAS.asString())
+ .withFactory(AdditionalInformationDTOModule::new);
+
+ private final String type;
+ private final long processedQuotaRoots;
+ private final ImmutableList<String> failedQuotaRoots;
+ private final Instant timestamp;
+
+ public RecomputeCurrentQuotasTaskAdditionalInformationDTO(@JsonProperty("type") String type,
+ @JsonProperty("processedQuotaRoots") long processedQuotaRoots,
+ @JsonProperty("failedQuotaRoots") ImmutableList<String> failedQuotaRoots,
+ @JsonProperty("timestamp") Instant timestamp) {
+ this.type = type;
+ this.processedQuotaRoots = processedQuotaRoots;
+ this.failedQuotaRoots = failedQuotaRoots;
+ this.timestamp = timestamp;
+ }
+
+ public long getProcessedQuotaRoots() {
+ return processedQuotaRoots;
+ }
+
+ public ImmutableList<String> getFailedQuotaRoots() {
+ return failedQuotaRoots;
+ }
+
+ @Override
+ public Instant getTimestamp() {
+ return timestamp;
+ }
+
+ @Override
+ public String getType() {
+ return type;
+ }
+
+ private RecomputeCurrentQuotasTask.Details toDomainObject() {
+ return new RecomputeCurrentQuotasTask.Details(timestamp,
+ processedQuotaRoots,
+ failedQuotaRoots);
+ }
+}
diff --git a/mailbox/tools/quota-recompute/src/main/java/org/apache/james/mailbox/quota/task/RecomputeCurrentQuotasTaskDTO.java b/mailbox/tools/quota-recompute/src/main/java/org/apache/james/mailbox/quota/task/RecomputeCurrentQuotasTaskDTO.java
new file mode 100644
index 0000000..33d5a4e
--- /dev/null
+++ b/mailbox/tools/quota-recompute/src/main/java/org/apache/james/mailbox/quota/task/RecomputeCurrentQuotasTaskDTO.java
@@ -0,0 +1,57 @@
+/****************************************************************
+ * 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.mailbox.quota.task;
+
+import org.apache.james.json.DTOModule;
+import org.apache.james.server.task.json.dto.TaskDTO;
+import org.apache.james.server.task.json.dto.TaskDTOModule;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class RecomputeCurrentQuotasTaskDTO implements TaskDTO {
+ private static RecomputeCurrentQuotasTaskDTO toDTO(RecomputeCurrentQuotasTask domainObject, String typeName) {
+ return new RecomputeCurrentQuotasTaskDTO(typeName);
+ }
+
+ public static TaskDTOModule<RecomputeCurrentQuotasTask, RecomputeCurrentQuotasTaskDTO> module(RecomputeCurrentQuotasService service) {
+ return DTOModule
+ .forDomainObject(RecomputeCurrentQuotasTask.class)
+ .convertToDTO(RecomputeCurrentQuotasTaskDTO.class)
+ .toDomainObjectConverter(dto -> dto.toDomainObject(service))
+ .toDTOConverter(RecomputeCurrentQuotasTaskDTO::toDTO)
+ .typeName(RecomputeCurrentQuotasTask.RECOMPUTE_CURRENT_QUOTAS.asString())
+ .withFactory(TaskDTOModule::new);
+ }
+
+ private final String type;
+
+ public RecomputeCurrentQuotasTaskDTO(@JsonProperty("type") String type) {
+ this.type = type;
+ }
+
+ private RecomputeCurrentQuotasTask toDomainObject(RecomputeCurrentQuotasService service) {
+ return new RecomputeCurrentQuotasTask(service);
+ }
+
+ @Override
+ public String getType() {
+ return type;
+ }
+}
diff --git a/mailbox/tools/quota-recompute/src/test/java/org/apache/james/mailbox/quota/task/RecomputeCurrentQuotasTaskSerializationTest.java b/mailbox/tools/quota-recompute/src/test/java/org/apache/james/mailbox/quota/task/RecomputeCurrentQuotasTaskSerializationTest.java
new file mode 100644
index 0000000..9eb7405
--- /dev/null
+++ b/mailbox/tools/quota-recompute/src/test/java/org/apache/james/mailbox/quota/task/RecomputeCurrentQuotasTaskSerializationTest.java
@@ -0,0 +1,61 @@
+/****************************************************************
+ * 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.mailbox.quota.task;
+
+import static org.mockito.Mockito.mock;
+
+import java.time.Instant;
+
+import org.apache.james.JsonSerializationVerifier;
+import org.junit.jupiter.api.Test;
+
+import com.google.common.collect.ImmutableList;
+
+class RecomputeCurrentQuotasTaskSerializationTest {
+ static final Instant TIMESTAMP = Instant.parse("2018-11-13T12:00:55Z");
+ static final String QUOTA_ROOT_AS_STRING = "bob@localhost";
+
+ static final RecomputeCurrentQuotasService SERVICE = mock(RecomputeCurrentQuotasService.class);
+ static final RecomputeCurrentQuotasTask TASK = new RecomputeCurrentQuotasTask(SERVICE);
+ static final String SERIALIZED_TASK = "{\"type\": \"recompute-current-quotas\"}";
+ static final RecomputeCurrentQuotasTask.Details DETAILS = new RecomputeCurrentQuotasTask.Details(TIMESTAMP, 12, ImmutableList.of(QUOTA_ROOT_AS_STRING));
+ static final String SERIALIZED_ADDITIONAL_INFORMATION = "{" +
+ " \"type\":\"recompute-current-quotas\"," +
+ " \"processedQuotaRoots\":12," +
+ " \"failedQuotaRoots\":[\"bob@localhost\"]," +
+ " \"timestamp\":\"2018-11-13T12:00:55Z\"" +
+ "}";
+
+ @Test
+ void taskShouldBeSerializable() throws Exception {
+ JsonSerializationVerifier.dtoModule(RecomputeCurrentQuotasTaskDTO.module(SERVICE))
+ .bean(TASK)
+ .json(SERIALIZED_TASK)
+ .verify();
+ }
+
+ @Test
+ void additionalInformationShouldBeSerializable() throws Exception {
+ JsonSerializationVerifier.dtoModule(RecomputeCurrentQuotasTaskAdditionalInformationDTO.MODULE)
+ .bean(DETAILS)
+ .json(SERIALIZED_ADDITIONAL_INFORMATION)
+ .verify();
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org