JAMES-2400 Provide a simple scanning implementation for QuotaSearcher

Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/c58a673c
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/c58a673c
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/c58a673c

Branch: refs/heads/master
Commit: c58a673c2ec4b3871ab1f25ad34fd2602ca094d9
Parents: 3bb7ee8
Author: benwa <btell...@linagora.com>
Authored: Mon May 21 12:03:31 2018 +0700
Committer: benwa <btell...@linagora.com>
Committed: Wed May 23 09:09:41 2018 +0700

----------------------------------------------------------------------
 .../java/org/apache/james/core/CoreFixture.java |   4 +-
 mailbox/plugin/quota-search-scanning/pom.xml    | 102 ++++++++++++++++++
 .../quota/search/scanning/ClauseConverter.java  | 103 +++++++++++++++++++
 .../search/scanning/ScanningQuotaSearcher.java  |  74 +++++++++++++
 .../MemoryQuotaSearchTestSystemExtension.java   |  63 ++++++++++++
 .../scanning/ScanningQuotaSearcherTest.java     |  28 +++++
 mailbox/pom.xml                                 |   1 +
 pom.xml                                         |  11 ++
 8 files changed, 384 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/c58a673c/core/src/test/java/org/apache/james/core/CoreFixture.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/james/core/CoreFixture.java 
b/core/src/test/java/org/apache/james/core/CoreFixture.java
index 237e78e..4220bc3 100644
--- a/core/src/test/java/org/apache/james/core/CoreFixture.java
+++ b/core/src/test/java/org/apache/james/core/CoreFixture.java
@@ -20,8 +20,8 @@
 package org.apache.james.core;
 
 import static org.apache.james.core.CoreFixture.Domains.ALPHABET_TLD;
-import static org.apache.james.core.CoreFixture.Domains.SIMPSON_COM;
 import static org.apache.james.core.CoreFixture.Domains.DOMAIN_TLD;
