JAMES-2345 Introduce JMAP Quota DTO
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/bfd71851 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/bfd71851 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/bfd71851 Branch: refs/heads/master Commit: bfd718517f24e044b0020b9e8c67ec3e5e85a8d8 Parents: 95c2367 Author: Raphael Ouazana <[email protected]> Authored: Tue Mar 6 14:50:48 2018 +0100 Committer: Raphael Ouazana <[email protected]> Committed: Thu Mar 8 09:29:51 2018 +0100 ---------------------------------------------------------------------- .../integration/GetMailboxesMethodTest.java | 34 ++++++++ .../apache/james/jmap/model/MailboxFactory.java | 9 ++ .../james/jmap/model/mailbox/Mailbox.java | 24 +++++- .../apache/james/jmap/model/mailbox/Quotas.java | 91 ++++++++++++++++++++ .../james/jmap/model/mailbox/MailboxTest.java | 2 +- 5 files changed, 155 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/bfd71851/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMailboxesMethodTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMailboxesMethodTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMailboxesMethodTest.java index 54cc98b..ed06dd6 100644 --- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMailboxesMethodTest.java +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMailboxesMethodTest.java @@ -764,4 +764,38 @@ public abstract class GetMailboxesMethodTest { .body(FIRST_MAILBOX + ".mayDelete", equalTo(false)) .body(FIRST_MAILBOX + ".mayRename", equalTo(false)); } + + @Test + public void getMailboxesShouldReturnUnlimitedQuotasForInboxByDefault() throws Exception { + String mailboxId = mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, alice, DefaultMailboxes.INBOX).serialize(); + + given() + .header("Authorization", accessToken.serialize()) + .body("[[\"getMailboxes\", {\"ids\": [\"" + mailboxId + "\"]}, \"#0\"]]") + .when() + .post("/jmap") + .then() + .statusCode(200) + .body(NAME, equalTo("mailboxes")) + .body(ARGUMENTS + ".list", hasSize(1)) + .body(FIRST_MAILBOX + ".quotas['key']['STORAGE'].max", nullValue()) + .body(FIRST_MAILBOX + ".quotas['key']['MESSAGE'].max", nullValue()); + } + + @Test + public void getMailboxesShouldReturnEmptyQuotasForInboxWhenNoMail() throws Exception { + String mailboxId = mailboxProbe.createMailbox(MailboxConstants.USER_NAMESPACE, alice, DefaultMailboxes.INBOX).serialize(); + + given() + .header("Authorization", accessToken.serialize()) + .body("[[\"getMailboxes\", {\"ids\": [\"" + mailboxId + "\"]}, \"#0\"]]") + .when() + .post("/jmap") + .then() + .statusCode(200) + .body(NAME, equalTo("mailboxes")) + .body(ARGUMENTS + ".list", hasSize(1)) + .body(FIRST_MAILBOX + ".quotas['key']['STORAGE'].used", equalTo(0)) + .body(FIRST_MAILBOX + ".quotas['key']['MESSAGE'].used", equalTo(0)); + } } http://git-wip-us.apache.org/repos/asf/james-project/blob/bfd71851/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java index 949a6e4..8013ed3 100644 --- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/MailboxFactory.java @@ -25,6 +25,9 @@ import javax.inject.Inject; import org.apache.james.jmap.model.mailbox.Mailbox; import org.apache.james.jmap.model.mailbox.MailboxNamespace; +import org.apache.james.jmap.model.mailbox.Quotas; +import org.apache.james.jmap.model.mailbox.Quotas.QuotaId; +import org.apache.james.jmap.model.mailbox.Quotas.Type; import org.apache.james.jmap.model.mailbox.Rights; import org.apache.james.jmap.model.mailbox.Rights.Username; import org.apache.james.jmap.model.mailbox.SortOrder; @@ -38,11 +41,13 @@ import org.apache.james.mailbox.model.MailboxCounters; import org.apache.james.mailbox.model.MailboxId; import org.apache.james.mailbox.model.MailboxMetaData; import org.apache.james.mailbox.model.MailboxPath; +import org.apache.james.mailbox.model.QuotaRoot; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.common.base.Splitter; import com.google.common.base.Throwables; +import com.google.common.collect.ImmutableMap; public class MailboxFactory { public static final boolean NO_RESET_RECENT = false; @@ -108,6 +113,9 @@ public class MailboxFactory { Rights rights = Rights.fromACL(metaData.getACL()) .removeEntriesFor(Username.forMailboxPath(messageManager.getMailboxPath())); Username username = Username.fromSession(mailboxSession); + Quotas quotas = new Quotas(ImmutableMap.of(new QuotaId(QuotaRoot.quotaRoot("key")), new Quotas.Quota(ImmutableMap.of( + Type.STORAGE, new Quotas.Value(Number.ZERO, Optional.empty()), + Type.MESSAGE, new Quotas.Value(Number.ZERO, Optional.empty()))))); return Mailbox.builder() .id(messageManager.getId()) @@ -125,6 +133,7 @@ public class MailboxFactory { .mayRemoveItems(rights.mayRemoveItems(username).orElse(isOwner)) .mayRename(rights.mayRename(username).orElse(isOwner)) .namespace(getNamespace(mailboxPath, isOwner)) + .quotas(quotas) .build(); } http://git-wip-us.apache.org/repos/asf/james-project/blob/bfd71851/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/Mailbox.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/Mailbox.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/Mailbox.java index 8dc0ff2..b19e882 100644 --- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/Mailbox.java +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/Mailbox.java @@ -65,6 +65,7 @@ public class Mailbox { private Optional<Number> unreadThreads; private Optional<Rights> sharedWith; private Optional<MailboxNamespace> namespace; + private Optional<Quotas> quotas; private Builder() { parentId = Optional.empty(); @@ -75,6 +76,7 @@ public class Mailbox { totalThreads = Optional.empty(); unreadThreads = Optional.empty(); role = Optional.empty(); + quotas = Optional.empty(); } public Builder id(MailboxId id) { @@ -169,6 +171,11 @@ public class Mailbox { return this; } + public Builder quotas(Quotas quotas) { + this.quotas = Optional.of(quotas); + return this; + } + public Mailbox build() { Preconditions.checkState(!Strings.isNullOrEmpty(name), "'name' is mandatory"); Preconditions.checkState(id != null, "'id' is mandatory"); @@ -190,7 +197,8 @@ public class Mailbox { totalThreads.orElse(Number.ZERO), unreadThreads.orElse(Number.ZERO), sharedWith.orElse(Rights.EMPTY), - namespace.orElse(MailboxNamespace.personal())); + namespace.orElse(MailboxNamespace.personal()), + quotas); } } @@ -212,10 +220,12 @@ public class Mailbox { private final Number unreadThreads; private final Rights sharedWith; private final MailboxNamespace namespace; + private final Optional<Quotas> quotas; @VisibleForTesting Mailbox(MailboxId id, String name, Optional<MailboxId> parentId, Optional<Role> role, SortOrder sortOrder, boolean mustBeOnlyMailbox, boolean mayReadItems, boolean mayAddItems, boolean mayRemoveItems, boolean mayCreateChild, boolean mayRename, boolean mayDelete, - Number totalMessages, Number unreadMessages, Number totalThreads, Number unreadThreads, Rights sharedWith, MailboxNamespace namespace) { + Number totalMessages, Number unreadMessages, Number totalThreads, Number unreadThreads, Rights sharedWith, MailboxNamespace namespace, + Optional<Quotas> quotas) { this.id = id; this.name = name; @@ -235,6 +245,7 @@ public class Mailbox { this.unreadThreads = unreadThreads; this.sharedWith = sharedWith; this.namespace = namespace; + this.quotas = quotas; } public MailboxId getId() { @@ -309,6 +320,10 @@ public class Mailbox { return namespace; } + public Optional<Quotas> getQuotas() { + return quotas; + } + @JsonIgnore public boolean hasRole(Role role) { return this.role @@ -342,7 +357,8 @@ public class Mailbox { && Objects.equals(this.totalThreads, other.totalThreads) && Objects.equals(this.unreadThreads, other.unreadThreads) && Objects.equals(this.sharedWith, other.sharedWith) - && Objects.equals(this.namespace, other.namespace); + && Objects.equals(this.namespace, other.namespace) + && Objects.equals(this.quotas, other.quotas); } return false; } @@ -351,7 +367,7 @@ public class Mailbox { public final int hashCode() { return Objects.hash(id, name, parentId, role, sortOrder, mustBeOnlyMailbox, mayReadItems, mayAddItems, mayRemoveItems, mayCreateChild, mayRename, mayDelete, totalMessages, unreadMessages, totalThreads, - unreadThreads, sharedWith, namespace); + unreadThreads, sharedWith, namespace, quotas); } @Override http://git-wip-us.apache.org/repos/asf/james-project/blob/bfd71851/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/Quotas.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/Quotas.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/Quotas.java new file mode 100644 index 0000000..8116111 --- /dev/null +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/mailbox/Quotas.java @@ -0,0 +1,91 @@ +/**************************************************************** + * 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.jmap.model.mailbox; + +import java.util.Map; +import java.util.Optional; + +import org.apache.james.jmap.model.Number; +import org.apache.james.mailbox.model.QuotaRoot; + +import com.fasterxml.jackson.annotation.JsonValue; +import com.google.common.collect.ImmutableMap; + +public class Quotas { + + private final Map<QuotaId, Quota> quotas; + + public Quotas(ImmutableMap<QuotaId, Quota> quotas) { + this.quotas = quotas; + } + + @JsonValue + public Map<QuotaId, Quota> getQuotas() { + return quotas; + } + + public static class QuotaId { + private final QuotaRoot quotaRoot; + + public QuotaId(QuotaRoot quotaRoot) { + this.quotaRoot = quotaRoot; + } + + @JsonValue + public String getName() { + return quotaRoot.getValue(); + } + } + + public static class Quota { + private final Map<Type, Value> quota; + + public Quota(ImmutableMap<Type, Value> quota) { + this.quota = quota; + } + + @JsonValue + public Map<Type, Value> getQuota() { + return quota; + } + } + + public static enum Type { + STORAGE, + MESSAGE; + } + + public static class Value { + private final Number used; + private final Optional<Number> max; + + public Value(Number used, Optional<Number> max) { + this.used = used; + this.max = max; + } + + public Number getUsed() { + return used; + } + + public Optional<Number> getMax() { + return max; + } + } +} http://git-wip-us.apache.org/repos/asf/james-project/blob/bfd71851/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/MailboxTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/MailboxTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/MailboxTest.java index be674c3..db257e2 100644 --- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/MailboxTest.java +++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/MailboxTest.java @@ -71,7 +71,7 @@ public class MailboxTest { Mailbox expectedMailbox = new Mailbox(InMemoryId.of(1), "name", Optional.of(InMemoryId.of(0)), Optional.of(Role.DRAFTS), SortOrder.of(123), true, true, true, true, true, true, true, totalMessages, unreadMessages, totalThreads, unreadThreads, - Rights.EMPTY, MailboxNamespace.personal()); + Rights.EMPTY, MailboxNamespace.personal(), Optional.empty()); Mailbox mailbox = Mailbox.builder() .id(InMemoryId.of(1)) --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
