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 ro...@apache.org on 2019/06/12 14:32:11 UTC

[james-project] branch 3.3.x updated (8d69a83 -> 86279b6)

This is an automated email from the ASF dual-hosted git repository.

rouazana pushed a change to branch 3.3.x
in repository https://gitbox.apache.org/repos/asf/james-project.git.


    from 8d69a83  JAMES-2699 Add documentation for Mailet API deprecation
     new fcc764f  JMAP getMailboxes preload quotas for user namespace/name in order to avoid doing it for each mailbox
     new e65b685  JAMES-2746 extract QuotaLoader from MailboxFactory
     new 00438bf  JAMES-2761 get mailbox capabilities out of the loop on its messages
     new 033ab85  JAMES-2761 remove dead code in AbstractSelectionProcessor.respond
     new 9dd7ebc  Add dependencies file matching branch needs
     new 86279b6  JAMES-2754 extract external James configuration

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../compilation/java-8/integration_tests.sh        | 12 +++-
 dockerfiles/run/dependencies.properties            |  4 ++
 .../imap/processor/AbstractMailboxProcessor.java   | 44 ++++++------
 .../imap/processor/AbstractSelectionProcessor.java | 18 +----
 .../james/jmap/methods/GetMailboxesMethod.java     | 45 ++++++++----
 .../apache/james/jmap/model/MailboxFactory.java    | 67 +++++++-----------
 .../apache/james/jmap/model/mailbox/Quotas.java    | 15 ++++
 .../jmap/utils/quotas/DefaultQuotaLoader.java      | 50 +++++++-------
 .../james/jmap/utils/quotas/QuotaLoader.java       | 40 +++++------
 .../quotas/QuotaLoaderWithDefaultPreloaded.java    | 80 ++++++++++++++++++++++
 .../james/jmap/methods/GetMailboxesMethodTest.java | 31 +++++----
 .../james/jmap/model/MailboxFactoryTest.java       |  2 +
 .../james/jmap/model/mailbox/QuotaIdTest.java}     | 13 ++--
 13 files changed, 260 insertions(+), 161 deletions(-)
 create mode 100644 dockerfiles/run/dependencies.properties
 copy mailbox/api/src/test/java/org/apache/james/mailbox/manager/IntegrationResources.java => server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/quotas/DefaultQuotaLoader.java (56%)
 copy mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/QuotaCodec.java => server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/quotas/QuotaLoader.java (58%)
 create mode 100644 server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/quotas/QuotaLoaderWithDefaultPreloaded.java
 copy server/{task/src/test/java/org/apache/james/task/TaskIdTest.java => protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/QuotaIdTest.java} (87%)


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 04/06: JAMES-2761 remove dead code in AbstractSelectionProcessor.respond

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rouazana pushed a commit to branch 3.3.x
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 033ab85cd25d72ffc774daec3df8e90887ea5a6e
Author: Rémi Kowalski <rk...@linagora.com>
AuthorDate: Tue May 14 10:09:51 2019 +0200

    JAMES-2761 remove dead code in AbstractSelectionProcessor.respond
---
 .../imap/processor/AbstractSelectionProcessor.java     | 18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java
index 3abf4e7..5a3e09f 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractSelectionProcessor.java
@@ -53,7 +53,6 @@ import org.apache.james.mailbox.exception.MailboxNotFoundException;
 import org.apache.james.mailbox.exception.MessageRangeException;
 import org.apache.james.mailbox.model.MailboxPath;
 import org.apache.james.mailbox.model.MessageRange;
-import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.metrics.api.MetricFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -115,9 +114,7 @@ abstract class AbstractSelectionProcessor<M extends AbstractMailboxSelectionRequ
             taggedBad(command, tag, responder, HumanReadableText.QRESYNC_NOT_ENABLED);
             return;
         }
-        
-        
-        
+
         final MessageManager.MetaData metaData = selectMailbox(fullMailboxPath, session);
         final SelectedMailbox selected = session.getSelected();
         MessageUid firstUnseen = metaData.getFirstUnseen();
@@ -161,17 +158,14 @@ abstract class AbstractSelectionProcessor<M extends AbstractMailboxSelectionRequ
                 final MailboxManager mailboxManager = getMailboxManager();
                 final MailboxSession mailboxSession = ImapSessionUtils.getMailboxSession(session);
                 final MessageManager mailbox = mailboxManager.getMailbox(fullMailboxPath, mailboxSession);
-               
-                
+
                 //  If the provided UIDVALIDITY matches that of the selected mailbox, the
                 //  server then checks the last known modification sequence.
                 //
                 //  The server sends the client any pending flag changes (using FETCH
                 //  responses that MUST contain UIDs) and expunges those that have
                 //  occurred in this mailbox since the provided modification sequence.
-                SearchQuery sq = new SearchQuery();
-                sq.andCriteria(SearchQuery.modSeqGreaterThan(request.getKnownModSeq()));
-                
+
                 UidRange[] uidSet = request.getUidSet();
 
                 if (uidSet == null) {
@@ -219,8 +213,6 @@ abstract class AbstractSelectionProcessor<M extends AbstractMailboxSelectionRequ
                                 knownUidsList.add(uid);
                             }
                         }
-                       
-                        
                         
                         // loop over the known sequences and check the UID for MSN X again the known UID X 
                         MessageUid firstUid = MessageUid.MIN_VALUE;
@@ -248,7 +240,6 @@ abstract class AbstractSelectionProcessor<M extends AbstractMailboxSelectionRequ
                                     done = true;
                                     break;
                                 }
-
                             }
 
                             // We found the first uid to start with 
@@ -272,7 +263,6 @@ abstract class AbstractSelectionProcessor<M extends AbstractMailboxSelectionRequ
                             }
                         }
                         
-                        
                     }
                     
                     List<MessageRange> ranges = new ArrayList<>();
@@ -284,8 +274,6 @@ abstract class AbstractSelectionProcessor<M extends AbstractMailboxSelectionRequ
                         }
                     }
                     
-                    
-                    
                     // TODO: Reconsider if we can do something to make the handling better. Maybe at least cache the triplets for the expunged
                     //       while have the server running. This could maybe allow us to not return every expunged message all the time
                     //  


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 01/06: JMAP getMailboxes preload quotas for user namespace/name in order to avoid doing it for each mailbox

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rouazana pushed a commit to branch 3.3.x
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit fcc764fbf5e8ae48ee7fa9c25410ecf4cda734c9
Author: Rémi Kowalski <rk...@linagora.com>
AuthorDate: Tue Apr 23 17:19:35 2019 +0200

    JMAP getMailboxes preload quotas for user namespace/name in order to avoid doing it for each mailbox