+import static org.apache.james.core.CoreFixture.Domains.SIMPSON_COM;
 
 public interface CoreFixture {
     interface Domains {
@@ -34,7 +34,7 @@ public interface CoreFixture {
         interface Simpson {
             User BART = User.fromLocalPartWithDomain("bart", SIMPSON_COM);
             User HOMER = User.fromLocalPartWithDomain("homer", SIMPSON_COM);
-            User LISA = User.fromLocalPartWithDomain("foo3", SIMPSON_COM);
+            User LISA = User.fromLocalPartWithDomain("lisa", SIMPSON_COM);
         }
 
         interface Alphabet {

http://git-wip-us.apache.org/repos/asf/james-project/blob/c58a673c/mailbox/plugin/quota-search-scanning/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/plugin/quota-search-scanning/pom.xml 
b/mailbox/plugin/quota-search-scanning/pom.xml
new file mode 100644
index 0000000..97ad7a9
--- /dev/null
+++ b/mailbox/plugin/quota-search-scanning/pom.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>apache-james-mailbox</artifactId>
+        <groupId>org.apache.james</groupId>
+        <version>3.1.0-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>apache-james-mailbox-quota-search-scanning</artifactId>
+    <name>Apache James :: Mailbox :: Plugin :: Quota Search :: Scanning</name>
+    <description>Apache James Mailbox scanning implementation for quota 
search</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-api</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-memory</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-memory</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-quota-search</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>apache-james-mailbox-quota-search</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>james-core</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-data-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>${project.groupId}</groupId>
+            <artifactId>james-server-data-memory</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-launcher</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/c58a673c/mailbox/plugin/quota-search-scanning/src/main/java/org/apache/james/quota/search/scanning/ClauseConverter.java
----------------------------------------------------------------------
diff --git 
a/mailbox/plugin/quota-search-scanning/src/main/java/org/apache/james/quota/search/scanning/ClauseConverter.java
 
b/mailbox/plugin/quota-search-scanning/src/main/java/org/apache/james/quota/search/scanning/ClauseConverter.java
new file mode 100644
index 0000000..43e158c
--- /dev/null
+++ 
b/mailbox/plugin/quota-search-scanning/src/main/java/org/apache/james/quota/search/scanning/ClauseConverter.java
@@ -0,0 +1,103 @@
+/****************************************************************
+ * 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.quota.search.scanning;
+
+import java.util.Map;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+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.QuotaCount;
+import org.apache.james.mailbox.quota.QuotaManager;
+import org.apache.james.mailbox.quota.QuotaSize;
+import org.apache.james.mailbox.quota.UserQuotaRootResolver;
+import org.apache.james.quota.search.QuotaClause;
+
+import com.google.common.collect.ImmutableMap;
+
+public class ClauseConverter {
+
+    private final UserQuotaRootResolver quotaRootResolver;
+    private final QuotaManager quotaManager;
+    private final Map<Class<? extends QuotaClause>, Function<QuotaClause, 
Predicate<User>>> toPredicates;
+
+    @Inject
+    public ClauseConverter(UserQuotaRootResolver quotaRootResolver, 
QuotaManager quotaManager) {
+        this.quotaRootResolver = quotaRootResolver;
+        this.quotaManager = quotaManager;
+        this.toPredicates = ImmutableMap.of(
+            QuotaClause.And.class, this::andToPredicate,
+            QuotaClause.LessThan.class, this::lessThanToPredicate,
+            QuotaClause.MoreThan.class, this::moreThanToPredicate,
+            QuotaClause.HasDomain.class, this::hasDomainToPredicate);
+    }
+
+    public Predicate<User> andToPredicate(QuotaClause.And and) {
+        return and.getClauses()
+            .stream()
+            .map(this::toPredicate)
+            .reduce((p1, p2) -> (user -> p1.test(user) && p2.test(user)))
+            .orElse(user -> true);
+    }
+
+    public Predicate<User> toPredicate(QuotaClause clause) {
+        return toPredicates.get(clause.getClass())
+            .apply(clause);
+    }
+
+    public Predicate<User> moreThanToPredicate(QuotaClause clause) {
+        QuotaClause.MoreThan moreThan = (QuotaClause.MoreThan) clause;
+        return user -> retrieveUserRatio(user) >= 
moreThan.getQuotaBoundary().getRatio();
+    }
+
+    public Predicate<User> lessThanToPredicate(QuotaClause clause) {
+        QuotaClause.LessThan lessThan = (QuotaClause.LessThan) clause;
+        return user -> retrieveUserRatio(user) <= 
lessThan.getQuotaBoundary().getRatio();
+    }
+
+    public Predicate<User> hasDomainToPredicate(QuotaClause clause) {
+        QuotaClause.HasDomain hasDomain = (QuotaClause.HasDomain) clause;
+        return user -> user.getDomainPart()
+            .map(hasDomain.getDomain()::equals)
+            .orElse(false);
+    }
+
+    public Predicate<User> andToPredicate(QuotaClause clause) {
+        QuotaClause.And and = (QuotaClause.And) clause;
+        return andToPredicate(and);
+    }
+
+    public double retrieveUserRatio(User user) {
+        try {
+            QuotaRoot quotaRoot = quotaRootResolver.forUser(user);
+            Quota<QuotaSize> storageQuota = 
quotaManager.getStorageQuota(quotaRoot);
+            Quota<QuotaCount> messageQuota = 
quotaManager.getMessageQuota(quotaRoot);
+
+            return Math.max(storageQuota.getRatio(), messageQuota.getRatio());
+        } catch (MailboxException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c58a673c/mailbox/plugin/quota-search-scanning/src/main/java/org/apache/james/quota/search/scanning/ScanningQuotaSearcher.java
----------------------------------------------------------------------
diff --git 
a/mailbox/plugin/quota-search-scanning/src/main/java/org/apache/james/quota/search/scanning/ScanningQuotaSearcher.java
 
b/mailbox/plugin/quota-search-scanning/src/main/java/org/apache/james/quota/search/scanning/ScanningQuotaSearcher.java
new file mode 100644
index 0000000..8d388d0
--- /dev/null
+++ 
b/mailbox/plugin/quota-search-scanning/src/main/java/org/apache/james/quota/search/scanning/ScanningQuotaSearcher.java
@@ -0,0 +1,74 @@
+/****************************************************************
+ * 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.quota.search.scanning;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Stream;
+
+import javax.inject.Inject;
+
+import org.apache.james.core.User;
+import org.apache.james.quota.search.Limit;
+import org.apache.james.quota.search.QuotaQuery;
+import org.apache.james.quota.search.QuotaSearcher;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.james.user.api.UsersRepositoryException;
+import org.apache.james.util.streams.Iterators;
+
+import com.github.steveash.guavate.Guavate;
+
+public class ScanningQuotaSearcher implements QuotaSearcher {
+    private final UsersRepository usersRepository;
+    private final ClauseConverter clauseConverter;
+
+    @Inject
+    public ScanningQuotaSearcher(UsersRepository usersRepository, 
ClauseConverter clauseConverter) {
+        this.usersRepository = usersRepository;
+        this.clauseConverter = clauseConverter;
+    }
+
+    @Override
+    public List<User> search(QuotaQuery query) {
+        Stream<User> results = Iterators.toStream(listUsers())
+            .map(User::fromUsername)
+            .filter(clauseConverter.andToPredicate(query.getClause()))
+            .sorted(Comparator.comparing(User::asString))
+            .skip(query.getOffset().getValue());
+
+        return limit(results, query.getLimit())
+            .collect(Guavate.toImmutableList());
+    }
+
+    public Stream<User> limit(Stream<User> results, Limit limit) {
+        return limit.getValue()
+            .map(results::limit)
+            .orElse(results);
+    }
+
+    public Iterator<String> listUsers() {
+        try {
+            return usersRepository.list();
+        } catch (UsersRepositoryException e) {
+            throw new RuntimeException(e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c58a673c/mailbox/plugin/quota-search-scanning/src/test/java/org/apache/james/quota/search/scanning/MemoryQuotaSearchTestSystemExtension.java
----------------------------------------------------------------------
diff --git 
a/mailbox/plugin/quota-search-scanning/src/test/java/org/apache/james/quota/search/scanning/MemoryQuotaSearchTestSystemExtension.java
 
b/mailbox/plugin/quota-search-scanning/src/test/java/org/apache/james/quota/search/scanning/MemoryQuotaSearchTestSystemExtension.java
new file mode 100644
index 0000000..6bd1df3
--- /dev/null
+++ 
b/mailbox/plugin/quota-search-scanning/src/test/java/org/apache/james/quota/search/scanning/MemoryQuotaSearchTestSystemExtension.java
@@ -0,0 +1,63 @@
+/****************************************************************
+ * 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.quota.search.scanning;
+
+import static org.mockito.Mockito.mock;
+
+import org.apache.james.dnsservice.api.DNSService;
+import org.apache.james.domainlist.memory.MemoryDomainList;
+import org.apache.james.mailbox.acl.SimpleGroupMembershipResolver;
+import org.apache.james.mailbox.inmemory.manager.InMemoryIntegrationResources;
+import org.apache.james.quota.search.QuotaSearchTestSystem;
+import org.apache.james.user.memory.MemoryUsersRepository;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.api.extension.ParameterContext;
+import org.junit.jupiter.api.extension.ParameterResolutionException;
+import org.junit.jupiter.api.extension.ParameterResolver;
+
+public class MemoryQuotaSearchTestSystemExtension implements ParameterResolver 
{
+
+    @Override
+    public boolean supportsParameter(ParameterContext parameterContext, 
ExtensionContext extensionContext) throws ParameterResolutionException {
+        return (parameterContext.getParameter().getType() == 
QuotaSearchTestSystem.class);
+    }
+
+    @Override
+    public Object resolveParameter(ParameterContext parameterContext, 
ExtensionContext extensionContext) throws ParameterResolutionException {
+        try {
+            InMemoryIntegrationResources.Resources resources = new 
InMemoryIntegrationResources().createResources(new 
SimpleGroupMembershipResolver());
+
+            MemoryUsersRepository usersRepository = 
MemoryUsersRepository.withVirtualHosting();
+
+            DNSService dnsService = mock(DNSService.class);
+            MemoryDomainList domainList = new MemoryDomainList(dnsService);
+            usersRepository.setDomainList(domainList);
+
+            return new QuotaSearchTestSystem(
+                resources.getMaxQuotaManager(),
+                resources.getMailboxManager(),
+                new ScanningQuotaSearcher(usersRepository,
+                    new ClauseConverter(resources.getQuotaRootResolver(), 
resources.getQuotaManager())),
+                usersRepository, domainList);
+        } catch (Exception e) {
+            throw new ParameterResolutionException("Error while resolving 
parameter", e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c58a673c/mailbox/plugin/quota-search-scanning/src/test/java/org/apache/james/quota/search/scanning/ScanningQuotaSearcherTest.java
----------------------------------------------------------------------
diff --git 
a/mailbox/plugin/quota-search-scanning/src/test/java/org/apache/james/quota/search/scanning/ScanningQuotaSearcherTest.java
 
b/mailbox/plugin/quota-search-scanning/src/test/java/org/apache/james/quota/search/scanning/ScanningQuotaSearcherTest.java
new file mode 100644
index 0000000..bc24047
--- /dev/null
+++ 
b/mailbox/plugin/quota-search-scanning/src/test/java/org/apache/james/quota/search/scanning/ScanningQuotaSearcherTest.java
@@ -0,0 +1,28 @@
+/****************************************************************
+ * 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.quota.search.scanning;
+
+import org.apache.james.quota.search.QuotaSearcherContract;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+@ExtendWith(MemoryQuotaSearchTestSystemExtension.class)
+public class ScanningQuotaSearcherTest implements QuotaSearcherContract {
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c58a673c/mailbox/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/pom.xml b/mailbox/pom.xml
index beac9a4..4db6033 100644
--- a/mailbox/pom.xml
+++ b/mailbox/pom.xml
@@ -57,6 +57,7 @@
         <module>plugin/quota-mailing-cassandra</module>
         <module>plugin/quota-mailing-memory</module>
         <module>plugin/quota-search</module>
+        <module>plugin/quota-search-scanning</module>
         <module>plugin/spamassassin</module>
     </modules>
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/c58a673c/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 3b4fa0b..52e7c40 100644
--- a/pom.xml
+++ b/pom.xml
@@ -809,6 +809,17 @@
             </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
+                <artifactId>apache-james-mailbox-quota-search</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>apache-james-mailbox-quota-search</artifactId>
+                <version>${project.version}</version>
+                <type>test-jar</type>
+            </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
                 <artifactId>apache-james-mailbox-scanning-search</artifactId>
                 <version>${project.version}</version>
             </dependency>


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

Reply via email to