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

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

commit f22d4c4f70e4389db5089d4d200098f1c2a7a66e
Author: Rene Cordier <rcord...@linagora.com>
AuthorDate: Fri Aug 25 17:27:42 2023 +0700

    JAMES-3926 Implement CassandraCurrentQuotaManagerMigration
---
 mailbox/cassandra/pom.xml                          |  10 ++
 .../CassandraCurrentQuotaManagerMigration.java     |  67 +++++++++++
 .../CassandraCurrentQuotaManagerMigrationTest.java | 124 +++++++++++++++++++++
 3 files changed, 201 insertions(+)

diff --git a/mailbox/cassandra/pom.xml b/mailbox/cassandra/pom.xml
index 22255438ea..101c1c92aa 100644
--- a/mailbox/cassandra/pom.xml
+++ b/mailbox/cassandra/pom.xml
@@ -111,11 +111,21 @@
             <type>test-jar</type>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-data-api</artifactId>
+        </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>james-server-data-cassandra</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-data-library</artifactId>
+            <type>test-jar</type>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>james-server-task-api</artifactId>
diff --git 
a/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/migration/CassandraCurrentQuotaManagerMigration.java
 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/migration/CassandraCurrentQuotaManagerMigration.java
new file mode 100644
index 0000000000..b22e2aec63
--- /dev/null
+++ 
b/mailbox/cassandra/src/main/java/org/apache/james/mailbox/cassandra/quota/migration/CassandraCurrentQuotaManagerMigration.java
@@ -0,0 +1,67 @@
+/****************************************************************
+ * 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.mailbox.cassandra.quota.migration;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.apache.james.backends.cassandra.migration.Migration;
+import org.apache.james.core.Username;
+import org.apache.james.mailbox.model.QuotaOperation;
+import org.apache.james.mailbox.model.QuotaRoot;
+import org.apache.james.mailbox.quota.CurrentQuotaManager;
+import org.apache.james.mailbox.quota.UserQuotaRootResolver;
+import org.apache.james.user.api.UsersRepository;
+
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+
+public class CassandraCurrentQuotaManagerMigration implements Migration {
+    private final UsersRepository usersRepository;
+    private final UserQuotaRootResolver userQuotaRootResolver;
+    private final CurrentQuotaManager oldCurrentQuotaManager;
+    private final CurrentQuotaManager newCurrentQuotaManager;
+
+    @Inject
+    public CassandraCurrentQuotaManagerMigration(UsersRepository 
usersRepository,
+                                                 UserQuotaRootResolver 
userQuotaRootResolver,
+                                                 @Named("old") 
CurrentQuotaManager oldCurrentQuotaManager,
+                                                 CurrentQuotaManager 
newCurrentQuotaManager) {
+        this.usersRepository = usersRepository;
+        this.userQuotaRootResolver = userQuotaRootResolver;
+        this.oldCurrentQuotaManager = oldCurrentQuotaManager;
+        this.newCurrentQuotaManager = newCurrentQuotaManager;
+    }
+
+    @Override
+    public void apply() throws InterruptedException {
+        Flux.from(usersRepository.listReactive())
+            .flatMap(this::migrateCurrentValue)
+            .then()
+            .block();
+    }
+
+    private Mono<Void> migrateCurrentValue(Username username) {
+        QuotaRoot quotaRoot = userQuotaRootResolver.forUser(username);
+
+        return Mono.from(oldCurrentQuotaManager.getCurrentQuotas(quotaRoot))
+            .flatMap(currentQuotas -> 
Mono.from(newCurrentQuotaManager.setCurrentQuotas(QuotaOperation.from(quotaRoot,
 currentQuotas))));
+    }
+}
diff --git 
a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/migration/CassandraCurrentQuotaManagerMigrationTest.java
 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/migration/CassandraCurrentQuotaManagerMigrationTest.java
new file mode 100644
index 0000000000..cb33b72735
--- /dev/null
+++ 
b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/quota/migration/CassandraCurrentQuotaManagerMigrationTest.java
@@ -0,0 +1,124 @@
+/****************************************************************
+ * 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.mailbox.cassandra.quota.migration;
+
+import static 
org.apache.james.mailbox.store.quota.DefaultUserQuotaRootResolver.SEPARATOR;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.commons.configuration2.BaseHierarchicalConfiguration;
+import org.apache.james.backends.cassandra.CassandraCluster;
+import org.apache.james.backends.cassandra.CassandraClusterExtension;
+import org.apache.james.backends.cassandra.components.CassandraModule;
+import 
org.apache.james.backends.cassandra.components.CassandraMutualizedQuotaModule;
+import 
org.apache.james.backends.cassandra.components.CassandraQuotaCurrentValueDao;
+import org.apache.james.core.Domain;
+import org.apache.james.core.Username;
+import org.apache.james.core.quota.QuotaCountUsage;
+import org.apache.james.core.quota.QuotaSizeUsage;
+import org.apache.james.domainlist.api.DomainList;
+import org.apache.james.domainlist.api.mock.SimpleDomainList;
+import org.apache.james.domainlist.cassandra.CassandraDomainListModule;
+import org.apache.james.mailbox.cassandra.modules.CassandraQuotaModule;
+import org.apache.james.mailbox.cassandra.quota.CassandraCurrentQuotaManagerV1;
+import org.apache.james.mailbox.cassandra.quota.CassandraCurrentQuotaManagerV2;
+import org.apache.james.mailbox.model.CurrentQuotas;
+import org.apache.james.mailbox.model.MailboxConstants;
+import org.apache.james.mailbox.model.QuotaOperation;
+import org.apache.james.mailbox.model.QuotaRoot;
+import org.apache.james.mailbox.quota.UserQuotaRootResolver;
+import org.apache.james.user.api.UsersRepository;
+import org.apache.james.user.cassandra.CassandraUsersDAO;
+import org.apache.james.user.cassandra.CassandraUsersRepositoryModule;
+import org.apache.james.user.lib.UsersRepositoryImpl;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+public class CassandraCurrentQuotaManagerMigrationTest {
+    private static final Username BOB = Username.of("bob");
+    private static final QuotaRoot QUOTA_ROOT = 
QuotaRoot.quotaRoot(MailboxConstants.USER_NAMESPACE + SEPARATOR + 
BOB.asString(), BOB.getDomainPart());
+
+    @RegisterExtension
+    static CassandraClusterExtension cassandraCluster = new 
CassandraClusterExtension(CassandraModule.aggregateModules(
+        CassandraQuotaModule.MODULE,
+        CassandraUsersRepositoryModule.MODULE,
+        CassandraDomainListModule.MODULE,
+        CassandraMutualizedQuotaModule.MODULE));
+
+    private UsersRepositoryImpl<CassandraUsersDAO> getUsersRepository() throws 
Exception {
+        boolean enableVirtualHosting = false;
+        DomainList domainList = new SimpleDomainList();
+        domainList.addDomain(Domain.of("domain.tld"));
+        CassandraUsersDAO usersDAO = new 
CassandraUsersDAO(cassandraCluster.getCassandraCluster().getConf());
+        BaseHierarchicalConfiguration configuration = new 
BaseHierarchicalConfiguration();
+        configuration.addProperty("enableVirtualHosting", 
String.valueOf(enableVirtualHosting));
+
+        UsersRepositoryImpl<CassandraUsersDAO> usersRepository = new 
UsersRepositoryImpl<>(domainList, usersDAO);
+        usersRepository.configure(configuration);
+        return usersRepository;
+    }
+
+    private CassandraCurrentQuotaManagerV1 oldCurrentQuotaManager;
+    private CassandraCurrentQuotaManagerV2 newCurrentQuotaManager;
+    private UserQuotaRootResolver userQuotaRootResolver;
+    private CassandraCurrentQuotaManagerMigration testee;
+
+    @BeforeEach
+    void setUp() throws Exception {
+        CassandraCluster cassandra = cassandraCluster.getCassandraCluster();
+
+        oldCurrentQuotaManager = new 
CassandraCurrentQuotaManagerV1(cassandra.getConf());
+        newCurrentQuotaManager = new CassandraCurrentQuotaManagerV2(new 
CassandraQuotaCurrentValueDao(cassandra.getConf()));
+        UsersRepository usersRepository = getUsersRepository();
+
+        usersRepository.addUser(BOB, "passBob");
+
+        userQuotaRootResolver = mock(UserQuotaRootResolver.class);
+        when(userQuotaRootResolver.forUser(eq(BOB))).thenReturn(QUOTA_ROOT);
+
+        testee = new CassandraCurrentQuotaManagerMigration(usersRepository, 
userQuotaRootResolver, oldCurrentQuotaManager, newCurrentQuotaManager);
+    }
+
+    @Test
+    void shouldMigrateQuotaUsage() throws Exception {
+        CurrentQuotas currentQuotas = new 
CurrentQuotas(QuotaCountUsage.count(42L), QuotaSizeUsage.size(172L));
+        QuotaOperation quotaOperation =  QuotaOperation.from(QUOTA_ROOT, 
currentQuotas);
+
+        oldCurrentQuotaManager.setCurrentQuotas(quotaOperation).block();
+
+        testee.apply();
+
+        assertThat(newCurrentQuotaManager.getCurrentQuotas(QUOTA_ROOT).block())
+            .isEqualTo(currentQuotas);
+    }
+
+    @Test
+    void shouldNotFailWhenNoQuota() throws Exception {
+        CurrentQuotas defaultQuota = new 
CurrentQuotas(QuotaCountUsage.count(0L), QuotaSizeUsage.size(0L));
+
+        testee.apply();
+
+        assertThat(newCurrentQuotaManager.getCurrentQuotas(QUOTA_ROOT).block())
+            .isEqualTo(defaultQuota);
+    }
+}


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

Reply via email to