---
 .../james/jmap/methods/GetMailboxesMethod.java     | 38 ++++++++++++++------
 .../apache/james/jmap/model/MailboxFactory.java    | 42 +++++++++++++++++-----
 .../apache/james/jmap/model/mailbox/Quotas.java    | 15 ++++++++
 .../james/jmap/model/mailbox/QuotaIdTest.java      | 32 +++++++++++++++++
 4 files changed, 108 insertions(+), 19 deletions(-)

diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMailboxesMethod.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMailboxesMethod.java
index 9b33064..ab22edc 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMailboxesMethod.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMailboxesMethod.java
@@ -33,6 +33,7 @@ import org.apache.james.jmap.model.GetMailboxesResponse;
 import org.apache.james.jmap.model.MailboxFactory;
 import org.apache.james.jmap.model.MailboxProperty;
 import org.apache.james.jmap.model.mailbox.Mailbox;
+import org.apache.james.jmap.model.mailbox.Quotas;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.exception.MailboxException;
@@ -44,6 +45,7 @@ import org.apache.james.util.MDCBuilder;
 import org.apache.james.util.OptionalUtils;
 
 import com.github.fge.lambdas.Throwing;
+import com.github.steveash.guavate.Guavate;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
@@ -54,6 +56,8 @@ public class GetMailboxesMethod implements Method {
 
     private static final Method.Request.Name METHOD_NAME = Method.Request.name("getMailboxes");
     private static final Method.Response.Name RESPONSE_NAME = Method.Response.name("mailboxes");
+    private static final Optional<List<MailboxMetaData>> NO_PRELOADED_METADATA = Optional.empty();
+    private static final Optional<Quotas> NO_PRELOADED_QUOTAS = Optional.empty();
 
     private final MailboxManager mailboxManager; 
     private final MailboxFactory mailboxFactory;
@@ -106,10 +110,10 @@ public class GetMailboxesMethod implements Method {
         GetMailboxesResponse.Builder builder = GetMailboxesResponse.builder();
         try {
             Optional<ImmutableList<MailboxId>> mailboxIds = mailboxesRequest.getIds();
-            retrieveMailboxes(mailboxIds, mailboxSession)
+            List<Mailbox> mailboxes = retrieveMailboxes(mailboxIds, mailboxSession)
                 .sorted(Comparator.comparing(Mailbox::getSortOrder))
-                .forEach(builder::add);
-            return builder.build();
+                .collect(Guavate.toImmutableList());
+            return builder.addAll(mailboxes).build();
         } catch (MailboxException e) {
             throw new RuntimeException(e);
         }
@@ -121,31 +125,43 @@ public class GetMailboxesMethod implements Method {
             .orElseGet(Throwing.supplier(() -> retrieveAllMailboxes(mailboxSession)).sneakyThrow());
     }
 
+
+
     private Stream<Mailbox> retrieveSpecificMailboxes(MailboxSession mailboxSession, ImmutableList<MailboxId> mailboxIds) {
         return mailboxIds
             .stream()
-            .map(mailboxId -> mailboxFactory.builder()
+            .map(mailboxId ->  mailboxFactory.builder()
                 .id(mailboxId)
                 .session(mailboxSession)
-                .build())
+                .usingPreloadedMailboxesMetadata(NO_PRELOADED_METADATA)
+                .usingPreloadedUserDefaultQuotas(NO_PRELOADED_QUOTAS)
+                .build()
+            )
             .flatMap(OptionalUtils::toStream);
     }
 
     private Stream<Mailbox> retrieveAllMailboxes(MailboxSession mailboxSession) throws MailboxException {
-        List<MailboxMetaData> userMailboxes = mailboxManager.search(
-            MailboxQuery.builder()
-                .matchesAllMailboxNames()
-                .build(),
-            mailboxSession);
+        List<MailboxMetaData> userMailboxes = getAllMailboxesMetaData(mailboxSession);
+        Quotas mailboxQuotas =  mailboxFactory.getUserDefaultQuotas(mailboxSession);
+
         return userMailboxes
             .stream()
             .map(MailboxMetaData::getId)
             .map(mailboxId -> mailboxFactory.builder()
                 .id(mailboxId)
                 .session(mailboxSession)
-                .usingPreloadedMailboxesMetadata(userMailboxes)
+                .usingPreloadedMailboxesMetadata(Optional.of(userMailboxes))
+                .usingPreloadedUserDefaultQuotas(Optional.of(mailboxQuotas))
                 .build())
             .flatMap(OptionalUtils::toStream);
     }
 
+    private List<MailboxMetaData> getAllMailboxesMetaData(MailboxSession mailboxSession) throws MailboxException {
+        return mailboxManager.search(
+                MailboxQuery.builder()
+                    .matchesAllMailboxNames()
+                    .build(),
+                mailboxSession);
+    }
+
 }
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 0080339..d2506fb 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
@@ -59,7 +59,8 @@ public class MailboxFactory {
         private final MailboxFactory mailboxFactory;
         private MailboxSession session;
         private MailboxId id;
-        private List<MailboxMetaData> userMailboxesMetadata;
+        private Optional<List<MailboxMetaData>> userMailboxesMetadata = Optional.empty();
+        private Optional<Quotas> preloadedUserDefaultQuotas = Optional.empty();
 
         private MailboxBuilder(MailboxFactory mailboxFactory) {
             this.mailboxFactory = mailboxFactory;
@@ -75,18 +76,23 @@ public class MailboxFactory {
             return this;
         }
 
-        public MailboxBuilder usingPreloadedMailboxesMetadata(List<MailboxMetaData> userMailboxesMetadata) {
+        public MailboxBuilder usingPreloadedMailboxesMetadata(Optional<List<MailboxMetaData>> userMailboxesMetadata) {
             this.userMailboxesMetadata = userMailboxesMetadata;
             return this;
         }
 
+        public MailboxBuilder usingPreloadedUserDefaultQuotas(Optional<Quotas> preloadedUserDefaultQuotas) {
+            this.preloadedUserDefaultQuotas = preloadedUserDefaultQuotas;
+            return this;
+        }
+
         public Optional<Mailbox> build() {
             Preconditions.checkNotNull(id);
             Preconditions.checkNotNull(session);
 
             try {
                 MessageManager mailbox = mailboxFactory.mailboxManager.getMailbox(id, session);
-                return Optional.of(mailboxFactory.fromMessageManager(mailbox, Optional.ofNullable(userMailboxesMetadata), session));
+                return Optional.of(mailboxFactory.fromMessageManager(mailbox, userMailboxesMetadata, preloadedUserDefaultQuotas, session));
             } catch (MailboxNotFoundException e) {
                 return Optional.empty();
             } catch (MailboxException e) {
@@ -106,8 +112,10 @@ public class MailboxFactory {
         return new MailboxBuilder(this);
     }
 
-    private Mailbox fromMessageManager(MessageManager messageManager, Optional<List<MailboxMetaData>> userMailboxesMetadata,
-                                                 MailboxSession mailboxSession) throws MailboxException {
+    private Mailbox fromMessageManager(MessageManager messageManager,
+                                       Optional<List<MailboxMetaData>> userMailboxesMetadata,
+                                       Optional<Quotas> preloadedDefaultUserQuotas,
+                                       MailboxSession mailboxSession) throws MailboxException {
         MailboxPath mailboxPath = messageManager.getMailboxPath();
         boolean isOwner = mailboxPath.belongsTo(mailboxSession);
         Optional<Role> role = Role.from(mailboxPath.getName());
@@ -116,7 +124,8 @@ public class MailboxFactory {
         Rights rights = Rights.fromACL(messageManager.getResolvedAcl(mailboxSession))
             .removeEntriesFor(Username.forMailboxPath(mailboxPath));
         Username username = Username.fromSession(mailboxSession);
-        Quotas quotas = getQuotas(mailboxPath);
+
+        Quotas quotas = getQuotas(mailboxPath, preloadedDefaultUserQuotas);
 
         return Mailbox.builder()
             .id(messageManager.getId())
@@ -138,15 +147,32 @@ public class MailboxFactory {
             .build();
     }
 
-    private Quotas getQuotas(MailboxPath mailboxPath) throws MailboxException {
+    private Quotas getQuotas(MailboxPath mailboxPath, Optional<Quotas> preloadedUserDefaultQuotas) throws MailboxException {
         QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(mailboxPath);
+        QuotaId quotaId = QuotaId.fromQuotaRoot(quotaRoot);
+
+        if (containsQuotaId(preloadedUserDefaultQuotas, quotaId)) {
+            return preloadedUserDefaultQuotas.get();
+        }
         return Quotas.from(
-            QuotaId.fromQuotaRoot(quotaRoot),
+            quotaId,
             Quotas.Quota.from(
                 quotaToValue(quotaManager.getStorageQuota(quotaRoot)),
                 quotaToValue(quotaManager.getMessageQuota(quotaRoot))));
     }
 
+    private boolean containsQuotaId(Optional<Quotas> preloadedUserDefaultQuotas, QuotaId quotaId) {
+        return preloadedUserDefaultQuotas
+                .map(Quotas::getQuotas)
+                .map(quotaIdQuotaMap -> quotaIdQuotaMap.containsKey(quotaId))
+                .orElse(false);
+    }
+
+    public Quotas getUserDefaultQuotas(MailboxSession mailboxSession) throws MailboxException {
+        MailboxPath inboxPath = MailboxPath.inbox(mailboxSession);
+        return getQuotas(inboxPath, Optional.empty());
+    }
+
     private <T extends QuotaValue<T>> Quotas.Value<T> quotaToValue(Quota<T> quota) {
         return new Quotas.Value<>(
                 quotaValueToNumber(quota.getUsed()),
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
index 30ae9a2..a090cb5 100644
--- 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
@@ -19,6 +19,7 @@
 package org.apache.james.jmap.model.mailbox;
 
 import java.util.Map;
+import java.util.Objects;
 import java.util.Optional;
 
 import org.apache.james.core.quota.QuotaCount;
@@ -66,6 +67,20 @@ public class Quotas {
         public String getName() {
             return quotaRoot.getValue();
         }
+
+        @Override
+        public final boolean equals(Object o) {
+            if (o instanceof QuotaId) {
+                QuotaId other = (QuotaId) o;
+                return Objects.equals(quotaRoot, other.quotaRoot);
+            }
+            return false;
+        }
+
+        @Override
+        public final int hashCode() {
+            return Objects.hashCode(quotaRoot);
+        }
     }
 
     public static class Quota {
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/QuotaIdTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/QuotaIdTest.java
new file mode 100644
index 0000000..591b69d
--- /dev/null
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/mailbox/QuotaIdTest.java
@@ -0,0 +1,32 @@
+/****************************************************************
+ * 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 org.junit.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+public class QuotaIdTest {
+
+    @Test
+    public void shouldRespectJavaBeanContract() {
+        EqualsVerifier.forClass(Quotas.QuotaId.class).verify();
+    }
+
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 05/06: Add dependencies file matching branch needs

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rouazana pushed a commit to branch 3.3.x
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 9dd7ebc1775b96fdda896a71ec1666cfd0f57a53
Author: Antoine DUPRAT <ad...@linagora.com>
AuthorDate: Wed Jun 5 14:33:19 2019 +0200

    Add dependencies file matching branch needs
---
 dockerfiles/run/dependencies.properties | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/dockerfiles/run/dependencies.properties b/dockerfiles/run/dependencies.properties
new file mode 100644
index 0000000..6a19ecd
--- /dev/null
+++ b/dockerfiles/run/dependencies.properties
@@ -0,0 +1,4 @@
+cassandra=cassandra:3.11.3
+elasticSearch=elasticsearch:2.4.6
+rabbitmq=rabbitmq:3.7.7-management
+swift=linagora/openstack-keystone-swift:pike


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 03/06: JAMES-2761 get mailbox capabilities out of the loop on its messages

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rouazana pushed a commit to branch 3.3.x
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 00438bf51efe0f804607c3e8f970c7faaced2a3f
Author: Rémi Kowalski <rk...@linagora.com>
AuthorDate: Mon May 13 11:22:53 2019 +0200

    JAMES-2761 get mailbox capabilities out of the loop on its messages
---
 .../imap/processor/AbstractMailboxProcessor.java   | 44 ++++++++++++----------
 1 file changed, 24 insertions(+), 20 deletions(-)

diff --git a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractMailboxProcessor.java b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractMailboxProcessor.java
index 08bef66..f6f1bab 100644
--- a/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractMailboxProcessor.java
+++ b/protocols/imap/src/main/java/org/apache/james/imap/processor/AbstractMailboxProcessor.java
@@ -52,7 +52,6 @@ import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
 import org.apache.james.mailbox.MessageManager.MetaData;
-import org.apache.james.mailbox.MessageManager.MetaData.FetchGroup;
 import org.apache.james.mailbox.MessageUid;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.exception.MessageRangeException;
@@ -201,12 +200,10 @@ public abstract class AbstractMailboxProcessor<M extends ImapRequest> extends Ab
     }
     
     private void addFlagsResponses(ImapSession session, SelectedMailbox selected, ImapProcessor.Responder responder, boolean useUid) {
-       
         try {
-  
             // To be lazily initialized only if needed, which is in minority of cases.
             MessageManager messageManager = null;
-
+            MetaData metaData = null;
             final MailboxSession mailboxSession = ImapSessionUtils.getMailboxSession(session);
 
             // Check if we need to send a FLAGS and PERMANENTFLAGS response before the FETCH response
@@ -215,48 +212,55 @@ public abstract class AbstractMailboxProcessor<M extends ImapRequest> extends Ab
             if (selected.hasNewApplicableFlags()) {
                 messageManager = getMailbox(session, selected);
                 flags(responder, selected);
-                permanentFlags(responder, messageManager.getMetaData(false, mailboxSession, MessageManager.MetaData.FetchGroup.NO_COUNT), selected);
+                metaData = messageManager.getMetaData(false, mailboxSession, MessageManager.MetaData.FetchGroup.NO_COUNT);
+
+                permanentFlags(responder, metaData, selected);
                 selected.resetNewApplicableFlags();
             }
             
             final Collection<MessageUid> flagUpdateUids = selected.flagUpdateUids();
             if (!flagUpdateUids.isEmpty()) {
                 Iterator<MessageRange> ranges = MessageRange.toRanges(flagUpdateUids).iterator();
+                if (messageManager == null) {
+                    messageManager = getMailbox(session, selected);
+                }
+                if (metaData == null) {
+                    metaData = messageManager.getMetaData(false, mailboxSession, MessageManager.MetaData.FetchGroup.NO_COUNT);
+                }
+                boolean isModSeqPermanent = metaData.isModSeqPermanent();
                 while (ranges.hasNext()) {
-                 if (messageManager == null) {
-                     messageManager = getMailbox(session, selected);
-                 }
-                    addFlagsResponses(session, selected, responder, useUid, ranges.next(), messageManager, mailboxSession);
+                    addFlagsResponses(session, selected, responder, useUid, ranges.next(), messageManager, isModSeqPermanent, mailboxSession);
                 }
-
             }
-            
+
         } catch (MailboxException e) {
             handleResponseException(responder, e, HumanReadableText.FAILURE_TO_LOAD_FLAGS, session);
         }
 
     }
     
-    protected void addFlagsResponses(ImapSession session, SelectedMailbox selected, ImapProcessor.Responder responder, boolean useUid, MessageRange messageSet, MessageManager mailbox, MailboxSession mailboxSession) throws MailboxException {
-
+    private void addFlagsResponses(ImapSession session,
+                                   SelectedMailbox selected,
+                                   ImapProcessor.Responder responder,
+                                   boolean useUid,
+                                   MessageRange messageSet, MessageManager mailbox,
+                                   boolean isModSeqPermanent,
+                                   MailboxSession mailboxSession) throws MailboxException {
         final MessageResultIterator it = mailbox.getMessages(messageSet, FetchGroupImpl.MINIMAL,  mailboxSession);
+        final boolean qresyncEnabled = EnableProcessor.getEnabledCapabilities(session).contains(ImapConstants.SUPPORTS_QRESYNC);
+        final boolean condstoreEnabled = EnableProcessor.getEnabledCapabilities(session).contains(ImapConstants.SUPPORTS_CONDSTORE);
         while (it.hasNext()) {
             MessageResult mr = it.next();
             final MessageUid uid = mr.getUid();
             int msn = selected.msn(uid);
             if (msn == SelectedMailbox.NO_SUCH_MESSAGE) {
-                LOGGER.debug("No message found with uid {} in the uid<->msn mapping for mailbox {}. This may be because it was deleted by a concurrent session. So skip it..", uid, selected.getPath().getFullName(mailboxSession.getPathDelimiter()));
-                    
-
+                LOGGER.debug("No message found with uid {} in the uid<->msn mapping for mailbox {}. This may be because it was deleted by a concurrent session. So skip it..", uid, selected.getPath().asString());
                 // skip this as it was not found in the mapping
                 // 
                 // See IMAP-346
                 continue;
             }
 
-            boolean qresyncEnabled = EnableProcessor.getEnabledCapabilities(session).contains(ImapConstants.SUPPORTS_QRESYNC);
-            boolean condstoreEnabled = EnableProcessor.getEnabledCapabilities(session).contains(ImapConstants.SUPPORTS_CONDSTORE);
-
             final Flags flags = mr.getFlags();
             final MessageUid uidOut;
             if (useUid || qresyncEnabled) {
@@ -273,7 +277,7 @@ public abstract class AbstractMailboxProcessor<M extends ImapRequest> extends Ab
             
             // Check if we also need to return the MODSEQ in the response. This is true if CONDSTORE or
             // if QRESYNC was enabled, and the mailbox supports the permant storage of mod-sequences
-            if ((condstoreEnabled || qresyncEnabled) && mailbox.getMetaData(false, mailboxSession, FetchGroup.NO_COUNT).isModSeqPermanent()) {
+            if ((condstoreEnabled || qresyncEnabled) && isModSeqPermanent) {
                 response = new FetchResponse(msn, flags, uidOut, mr.getModSeq(), null, null, null, null, null, null);
             } else {
                 response = new FetchResponse(msn, flags, uidOut, null, null, null, null, null, null, null);


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 02/06: JAMES-2746 extract QuotaLoader from MailboxFactory

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rouazana pushed a commit to branch 3.3.x
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit e65b685e8dc70aaaf9991296e1b000230b2f1fa4
Author: Rémi Kowalski <rk...@linagora.com>
AuthorDate: Tue Apr 30 16:31:56 2019 +0200

    JAMES-2746 extract QuotaLoader from MailboxFactory
---
 .../james/jmap/methods/GetMailboxesMethod.java     | 31 +++++----
 .../apache/james/jmap/model/MailboxFactory.java    | 79 +++++----------------
 .../jmap/utils/quotas/DefaultQuotaLoader.java      | 52 ++++++++++++++
 .../james/jmap/utils/quotas/QuotaLoader.java       | 50 ++++++++++++++
 .../quotas/QuotaLoaderWithDefaultPreloaded.java    | 80 ++++++++++++++++++++++
 .../james/jmap/methods/GetMailboxesMethodTest.java | 31 +++++----
 .../james/jmap/model/MailboxFactoryTest.java       |  2 +
 7 files changed, 237 insertions(+), 88 deletions(-)

diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMailboxesMethod.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMailboxesMethod.java
index ab22edc..485d364 100644
--- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMailboxesMethod.java
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/GetMailboxesMethod.java
@@ -33,13 +33,16 @@ import org.apache.james.jmap.model.GetMailboxesResponse;
 import org.apache.james.jmap.model.MailboxFactory;
 import org.apache.james.jmap.model.MailboxProperty;
 import org.apache.james.jmap.model.mailbox.Mailbox;
-import org.apache.james.jmap.model.mailbox.Quotas;
+import org.apache.james.jmap.utils.quotas.QuotaLoader;
+import org.apache.james.jmap.utils.quotas.QuotaLoaderWithDefaultPreloaded;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.exception.MailboxException;
 import org.apache.james.mailbox.model.MailboxId;
 import org.apache.james.mailbox.model.MailboxMetaData;
 import org.apache.james.mailbox.model.search.MailboxQuery;
+import org.apache.james.mailbox.quota.QuotaManager;
+import org.apache.james.mailbox.quota.QuotaRootResolver;
 import org.apache.james.metrics.api.MetricFactory;
 import org.apache.james.util.MDCBuilder;
 import org.apache.james.util.OptionalUtils;
@@ -57,17 +60,21 @@ public class GetMailboxesMethod implements Method {
     private static final Method.Request.Name METHOD_NAME = Method.Request.name("getMailboxes");
     private static final Method.Response.Name RESPONSE_NAME = Method.Response.name("mailboxes");
     private static final Optional<List<MailboxMetaData>> NO_PRELOADED_METADATA = Optional.empty();
-    private static final Optional<Quotas> NO_PRELOADED_QUOTAS = Optional.empty();
 
-    private final MailboxManager mailboxManager; 
+    private final MailboxManager mailboxManager;
     private final MailboxFactory mailboxFactory;
     private final MetricFactory metricFactory;
+    private final QuotaRootResolver quotaRootResolver;
+    private final QuotaManager quotaManager;
 
     @Inject
-    @VisibleForTesting public GetMailboxesMethod(MailboxManager mailboxManager, MailboxFactory mailboxFactory, MetricFactory metricFactory) {
+    @VisibleForTesting
+    public GetMailboxesMethod(MailboxManager mailboxManager, QuotaRootResolver quotaRootResolver, QuotaManager quotaManager, MailboxFactory mailboxFactory, MetricFactory metricFactory) {
         this.mailboxManager = mailboxManager;
         this.mailboxFactory = mailboxFactory;
         this.metricFactory = metricFactory;
+        this.quotaRootResolver = quotaRootResolver;
+        this.quotaManager = quotaManager;
     }
 
     @Override
@@ -126,15 +133,13 @@ public class GetMailboxesMethod implements Method {
     }
 
 
-
     private Stream<Mailbox> retrieveSpecificMailboxes(MailboxSession mailboxSession, ImmutableList<MailboxId> mailboxIds) {
         return mailboxIds
             .stream()
-            .map(mailboxId ->  mailboxFactory.builder()
+            .map(mailboxId -> mailboxFactory.builder()
                 .id(mailboxId)
                 .session(mailboxSession)
                 .usingPreloadedMailboxesMetadata(NO_PRELOADED_METADATA)
-                .usingPreloadedUserDefaultQuotas(NO_PRELOADED_QUOTAS)
                 .build()
             )
             .flatMap(OptionalUtils::toStream);
@@ -142,7 +147,7 @@ public class GetMailboxesMethod implements Method {
 
     private Stream<Mailbox> retrieveAllMailboxes(MailboxSession mailboxSession) throws MailboxException {
         List<MailboxMetaData> userMailboxes = getAllMailboxesMetaData(mailboxSession);
-        Quotas mailboxQuotas =  mailboxFactory.getUserDefaultQuotas(mailboxSession);
+        QuotaLoader quotaLoader = new QuotaLoaderWithDefaultPreloaded(quotaRootResolver, quotaManager, mailboxSession);
 
         return userMailboxes
             .stream()
@@ -151,17 +156,17 @@ public class GetMailboxesMethod implements Method {
                 .id(mailboxId)
                 .session(mailboxSession)
                 .usingPreloadedMailboxesMetadata(Optional.of(userMailboxes))
-                .usingPreloadedUserDefaultQuotas(Optional.of(mailboxQuotas))
+                .quotaLoader(quotaLoader)
                 .build())
             .flatMap(OptionalUtils::toStream);
     }
 
     private List<MailboxMetaData> getAllMailboxesMetaData(MailboxSession mailboxSession) throws MailboxException {
         return mailboxManager.search(
-                MailboxQuery.builder()
-                    .matchesAllMailboxNames()
-                    .build(),
-                mailboxSession);
+            MailboxQuery.builder()
+                .matchesAllMailboxNames()
+                .build(),
+            mailboxSession);
     }
 
 }
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 d2506fb..2e88972 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
@@ -23,14 +23,14 @@ import java.util.Optional;
 
 import javax.inject.Inject;
 
-import org.apache.james.core.quota.QuotaValue;
 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.Rights;
 import org.apache.james.jmap.model.mailbox.Rights.Username;
 import org.apache.james.jmap.model.mailbox.SortOrder;
+import org.apache.james.jmap.utils.quotas.DefaultQuotaLoader;
+import org.apache.james.jmap.utils.quotas.QuotaLoader;
 import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MessageManager;
@@ -41,8 +41,6 @@ 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.Quota;
-import org.apache.james.mailbox.model.QuotaRoot;
 import org.apache.james.mailbox.quota.QuotaManager;
 import org.apache.james.mailbox.quota.QuotaRootResolver;
 
@@ -57,13 +55,14 @@ public class MailboxFactory {
 
     public static class MailboxBuilder {
         private final MailboxFactory mailboxFactory;
+        private QuotaLoader quotaLoader;
         private MailboxSession session;
         private MailboxId id;
         private Optional<List<MailboxMetaData>> userMailboxesMetadata = Optional.empty();
-        private Optional<Quotas> preloadedUserDefaultQuotas = Optional.empty();
 
-        private MailboxBuilder(MailboxFactory mailboxFactory) {
+        private MailboxBuilder(MailboxFactory mailboxFactory, QuotaLoader quotaLoader) {
             this.mailboxFactory = mailboxFactory;
+            this.quotaLoader = quotaLoader;
         }
 
         public MailboxBuilder id(MailboxId id) {
@@ -76,13 +75,13 @@ public class MailboxFactory {
             return this;
         }
 
-        public MailboxBuilder usingPreloadedMailboxesMetadata(Optional<List<MailboxMetaData>> userMailboxesMetadata) {
-            this.userMailboxesMetadata = userMailboxesMetadata;
+        public MailboxBuilder quotaLoader(QuotaLoader quotaLoader) {
+            this.quotaLoader = quotaLoader;
             return this;
         }
 
-        public MailboxBuilder usingPreloadedUserDefaultQuotas(Optional<Quotas> preloadedUserDefaultQuotas) {
-            this.preloadedUserDefaultQuotas = preloadedUserDefaultQuotas;
+        public MailboxBuilder usingPreloadedMailboxesMetadata(Optional<List<MailboxMetaData>> userMailboxesMetadata) {
+            this.userMailboxesMetadata = userMailboxesMetadata;
             return this;
         }
 
@@ -92,7 +91,7 @@ public class MailboxFactory {
 
             try {
                 MessageManager mailbox = mailboxFactory.mailboxManager.getMailbox(id, session);
-                return Optional.of(mailboxFactory.fromMessageManager(mailbox, userMailboxesMetadata, preloadedUserDefaultQuotas, session));
+                return Optional.of(mailboxFactory.fromMessageManager(mailbox, userMailboxesMetadata, quotaLoader, session));
             } catch (MailboxNotFoundException e) {
                 return Optional.empty();
             } catch (MailboxException e) {
@@ -109,12 +108,13 @@ public class MailboxFactory {
     }
 
     public MailboxBuilder builder() {
-        return new MailboxBuilder(this);
+        QuotaLoader defaultQuotaLoader = new DefaultQuotaLoader(quotaRootResolver, quotaManager);
+        return new MailboxBuilder(this, defaultQuotaLoader);
     }
 
     private Mailbox fromMessageManager(MessageManager messageManager,
                                        Optional<List<MailboxMetaData>> userMailboxesMetadata,
-                                       Optional<Quotas> preloadedDefaultUserQuotas,
+                                       QuotaLoader quotaLoader,
                                        MailboxSession mailboxSession) throws MailboxException {
         MailboxPath mailboxPath = messageManager.getMailboxPath();
         boolean isOwner = mailboxPath.belongsTo(mailboxSession);
@@ -125,7 +125,7 @@ public class MailboxFactory {
             .removeEntriesFor(Username.forMailboxPath(mailboxPath));
         Username username = Username.fromSession(mailboxSession);
 
-        Quotas quotas = getQuotas(mailboxPath, preloadedDefaultUserQuotas);
+        Quotas quotas = quotaLoader.getQuotas(mailboxPath);
 
         return Mailbox.builder()
             .id(messageManager.getId())
@@ -147,49 +147,6 @@ public class MailboxFactory {
             .build();
     }
 
-    private Quotas getQuotas(MailboxPath mailboxPath, Optional<Quotas> preloadedUserDefaultQuotas) throws MailboxException {
-        QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(mailboxPath);
-        QuotaId quotaId = QuotaId.fromQuotaRoot(quotaRoot);
-
-        if (containsQuotaId(preloadedUserDefaultQuotas, quotaId)) {
-            return preloadedUserDefaultQuotas.get();
-        }
-        return Quotas.from(
-            quotaId,
-            Quotas.Quota.from(
-                quotaToValue(quotaManager.getStorageQuota(quotaRoot)),
-                quotaToValue(quotaManager.getMessageQuota(quotaRoot))));
-    }
-
-    private boolean containsQuotaId(Optional<Quotas> preloadedUserDefaultQuotas, QuotaId quotaId) {
-        return preloadedUserDefaultQuotas
-                .map(Quotas::getQuotas)
-                .map(quotaIdQuotaMap -> quotaIdQuotaMap.containsKey(quotaId))
-                .orElse(false);
-    }
-
-    public Quotas getUserDefaultQuotas(MailboxSession mailboxSession) throws MailboxException {
-        MailboxPath inboxPath = MailboxPath.inbox(mailboxSession);
-        return getQuotas(inboxPath, Optional.empty());
-    }
-
-    private <T extends QuotaValue<T>> Quotas.Value<T> quotaToValue(Quota<T> quota) {
-        return new Quotas.Value<>(
-                quotaValueToNumber(quota.getUsed()),
-                quotaValueToOptionalNumber(quota.getLimit()));
-    }
-
-    private Number quotaValueToNumber(QuotaValue<?> value) {
-        return Number.BOUND_SANITIZING_FACTORY.from(value.asLong());
-    }
-
-    private Optional<Number> quotaValueToOptionalNumber(QuotaValue<?> value) {
-        if (value.isUnlimited()) {
-            return Optional.empty();
-        }
-        return Optional.of(quotaValueToNumber(value));
-    }
-
     private MailboxNamespace getNamespace(MailboxPath mailboxPath, boolean isOwner) {
         if (isOwner) {
             return MailboxNamespace.personal();
@@ -197,7 +154,8 @@ public class MailboxFactory {
         return MailboxNamespace.delegated(mailboxPath.getUser());
     }
 
-    @VisibleForTesting String getName(MailboxPath mailboxPath, MailboxSession mailboxSession) {
+    @VisibleForTesting
+    String getName(MailboxPath mailboxPath, MailboxSession mailboxSession) {
         String name = mailboxPath.getName();
         if (name.contains(String.valueOf(mailboxSession.getPathDelimiter()))) {
             List<String> levels = Splitter.on(mailboxSession.getPathDelimiter()).splitToList(name);
@@ -206,8 +164,9 @@ public class MailboxFactory {
         return name;
     }
 
-    @VisibleForTesting Optional<MailboxId> getParentIdFromMailboxPath(MailboxPath mailboxPath, Optional<List<MailboxMetaData>> userMailboxesMetadata,
-                                                                      MailboxSession mailboxSession) throws MailboxException {
+    @VisibleForTesting
+    Optional<MailboxId> getParentIdFromMailboxPath(MailboxPath mailboxPath, Optional<List<MailboxMetaData>> userMailboxesMetadata,
+                                                   MailboxSession mailboxSession) throws MailboxException {
         List<MailboxPath> levels = mailboxPath.getHierarchyLevels(mailboxSession.getPathDelimiter());
         if (levels.size() <= 1) {
             return Optional.empty();
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/quotas/DefaultQuotaLoader.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/quotas/DefaultQuotaLoader.java
new file mode 100644
index 0000000..816d7cb
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/quotas/DefaultQuotaLoader.java
@@ -0,0 +1,52 @@
+/****************************************************************
+ * 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.utils.quotas;
+
+import javax.inject.Inject;
+
+import org.apache.james.jmap.model.mailbox.Quotas;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.QuotaRoot;
+import org.apache.james.mailbox.quota.QuotaManager;
+import org.apache.james.mailbox.quota.QuotaRootResolver;
+
+public class DefaultQuotaLoader extends QuotaLoader {
+
+    private final QuotaRootResolver quotaRootResolver;
+    private final QuotaManager quotaManager;
+
+    @Inject
+    public DefaultQuotaLoader(QuotaRootResolver quotaRootResolver, QuotaManager quotaManager) {
+        this.quotaRootResolver = quotaRootResolver;
+        this.quotaManager = quotaManager;
+    }
+
+    public Quotas getQuotas(MailboxPath mailboxPath) throws MailboxException {
+        QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(mailboxPath);
+        Quotas.QuotaId quotaId = Quotas.QuotaId.fromQuotaRoot(quotaRoot);
+
+        return Quotas.from(
+            quotaId,
+            Quotas.Quota.from(
+                quotaToValue(quotaManager.getStorageQuota(quotaRoot)),
+                quotaToValue(quotaManager.getMessageQuota(quotaRoot))));
+    }
+
+}
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/quotas/QuotaLoader.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/quotas/QuotaLoader.java
new file mode 100644
index 0000000..2d16844
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/quotas/QuotaLoader.java
@@ -0,0 +1,50 @@
+/****************************************************************
+ * 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.utils.quotas;
+
+import java.util.Optional;
+
+import org.apache.james.core.quota.QuotaValue;
+import org.apache.james.jmap.model.Number;
+import org.apache.james.jmap.model.mailbox.Quotas;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.Quota;
+
+public abstract class QuotaLoader {
+
+    public abstract Quotas getQuotas(MailboxPath mailboxPath) throws MailboxException;
+
+    protected <T extends QuotaValue<T>> Quotas.Value<T> quotaToValue(Quota<T> quota) {
+        return new Quotas.Value<>(
+            quotaValueToNumber(quota.getUsed()),
+            quotaValueToOptionalNumber(quota.getLimit()));
+    }
+
+    protected Number quotaValueToNumber(QuotaValue<?> value) {
+        return Number.BOUND_SANITIZING_FACTORY.from(value.asLong());
+    }
+
+    protected Optional<Number> quotaValueToOptionalNumber(QuotaValue<?> value) {
+        if (value.isUnlimited()) {
+            return Optional.empty();
+        }
+        return Optional.of(quotaValueToNumber(value));
+    }
+}
diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/quotas/QuotaLoaderWithDefaultPreloaded.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/quotas/QuotaLoaderWithDefaultPreloaded.java
new file mode 100644
index 0000000..abbda4f
--- /dev/null
+++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/utils/quotas/QuotaLoaderWithDefaultPreloaded.java
@@ -0,0 +1,80 @@
+/****************************************************************
+ * 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.utils.quotas;
+
+import java.util.Optional;
+
+import org.apache.james.jmap.model.mailbox.Quotas;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.QuotaRoot;
+import org.apache.james.mailbox.quota.QuotaManager;
+import org.apache.james.mailbox.quota.QuotaRootResolver;
+
+public class QuotaLoaderWithDefaultPreloaded extends QuotaLoader {
+
+    private final QuotaRootResolver quotaRootResolver;
+    private final QuotaManager quotaManager;
+    private final Optional<Quotas> preloadedUserDefaultQuotas;
+    private final MailboxSession session;
+
+    public QuotaLoaderWithDefaultPreloaded(QuotaRootResolver quotaRootResolver,
+                                           QuotaManager quotaManager,
+                                           MailboxSession session) throws MailboxException {
+        this.quotaRootResolver = quotaRootResolver;
+        this.quotaManager = quotaManager;
+        this.session = session;
+        preloadedUserDefaultQuotas = Optional.of(getUserDefaultQuotas());
+
+    }
+
+    public Quotas getQuotas(MailboxPath mailboxPath) throws MailboxException {
+        QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(mailboxPath);
+        Quotas.QuotaId quotaId = Quotas.QuotaId.fromQuotaRoot(quotaRoot);
+
+        if (containsQuotaId(preloadedUserDefaultQuotas, quotaId)) {
+            return preloadedUserDefaultQuotas.get();
+        }
+        return Quotas.from(
+            quotaId,
+            Quotas.Quota.from(
+                quotaToValue(quotaManager.getStorageQuota(quotaRoot)),
+                quotaToValue(quotaManager.getMessageQuota(quotaRoot))));
+    }
+
+    private boolean containsQuotaId(Optional<Quotas> preloadedUserDefaultQuotas, Quotas.QuotaId quotaId) {
+        return preloadedUserDefaultQuotas
+            .map(Quotas::getQuotas)
+            .map(quotaIdQuotaMap -> quotaIdQuotaMap.containsKey(quotaId))
+            .orElse(false);
+    }
+
+    private Quotas getUserDefaultQuotas() throws MailboxException {
+        QuotaRoot quotaRoot = quotaRootResolver.getQuotaRoot(MailboxPath.inbox(session));
+        Quotas.QuotaId quotaId = Quotas.QuotaId.fromQuotaRoot(quotaRoot);
+        return Quotas.from(
+            quotaId,
+            Quotas.Quota.from(
+                quotaToValue(quotaManager.getStorageQuota(quotaRoot)),
+                quotaToValue(quotaManager.getMessageQuota(quotaRoot))));
+
+    }
+
+}
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMailboxesMethodTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMailboxesMethodTest.java
index 8ee3ec0..89fad73 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMailboxesMethodTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/GetMailboxesMethodTest.java
@@ -37,7 +37,6 @@ import org.apache.james.jmap.model.MailboxFactory;
 import org.apache.james.jmap.model.Number;
 import org.apache.james.jmap.model.mailbox.Mailbox;
 import org.apache.james.jmap.model.mailbox.SortOrder;
-import org.apache.james.mailbox.MailboxManager;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageManager;
@@ -68,17 +67,19 @@ public class GetMailboxesMethodTest {
     private ClientId clientId;
     private MailboxFactory mailboxFactory;
 
+    private QuotaRootResolver quotaRootResolver;
+    private QuotaManager quotaManager;
     @Before
     public void setup() throws Exception {
         clientId = ClientId.of("#0");
         InMemoryIntegrationResources inMemoryIntegrationResources = new InMemoryIntegrationResources();
         GroupMembershipResolver groupMembershipResolver = inMemoryIntegrationResources.createGroupMembershipResolver();
         mailboxManager = inMemoryIntegrationResources.createMailboxManager(groupMembershipResolver);
-        QuotaRootResolver quotaRootResolver = mailboxManager.getQuotaComponents().getQuotaRootResolver();
-        QuotaManager quotaManager = mailboxManager.getQuotaComponents().getQuotaManager();
+        quotaRootResolver = mailboxManager.getQuotaComponents().getQuotaRootResolver();
+        quotaManager = mailboxManager.getQuotaComponents().getQuotaManager();
         mailboxFactory = new MailboxFactory(mailboxManager, quotaManager, quotaRootResolver);
 
-        getMailboxesMethod = new GetMailboxesMethod(mailboxManager, mailboxFactory, new DefaultMetricFactory());
+        getMailboxesMethod = new GetMailboxesMethod(mailboxManager, quotaRootResolver, quotaManager,  mailboxFactory, new DefaultMetricFactory());
     }
 
     @Test
@@ -87,9 +88,9 @@ public class GetMailboxesMethodTest {
                 .build();
 
         MailboxSession mailboxSession = mailboxManager.createSystemSession(USERNAME);
-        
+
         List<JmapResponse> getMailboxesResponse = getMailboxesMethod.process(getMailboxesRequest, clientId, mailboxSession).collect(Collectors.toList());
-        
+
         assertThat(getMailboxesResponse)
                 .hasSize(1)
                 .extracting(JmapResponse::getResponse)
@@ -98,22 +99,22 @@ public class GetMailboxesMethodTest {
                 .flatExtracting(GetMailboxesResponse::getList)
                 .isEmpty();
     }
-    
+
     @Test
     public void getMailboxesShouldNotFailWhenMailboxManagerErrors() throws Exception {
-        MailboxManager mockedMailboxManager = mock(MailboxManager.class);
+        StoreMailboxManager mockedMailboxManager = mock(StoreMailboxManager.class);
         when(mockedMailboxManager.list(any()))
             .thenReturn(ImmutableList.of(new MailboxPath("namespace", "user", "name")));
         when(mockedMailboxManager.getMailbox(any(MailboxPath.class), any()))
             .thenThrow(new MailboxException());
-        GetMailboxesMethod testee = new GetMailboxesMethod(mockedMailboxManager, mailboxFactory, new DefaultMetricFactory());
-        
+        GetMailboxesMethod testee = new GetMailboxesMethod(mockedMailboxManager, quotaRootResolver, quotaManager, mailboxFactory, new DefaultMetricFactory());
+
         GetMailboxesRequest getMailboxesRequest = GetMailboxesRequest.builder()
                 .build();
         MailboxSession session = MailboxSessionUtil.create(USERNAME);
-        
+
         List<JmapResponse> getMailboxesResponse = testee.process(getMailboxesRequest, clientId, session).collect(Collectors.toList());
-        
+
         assertThat(getMailboxesResponse)
                 .hasSize(1)
                 .extracting(JmapResponse::getResponse)
@@ -143,7 +144,7 @@ public class GetMailboxesMethodTest {
                 .build();
 
         List<JmapResponse> getMailboxesResponse = getMailboxesMethod.process(getMailboxesRequest, clientId, mailboxSession).collect(Collectors.toList());
-        
+
         assertThat(getMailboxesResponse)
                 .hasSize(1)
                 .extracting(JmapResponse::getResponse)
@@ -168,7 +169,7 @@ public class GetMailboxesMethodTest {
                 .build();
 
         List<JmapResponse> getMailboxesResponse = getMailboxesMethod.process(getMailboxesRequest, clientId, userSession).collect(Collectors.toList());
-        
+
         assertThat(getMailboxesResponse)
                 .hasSize(1)
                 .extracting(JmapResponse::getResponse)
@@ -382,7 +383,7 @@ public class GetMailboxesMethodTest {
         mailboxManager.createMailbox(MailboxPath.forUser(USERNAME, "Spam"), mailboxSession);
         mailboxManager.createMailbox(MailboxPath.forUser(USERNAME, "Templates"), mailboxSession);
         mailboxManager.createMailbox(MailboxPath.forUser(USERNAME, "WITHOUT ROLE"), mailboxSession);
-        
+
         GetMailboxesRequest getMailboxesRequest = GetMailboxesRequest.builder()
                 .build();
 
diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MailboxFactoryTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MailboxFactoryTest.java
index 013e3ed..bef0d34 100644
--- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MailboxFactoryTest.java
+++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/MailboxFactoryTest.java
@@ -24,6 +24,8 @@ import java.util.Optional;
 
 import org.apache.james.jmap.model.mailbox.Mailbox;
 import org.apache.james.jmap.model.mailbox.MailboxNamespace;
+import org.apache.james.jmap.utils.quotas.DefaultQuotaLoader;
+import org.apache.james.jmap.utils.quotas.QuotaLoader;
 import org.apache.james.mailbox.MailboxSession;
 import org.apache.james.mailbox.inmemory.InMemoryId;
 import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


[james-project] 06/06: JAMES-2754 extract external James configuration

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rouazana pushed a commit to branch 3.3.x
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 86279b66f16ef8345170aa67092789899cbe738e
Author: Antoine DUPRAT <ad...@linagora.com>
AuthorDate: Tue Jun 11 08:50:29 2019 +0200

    JAMES-2754 extract external James configuration
---
 dockerfiles/compilation/java-8/integration_tests.sh | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/dockerfiles/compilation/java-8/integration_tests.sh b/dockerfiles/compilation/java-8/integration_tests.sh
index bfef037..856262d 100755
--- a/dockerfiles/compilation/java-8/integration_tests.sh
+++ b/dockerfiles/compilation/java-8/integration_tests.sh
@@ -5,6 +5,7 @@ printUsage() {
    echo "./integration_tests.sh URL BRANCH JAMES_IP JAMES_IMAP_PORT"
    echo "    JAMES_IP: IP of the James server to be tests"
    echo "    JAMES_IMAP_PORT: Exposed IMAP port of this James server"
+   echo "    JAMES_SMTP_PORT: Exposed SMTP port of this James server"
    echo "    SHA1(optional): Branch to build or master if none"
    exit 1
 }
@@ -26,7 +27,10 @@ do
             JAMES_IMAP_PORT=$2
          fi
          if ! [ -z "$3" ]; then
-            SHA1=$3
+            JAMES_SMTP_PORT=$3
+         fi
+         if ! [ -z "$4" ]; then
+            SHA1=$4
          fi
          ;;
    esac
@@ -42,12 +46,18 @@ if [ -z "$JAMES_IMAP_PORT" ]; then
    printUsage
 fi
 
+if [ -z "$JAMES_SMTP_PORT" ]; then
+   echo "You must provide a JAMES_SMTP_PORT"
+   printUsage
+fi
+
 if [ -z "$SHA1" ]; then
    SHA1=master
 fi
 
 export JAMES_ADDRESS=$JAMES_ADDRESS
 export JAMES_IMAP_PORT=$JAMES_IMAP_PORT
+export JAMES_SMTP_PORT=$JAMES_SMTP_PORT
 
 git clone $ORIGIN/.
 git checkout $SHA1


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org