JAMES-2344 Return a complete Quota overview on user quota route
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/630bf0a8 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/630bf0a8 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/630bf0a8 Branch: refs/heads/master Commit: 630bf0a86a8b3a138df99b4e9aa1ac956cb24ce2 Parents: c45b0f3 Author: Matthieu Baechler <matth...@apache.org> Authored: Fri Mar 9 14:21:46 2018 +0100 Committer: Matthieu Baechler <matth...@apache.org> Committed: Tue Mar 13 16:10:28 2018 +0100 ---------------------------------------------------------------------- .../james/webadmin/dto/QuotaDetailsDTO.java | 95 ++++++++++++++++++++ .../webadmin/service/UserQuotaService.java | 40 +++++++-- .../webadmin/routes/UserQuotaRoutesTest.java | 73 ++++++++++++--- 3 files changed, 192 insertions(+), 16 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/630bf0a8/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDetailsDTO.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDetailsDTO.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDetailsDTO.java new file mode 100644 index 0000000..6c563ec --- /dev/null +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/dto/QuotaDetailsDTO.java @@ -0,0 +1,95 @@ +/**************************************************************** + * 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.webadmin.dto; + +import java.util.Optional; + +import org.apache.james.mailbox.model.Quota; + +public class QuotaDetailsDTO { + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private Optional<QuotaDTO> global; + private Optional<QuotaDTO> user; + private Optional<QuotaDTO> computed; + + private Builder() { + global = Optional.empty(); + user = Optional.empty(); + computed = Optional.empty(); + } + + public Builder global(QuotaDTO global) { + this.global = Optional.of(global); + return this; + } + + public Builder user(QuotaDTO user) { + this.user = Optional.of(user); + return this; + } + + public Builder computed(QuotaDTO computed) { + this.computed = Optional.of(computed); + return this; + } + + public Builder valueForScope(Quota.Scope scope, QuotaDTO value) { + switch (scope) { + case Global: + return global(value); + case User: + return user(value); + } + return this; + } + + public QuotaDetailsDTO build() { + return new QuotaDetailsDTO(global, user, computed); + } + } + + private final Optional<QuotaDTO> global; + private final Optional<QuotaDTO> user; + private final Optional<QuotaDTO> computed; + + private QuotaDetailsDTO(Optional<QuotaDTO> global, Optional<QuotaDTO> user, Optional<QuotaDTO> computed) { + this.global = global; + this.user = user; + this.computed = computed; + } + + public Optional<QuotaDTO> getGlobal() { + return global; + } + + public Optional<QuotaDTO> getUser() { + return user; + } + + public Optional<QuotaDTO> getComputed() { + return computed; + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/630bf0a8/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserQuotaService.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserQuotaService.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserQuotaService.java index 1b79e42..7e48bba 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserQuotaService.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/service/UserQuotaService.java @@ -18,20 +18,26 @@ ****************************************************************/ package org.apache.james.webadmin.service; +import java.util.Map; import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Collectors; import javax.inject.Inject; import org.apache.james.core.User; import org.apache.james.mailbox.exception.MailboxException; +import org.apache.james.mailbox.model.Quota; import org.apache.james.mailbox.model.QuotaRoot; import org.apache.james.mailbox.quota.MaxQuotaManager; import org.apache.james.mailbox.quota.QuotaCount; import org.apache.james.mailbox.quota.QuotaSize; import org.apache.james.mailbox.quota.UserQuotaRootResolver; import org.apache.james.webadmin.dto.QuotaDTO; +import org.apache.james.webadmin.dto.QuotaDetailsDTO; import com.github.fge.lambdas.Throwing; +import com.google.common.collect.Sets; public class UserQuotaService { @@ -52,15 +58,39 @@ public class UserQuotaService { .ifPresent(Throwing.consumer(size -> maxQuotaManager.setMaxStorage(quotaRoot, size))); } - public QuotaDTO getQuota(User user) throws MailboxException { + public QuotaDetailsDTO getQuota(User user) throws MailboxException { QuotaRoot quotaRoot = userQuotaRootResolver.forUser(user); + QuotaDetailsDTO.Builder quotaDetails = QuotaDetailsDTO.builder(); + + mergeMaps( + maxQuotaManager.listMaxMessagesDetails(quotaRoot), + maxQuotaManager.listMaxStorageDetails(quotaRoot)) + .forEach(quotaDetails::valueForScope); + + quotaDetails.computed(computedQuota(quotaRoot)); + return quotaDetails.build(); + } + + private QuotaDTO computedQuota(QuotaRoot quotaRoot) throws MailboxException { return QuotaDTO - .builder() - .count(maxQuotaManager.getMaxMessage(quotaRoot)) - .size(maxQuotaManager.getMaxStorage(quotaRoot)) - .build(); + .builder() + .count(maxQuotaManager.getMaxMessage(quotaRoot)) + .size(maxQuotaManager.getMaxStorage(quotaRoot)) + .build(); } + private Map<Quota.Scope, QuotaDTO> mergeMaps(Map<Quota.Scope, QuotaCount> counts, Map<Quota.Scope, QuotaSize> sizes) { + return Sets.union(counts.keySet(), sizes.keySet()) + .stream() + .collect(Collectors.toMap(Function.identity(), + scope -> QuotaDTO + .builder() + .count(Optional.ofNullable(counts.get(scope))) + .size(Optional.ofNullable(sizes.get(scope))) + .build())); + } + + public Optional<QuotaSize> getMaxSizeQuota(User user) throws MailboxException { return maxQuotaManager.getMaxStorage(userQuotaRootResolver.forUser(user)); } http://git-wip-us.apache.org/repos/asf/james-project/blob/630bf0a8/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java ---------------------------------------------------------------------- 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 d1007b4..fa3dd6e 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 @@ -42,6 +42,7 @@ import org.apache.james.webadmin.WebAdminUtils; import org.apache.james.webadmin.jackson.QuotaModule; import org.apache.james.webadmin.service.UserQuotaService; import org.apache.james.webadmin.utils.JsonTransformer; +import org.assertj.core.api.SoftAssertions; import org.eclipse.jetty.http.HttpStatus; import org.junit.After; import org.junit.Before; @@ -373,10 +374,33 @@ public class UserQuotaRoutesTest { @Test public void getQuotaShouldReturnBothWhenValueSpecified() throws Exception { - int maxStorage = 42; - int maxMessage = 52; - maxQuotaManager.setMaxStorage(userQuotaRootResolver.forUser(BOB), QuotaSize.size(maxStorage)); - maxQuotaManager.setMaxMessage(userQuotaRootResolver.forUser(BOB), QuotaCount.count(maxMessage)); + maxQuotaManager.setDefaultMaxStorage(QuotaSize.size(1111)); + maxQuotaManager.setDefaultMaxMessage(QuotaCount.count(22)); + maxQuotaManager.setMaxStorage(userQuotaRootResolver.forUser(BOB), QuotaSize.size(42)); + maxQuotaManager.setMaxMessage(userQuotaRootResolver.forUser(BOB), QuotaCount.count(52)); + + JsonPath jsonPath = + given() + .get(QUOTA_USERS + "/" + BOB.asString()) + .then() + .statusCode(HttpStatus.OK_200) + .contentType(ContentType.JSON) + .extract() + .jsonPath(); + + SoftAssertions softly = new SoftAssertions(); + softly.assertThat(jsonPath.getLong("computed." + SIZE)).isEqualTo(42); + softly.assertThat(jsonPath.getLong("computed." + COUNT)).isEqualTo(52); + softly.assertThat(jsonPath.getLong("user." + SIZE)).isEqualTo(42); + softly.assertThat(jsonPath.getLong("user." + COUNT)).isEqualTo(52); + softly.assertThat(jsonPath.getLong("global." + SIZE)).isEqualTo(1111); + softly.assertThat(jsonPath.getLong("global." + COUNT)).isEqualTo(22); + } + + @Test + public void getQuotaShouldReturnOnlySpecifiedValues() throws Exception { + maxQuotaManager.setDefaultMaxStorage(QuotaSize.size(1111)); + maxQuotaManager.setMaxMessage(userQuotaRootResolver.forUser(BOB), QuotaCount.count(52)); JsonPath jsonPath = given() @@ -387,8 +411,35 @@ public class UserQuotaRoutesTest { .extract() .jsonPath(); - assertThat(jsonPath.getLong(SIZE)).isEqualTo(maxStorage); - assertThat(jsonPath.getLong(COUNT)).isEqualTo(maxMessage); + SoftAssertions softly = new SoftAssertions(); + softly.assertThat(jsonPath.getLong("computed." + SIZE)).isEqualTo(1111); + softly.assertThat(jsonPath.getLong("computed." + COUNT)).isEqualTo(52); + softly.assertThat(jsonPath.getLong("user." + COUNT)).isEqualTo(52); + softly.assertThat(jsonPath.getObject("user." + SIZE, Long.class)).isNull(); + softly.assertThat(jsonPath.getLong("global." + SIZE)).isEqualTo(1111); + softly.assertThat(jsonPath.getObject("global." + COUNT, Long.class)).isNull(); + } + + @Test + public void getQuotaShouldReturnGlobalValuesWhenNoUserValuesDefined() throws Exception { + maxQuotaManager.setDefaultMaxStorage(QuotaSize.size(1111)); + maxQuotaManager.setDefaultMaxMessage(QuotaCount.count(12)); + + JsonPath jsonPath = + given() + .get(QUOTA_USERS + "/" + BOB.asString()) + .then() + .statusCode(HttpStatus.OK_200) + .contentType(ContentType.JSON) + .extract() + .jsonPath(); + + SoftAssertions softly = new SoftAssertions(); + softly.assertThat(jsonPath.getLong("computed." + SIZE)).isEqualTo(1111); + softly.assertThat(jsonPath.getLong("computed." + COUNT)).isEqualTo(12); + softly.assertThat(jsonPath.getObject("user", Object.class)).isNull(); + softly.assertThat(jsonPath.getLong("global." + SIZE)).isEqualTo(1111); + softly.assertThat(jsonPath.getLong("global." + COUNT)).isEqualTo(12); } @Test @@ -420,8 +471,8 @@ public class UserQuotaRoutesTest { .extract() .jsonPath(); - assertThat(jsonPath.getLong(SIZE)).isEqualTo(maxStorage); - assertThat(jsonPath.getObject(COUNT, Long.class)).isNull(); + assertThat(jsonPath.getLong("user." + SIZE)).isEqualTo(maxStorage); + assertThat(jsonPath.getObject("user." + COUNT, Long.class)).isNull(); } @Test @@ -433,14 +484,14 @@ public class UserQuotaRoutesTest { JsonPath jsonPath = given() .get(QUOTA_USERS + "/" + BOB.asString()) - .then() + .then() .statusCode(HttpStatus.OK_200) .contentType(ContentType.JSON) .extract() .jsonPath(); - assertThat(jsonPath.getObject(SIZE, Long.class)).isNull(); - assertThat(jsonPath.getLong(COUNT)).isEqualTo(maxMessage); + assertThat(jsonPath.getObject("user." + SIZE, Long.class)).isNull(); + assertThat(jsonPath.getLong("user." + COUNT)).isEqualTo(maxMessage); } @Test --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org