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/05/28 02:11:14 UTC
[james-project] 06/08: JAMES-3184 Expose RecomputeCurrentQuotasTask
RunningOptions over webadmin
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 a803f40081d78d56c8339d6669692fb40d2fdda4
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Thu May 21 15:26:01 2020 +0700
JAMES-3184 Expose RecomputeCurrentQuotasTask RunningOptions over webadmin
---
.../james/webadmin/routes/UserQuotaRoutes.java | 20 ++-
.../james/webadmin/routes/UserQuotaRoutesTest.java | 152 +++++++++++++++++++++
.../routes/WebAdminQuotaSearchTestSystem.java | 14 +-
3 files changed, 183 insertions(+), 3 deletions(-)
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserQuotaRoutes.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserQuotaRoutes.java
index 4201768..b34e12b 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserQuotaRoutes.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/routes/UserQuotaRoutes.java
@@ -89,9 +89,27 @@ public class UserQuotaRoutes implements Routes {
public static final String USER_QUOTAS_OPERATIONS_INJECTION_KEY = "userQuotasOperations";
public static class RecomputeCurrentQuotasRequestToTask extends TaskFromRequestRegistry.TaskRegistration {
+ private static final String USERS_PER_SECOND = "usersPerSecond";
+
@Inject
public RecomputeCurrentQuotasRequestToTask(RecomputeCurrentQuotasService service) {
- super(RECOMPUTE_CURRENT_QUOTAS, request -> new RecomputeCurrentQuotasTask(service, RunningOptions.DEFAULT));
+ super(RECOMPUTE_CURRENT_QUOTAS, request -> new RecomputeCurrentQuotasTask(service,parseRunningOptions(request)));
+ }
+
+ private static RunningOptions parseRunningOptions(Request request) {
+ return intQueryParameter(request)
+ .map(RunningOptions::withUsersPerSecond)
+ .orElse(RunningOptions.DEFAULT);
+ }
+
+ private static Optional<Integer> intQueryParameter(Request request) {
+ try {
+ return Optional.ofNullable(request.queryParams(USERS_PER_SECOND))
+ .map(Integer::parseInt);
+ } catch (NumberFormatException e) {
+ throw new IllegalArgumentException(String.format("Illegal value supplied for query parameter '%s', expecting a " +
+ "strictly positive optional integer", USERS_PER_SECOND), e);
+ }
}
}
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java
index d656dcc..e5e1825 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java
@@ -28,6 +28,9 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.notNullValue;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
@@ -51,6 +54,7 @@ import org.apache.james.mailbox.quota.MaxQuotaManager;
import org.apache.james.mailbox.quota.UserQuotaRootResolver;
import org.apache.james.quota.search.QuotaSearchTestSystem;
import org.apache.james.user.api.UsersRepository;
+import org.apache.james.webadmin.utils.ErrorResponder;
import org.assertj.core.api.SoftAssertions;
import org.eclipse.jetty.http.HttpStatus;
import org.junit.jupiter.api.BeforeEach;
@@ -1257,4 +1261,152 @@ class UserQuotaRoutesTest {
}
}
+
+ @Nested
+ @ExtendWith(ScanningQuotaSearchExtension.class)
+ class PostRecomputeQuotas {
+ @Test
+ void actionRequestParameterShouldBeCompulsory() {
+ when()
+ .post("/quota/users")
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(400))
+ .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+ .body("message", is("Invalid arguments supplied in the user request"))
+ .body("details", is("'task' query parameter is compulsory. Supported values are [RecomputeCurrentQuotas]"));
+ }
+
+ @Test
+ void postShouldFailUponEmptyAction() {
+ given()
+ .queryParam("task", "")
+ .post("/quota/users")
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(400))
+ .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+ .body("message", is("Invalid arguments supplied in the user request"))
+ .body("details", is("'task' query parameter cannot be empty or blank. Supported values are [RecomputeCurrentQuotas]"));
+ }
+
+ @Test
+ void postShouldFailUponInvalidAction() {
+ given()
+ .queryParam("task", "invalid")
+ .post("/quota/users")
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(400))
+ .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+ .body("message", is("Invalid arguments supplied in the user request"))
+ .body("details", is("Invalid value supplied for query parameter 'task': invalid. Supported values are [RecomputeCurrentQuotas]"));
+ }
+
+ @Test
+ void postShouldFailWhenUsersPerSecondIsNotAnInt() {
+ given()
+ .queryParam("task", "RecomputeCurrentQuotas")
+ .queryParam("usersPerSecond", "abc")
+ .post("/quota/users")
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(400))
+ .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+ .body("message", is("Invalid arguments supplied in the user request"))
+ .body("details", is("Illegal value supplied for query parameter 'usersPerSecond', expecting a strictly positive optional integer"));
+ }
+
+ @Test
+ void postShouldFailWhenUsersPerSecondIsNegative() {
+ given()
+ .queryParam("task", "RecomputeCurrentQuotas")
+ .queryParam("usersPerSecond", "-1")
+ .post("/quota/users")
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(400))
+ .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+ .body("message", is("Invalid arguments supplied in the user request"))
+ .body("details", is("'usersPerSecond' needs to be strictly positive"));
+ }
+
+ @Test
+ void postShouldFailWhenUsersPerSecondIsZero() {
+ given()
+ .queryParam("task", "RecomputeCurrentQuotas")
+ .queryParam("usersPerSecond", "0")
+ .post("/quota/users")
+ .then()
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(400))
+ .body("type", is(ErrorResponder.ErrorType.INVALID_ARGUMENT.getType()))
+ .body("message", is("Invalid arguments supplied in the user request"))
+ .body("details", is("'usersPerSecond' needs to be strictly positive"));
+ }
+
+ @Test
+ void postShouldCreateANewTask() {
+ given()
+ .queryParam("task", "RecomputeCurrentQuotas")
+ .post("/quota/users")
+ .then()
+ .statusCode(HttpStatus.CREATED_201)
+ .body("taskId", notNullValue());
+ }
+
+ @Test
+ void postShouldCreateANewTaskWhenConcurrencyParametersAreSpecified() {
+ given()
+ .queryParam("task", "RecomputeCurrentQuotas")
+ .queryParam("usersPerSecond", "1")
+ .post("/quota/users")
+ .then()
+ .statusCode(HttpStatus.CREATED_201)
+ .body("taskId", notNullValue());
+ }
+
+ @Test
+ void recomputeAllShouldCompleteWhenNoUser() {
+ String taskId = with()
+ .queryParam("task", "RecomputeCurrentQuotas")
+ .post("/quota/users")
+ .jsonPath()
+ .get("taskId");
+
+ given()
+ .basePath(TasksRoutes.BASE)
+ .when()
+ .get(taskId + "/await")
+ .then()
+ .body("status", is("completed"))
+ .body("taskId", is(taskId))
+ .body("type", is("recompute-current-quotas"))
+ .body("additionalInformation.processedQuotaRoots", is(0))
+ .body("additionalInformation.failedQuotaRoots", hasSize(0))
+ .body("additionalInformation.runningOptions.usersPerSecond", is(1))
+ .body("startedDate", is(notNullValue()))
+ .body("submitDate", is(notNullValue()))
+ .body("completedDate", is(notNullValue()));
+ }
+
+ @Test
+ void runningOptionsShouldBePartOfTaskDetails() {
+ String taskId = with()
+ .queryParam("task", "RecomputeCurrentQuotas")
+ .queryParam("usersPerSecond", "20")
+ .post("/quota/users")
+ .jsonPath()
+ .get("taskId");
+
+ given()
+ .basePath(TasksRoutes.BASE)
+ .when()
+ .get(taskId + "/await")
+ .then()
+ .body("taskId", is(taskId))
+ .body("type", is("recompute-current-quotas"))
+ .body("additionalInformation.runningOptions.usersPerSecond", is(20));
+ }
+ }
}
diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/WebAdminQuotaSearchTestSystem.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/WebAdminQuotaSearchTestSystem.java
index 898d5d6..b315dbc 100644
--- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/WebAdminQuotaSearchTestSystem.java
+++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/WebAdminQuotaSearchTestSystem.java
@@ -19,9 +19,15 @@
package org.apache.james.webadmin.routes;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.james.mailbox.quota.task.RecomputeCurrentQuotasService;
import org.apache.james.quota.search.QuotaSearchTestSystem;
import org.apache.james.task.Hostname;
import org.apache.james.task.MemoryTaskManager;
+import org.apache.james.task.Task;
import org.apache.james.task.TaskManager;
import org.apache.james.webadmin.WebAdminServer;
import org.apache.james.webadmin.WebAdminUtils;
@@ -34,6 +40,7 @@ import org.apache.james.webadmin.utils.JsonTransformer;
import com.google.common.collect.ImmutableSet;
import io.restassured.specification.RequestSpecification;
+import reactor.core.publisher.Mono;
public class WebAdminQuotaSearchTestSystem {
private final QuotaSearchTestSystem quotaSearchTestSystem;
@@ -51,12 +58,15 @@ public class WebAdminQuotaSearchTestSystem {
QuotaModule quotaModule = new QuotaModule();
JsonTransformer jsonTransformer = new JsonTransformer(quotaModule);
TaskManager taskManager = new MemoryTaskManager(new Hostname("foo"));
+ RecomputeCurrentQuotasService mock = mock(RecomputeCurrentQuotasService.class);
+ when(mock.recomputeCurrentQuotas(any(), any())).thenReturn(Mono.just(Task.Result.COMPLETED));
+ TasksRoutes tasksRoutes = new TasksRoutes(taskManager, new JsonTransformer());
UserQuotaRoutes userQuotaRoutes = new UserQuotaRoutes(quotaSearchTestSystem.getUsersRepository(),
userQuotaService,
jsonTransformer,
ImmutableSet.of(quotaModule),
taskManager,
- ImmutableSet.of());
+ ImmutableSet.of(new UserQuotaRoutes.RecomputeCurrentQuotasRequestToTask(mock)));
DomainQuotaRoutes domainQuotaRoutes = new DomainQuotaRoutes(
quotaSearchTestSystem.getDomainList(),
new DomainQuotaService(quotaSearchTestSystem.getMaxQuotaManager()),
@@ -67,7 +77,7 @@ public class WebAdminQuotaSearchTestSystem {
new GlobalQuotaService(quotaSearchTestSystem.getMaxQuotaManager()),
jsonTransformer);
- this.webAdminServer = WebAdminUtils.createWebAdminServer(userQuotaRoutes, domainQuotaRoutes, globalQuotaRoutes)
+ this.webAdminServer = WebAdminUtils.createWebAdminServer(userQuotaRoutes, domainQuotaRoutes, globalQuotaRoutes, tasksRoutes)
.start();
this.requestSpecBuilder = WebAdminUtils.buildRequestSpecification(webAdminServer)
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org