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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to