This is an automated email from the ASF dual-hosted git repository. chibenwa pushed a commit to branch 3.9.x in repository https://gitbox.apache.org/repos/asf/james-project.git
commit 0a186ea38b4ee3b922410d7bf30e6a007e9a6734 Author: Benoit TELLIER <[email protected]> AuthorDate: Mon Jun 22 21:11:37 2026 +0200 [FIX] User rename was returning wrong quota when target address is not empty (backport) --- ...CassandraRecomputeCurrentQuotasServiceTest.java | 17 ++++++++++- .../task/JPARecomputeCurrentQuotasServiceTest.java | 18 +++++++++++- .../MemoryRecomputeCurrentQuotasServiceTest.java | 4 ++- .../PostgresRecomputeCurrentQuotasServiceTest.java | 19 ++++++++++++- .../task/RecomputeMailboxCurrentQuotasService.java | 33 +++++++++++++++++++++- .../mailbox/QuotaUsernameChangeTaskStepTest.java | 4 ++- 6 files changed, 89 insertions(+), 6 deletions(-) diff --git a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/CassandraRecomputeCurrentQuotasServiceTest.java b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/CassandraRecomputeCurrentQuotasServiceTest.java index 237014ac7e..c04a8b9d6d 100644 --- a/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/CassandraRecomputeCurrentQuotasServiceTest.java +++ b/mailbox/cassandra/src/test/java/org/apache/james/mailbox/cassandra/mail/task/CassandraRecomputeCurrentQuotasServiceTest.java @@ -21,6 +21,11 @@ package org.apache.james.mailbox.cassandra.mail.task; import static org.apache.james.backends.cassandra.Scenario.Builder.fail; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Set; import org.apache.james.backends.cassandra.CassandraCluster; import org.apache.james.backends.cassandra.CassandraClusterExtension; @@ -28,6 +33,8 @@ import org.apache.james.backends.cassandra.components.CassandraDataDefinition; import org.apache.james.core.quota.QuotaComponent; import org.apache.james.domainlist.api.DomainList; import org.apache.james.domainlist.cassandra.CassandraDomainListDataDefinition; +import org.apache.james.events.Event; +import org.apache.james.events.EventBus; import org.apache.james.mailbox.MailboxManager; import org.apache.james.mailbox.MailboxSession; import org.apache.james.mailbox.MessageManager; @@ -36,6 +43,7 @@ import org.apache.james.mailbox.cassandra.CassandraMailboxSessionMapperFactory; import org.apache.james.mailbox.cassandra.CassandraTestSystemFixture; import org.apache.james.mailbox.cassandra.mail.MailboxAggregateModule; import org.apache.james.mailbox.quota.CurrentQuotaManager; +import org.apache.james.mailbox.quota.QuotaManager; import org.apache.james.mailbox.quota.UserQuotaRootResolver; import org.apache.james.mailbox.quota.task.RecomputeCurrentQuotasService; import org.apache.james.mailbox.quota.task.RecomputeCurrentQuotasService.RunningOptions; @@ -89,12 +97,19 @@ public class CassandraRecomputeCurrentQuotasServiceTest implements RecomputeCurr userQuotaRootResolver = new DefaultUserQuotaRootResolver(sessionProvider, mapperFactory); CurrentQuotaCalculator currentQuotaCalculator = new CurrentQuotaCalculator(mapperFactory, userQuotaRootResolver); + QuotaManager quotaManager = mock(QuotaManager.class); + when(quotaManager.getQuotasReactive(any())).thenReturn(reactor.core.publisher.Mono.empty()); + EventBus eventBus = mock(EventBus.class); + when(eventBus.dispatch(any(Event.class), any(Set.class))).thenReturn(reactor.core.publisher.Mono.empty()); + testee = new RecomputeCurrentQuotasService(usersRepository, ImmutableSet.of(new RecomputeMailboxCurrentQuotasService(currentQuotaManager, currentQuotaCalculator, userQuotaRootResolver, sessionProvider, - mailboxManager), + mailboxManager, + quotaManager, + eventBus), RECOMPUTE_JMAP_UPLOAD_CURRENT_QUOTAS_SERVICE)); } diff --git a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/task/JPARecomputeCurrentQuotasServiceTest.java b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/task/JPARecomputeCurrentQuotasServiceTest.java index fef8c93b92..1304c27cb6 100644 --- a/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/task/JPARecomputeCurrentQuotasServiceTest.java +++ b/mailbox/jpa/src/test/java/org/apache/james/mailbox/jpa/mail/task/JPARecomputeCurrentQuotasServiceTest.java @@ -19,6 +19,12 @@ package org.apache.james.mailbox.jpa.mail.task; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Set; + import jakarta.persistence.EntityManagerFactory; import org.apache.commons.configuration2.BaseHierarchicalConfiguration; @@ -26,6 +32,8 @@ import org.apache.james.backends.jpa.JPAConfiguration; import org.apache.james.backends.jpa.JpaTestCluster; import org.apache.james.domainlist.api.DomainList; import org.apache.james.domainlist.jpa.model.JPADomain; +import org.apache.james.events.Event; +import org.apache.james.events.EventBus; import org.apache.james.mailbox.MailboxManager; import org.apache.james.mailbox.SessionProvider; import org.apache.james.mailbox.jpa.JPAMailboxFixture; @@ -35,6 +43,7 @@ import org.apache.james.mailbox.jpa.mail.JPAModSeqProvider; import org.apache.james.mailbox.jpa.mail.JPAUidProvider; import org.apache.james.mailbox.jpa.quota.JpaCurrentQuotaManager; import org.apache.james.mailbox.quota.CurrentQuotaManager; +import org.apache.james.mailbox.quota.QuotaManager; import org.apache.james.mailbox.quota.UserQuotaRootResolver; import org.apache.james.mailbox.quota.task.RecomputeCurrentQuotasService; import org.apache.james.mailbox.quota.task.RecomputeCurrentQuotasServiceContract; @@ -97,12 +106,19 @@ class JPARecomputeCurrentQuotasServiceTest implements RecomputeCurrentQuotasServ CurrentQuotaCalculator currentQuotaCalculator = new CurrentQuotaCalculator(mapperFactory, userQuotaRootResolver); + QuotaManager quotaManager = mock(QuotaManager.class); + when(quotaManager.getQuotasReactive(any())).thenReturn(reactor.core.publisher.Mono.empty()); + EventBus eventBus = mock(EventBus.class); + when(eventBus.dispatch(any(Event.class), any(Set.class))).thenReturn(reactor.core.publisher.Mono.empty()); + testee = new RecomputeCurrentQuotasService(usersRepository, ImmutableSet.of(new RecomputeMailboxCurrentQuotasService(currentQuotaManager, currentQuotaCalculator, userQuotaRootResolver, sessionProvider, - mailboxManager), + mailboxManager, + quotaManager, + eventBus), RECOMPUTE_JMAP_UPLOAD_CURRENT_QUOTAS_SERVICE)); } diff --git a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/task/MemoryRecomputeCurrentQuotasServiceTest.java b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/task/MemoryRecomputeCurrentQuotasServiceTest.java index 40568fbe81..7e01b8b36a 100644 --- a/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/task/MemoryRecomputeCurrentQuotasServiceTest.java +++ b/mailbox/memory/src/test/java/org/apache/james/mailbox/inmemory/mail/task/MemoryRecomputeCurrentQuotasServiceTest.java @@ -62,7 +62,9 @@ class MemoryRecomputeCurrentQuotasServiceTest implements RecomputeCurrentQuotasS resources.getCurrentQuotaCalculator(), resources.getDefaultUserQuotaRootResolver(), mailboxManager.getSessionProvider(), - mailboxManager), + mailboxManager, + resources.getQuotaManager(), + resources.getEventBus()), RECOMPUTE_JMAP_UPLOAD_CURRENT_QUOTAS_SERVICE)); } diff --git a/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/mail/task/PostgresRecomputeCurrentQuotasServiceTest.java b/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/mail/task/PostgresRecomputeCurrentQuotasServiceTest.java index ab55063756..ddd2c4ed29 100644 --- a/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/mail/task/PostgresRecomputeCurrentQuotasServiceTest.java +++ b/mailbox/postgres/src/test/java/org/apache/james/mailbox/postgres/mail/task/PostgresRecomputeCurrentQuotasServiceTest.java @@ -19,18 +19,27 @@ package org.apache.james.mailbox.postgres.mail.task; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Set; + import org.apache.commons.configuration2.BaseHierarchicalConfiguration; import org.apache.james.backends.postgres.PostgresDataDefinition; import org.apache.james.backends.postgres.PostgresExtension; import org.apache.james.backends.postgres.quota.PostgresQuotaCurrentValueDAO; import org.apache.james.backends.postgres.quota.PostgresQuotaDataDefinition; import org.apache.james.domainlist.api.DomainList; +import org.apache.james.events.EventBus; +import org.apache.james.events.RegistrationKey; import org.apache.james.mailbox.MailboxManager; import org.apache.james.mailbox.SessionProvider; import org.apache.james.mailbox.postgres.PostgresMailboxAggregateDataDefinition; import org.apache.james.mailbox.postgres.PostgresMailboxManagerProvider; import org.apache.james.mailbox.postgres.quota.PostgresCurrentQuotaManager; import org.apache.james.mailbox.quota.CurrentQuotaManager; +import org.apache.james.mailbox.quota.QuotaManager; import org.apache.james.mailbox.quota.UserQuotaRootResolver; import org.apache.james.mailbox.quota.task.RecomputeCurrentQuotasService; import org.apache.james.mailbox.quota.task.RecomputeCurrentQuotasServiceContract; @@ -47,6 +56,7 @@ import org.apache.james.user.postgres.PostgresUsersRepository; import org.apache.james.user.postgres.PostgresUsersRepositoryConfiguration; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.extension.RegisterExtension; +import org.mockito.ArgumentMatchers; import com.google.common.collect.ImmutableSet; @@ -87,12 +97,19 @@ class PostgresRecomputeCurrentQuotasServiceTest implements RecomputeCurrentQuota CurrentQuotaCalculator currentQuotaCalculator = new CurrentQuotaCalculator(mapperFactory, userQuotaRootResolver); + QuotaManager quotaManager = mock(QuotaManager.class); + when(quotaManager.getQuotasReactive(any())).thenReturn(reactor.core.publisher.Mono.empty()); + EventBus eventBus = mock(EventBus.class); + when(eventBus.dispatch(any(), ArgumentMatchers.<Set<RegistrationKey>>any())).thenReturn(reactor.core.publisher.Mono.empty()); + testee = new RecomputeCurrentQuotasService(usersRepository, ImmutableSet.of(new RecomputeMailboxCurrentQuotasService(currentQuotaManager, currentQuotaCalculator, userQuotaRootResolver, sessionProvider, - mailboxManager), + mailboxManager, + quotaManager, + eventBus), RECOMPUTE_JMAP_UPLOAD_CURRENT_QUOTAS_SERVICE)); } diff --git a/mailbox/tools/quota-recompute/src/main/java/org/apache/james/mailbox/quota/task/RecomputeMailboxCurrentQuotasService.java b/mailbox/tools/quota-recompute/src/main/java/org/apache/james/mailbox/quota/task/RecomputeMailboxCurrentQuotasService.java index dd08c9f85f..54623fc450 100644 --- a/mailbox/tools/quota-recompute/src/main/java/org/apache/james/mailbox/quota/task/RecomputeMailboxCurrentQuotasService.java +++ b/mailbox/tools/quota-recompute/src/main/java/org/apache/james/mailbox/quota/task/RecomputeMailboxCurrentQuotasService.java @@ -19,40 +19,56 @@ package org.apache.james.mailbox.quota.task; +import java.time.Instant; + import jakarta.inject.Inject; import org.apache.james.core.Username; import org.apache.james.core.quota.QuotaComponent; +import org.apache.james.events.EventBus; +import org.apache.james.events.RegistrationKey; import org.apache.james.mailbox.MailboxManager; import org.apache.james.mailbox.MailboxSession; import org.apache.james.mailbox.SessionProvider; 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.QuotaManager; import org.apache.james.mailbox.quota.UserQuotaRootResolver; +import org.apache.james.mailbox.store.event.EventFactory; import org.apache.james.mailbox.store.quota.CurrentQuotaCalculator; +import com.google.common.collect.ImmutableSet; + import reactor.core.publisher.Mono; public class RecomputeMailboxCurrentQuotasService implements RecomputeSingleComponentCurrentQuotasService { + private static final ImmutableSet<RegistrationKey> NO_REGISTRATION_KEYS = ImmutableSet.of(); + private final CurrentQuotaManager storeCurrentQuotaManager; private final CurrentQuotaCalculator currentQuotaCalculator; private final UserQuotaRootResolver userQuotaRootResolver; private final SessionProvider sessionProvider; private final MailboxManager mailboxManager; + private final QuotaManager quotaManager; + private final EventBus eventBus; @Inject public RecomputeMailboxCurrentQuotasService(CurrentQuotaManager storeCurrentQuotaManager, CurrentQuotaCalculator currentQuotaCalculator, UserQuotaRootResolver userQuotaRootResolver, SessionProvider sessionProvider, - MailboxManager mailboxManager) { + MailboxManager mailboxManager, + QuotaManager quotaManager, + EventBus eventBus) { this.storeCurrentQuotaManager = storeCurrentQuotaManager; this.currentQuotaCalculator = currentQuotaCalculator; this.userQuotaRootResolver = userQuotaRootResolver; this.sessionProvider = sessionProvider; this.mailboxManager = mailboxManager; + this.quotaManager = quotaManager; + this.eventBus = eventBus; } @@ -69,6 +85,21 @@ public class RecomputeMailboxCurrentQuotasService implements RecomputeSingleComp return currentQuotaCalculator.recalculateCurrentQuotas(quotaRoot, session) .map(recalculatedQuotas -> QuotaOperation.from(quotaRoot, recalculatedQuotas)) .flatMap(quotaOperation -> Mono.from(storeCurrentQuotaManager.setCurrentQuotas(quotaOperation))) + .then(dispatchQuotaUpdateEvent(username, quotaRoot)) .doFinally(any -> mailboxManager.endProcessingRequest(session)); } + + private Mono<Void> dispatchQuotaUpdateEvent(Username username, QuotaRoot quotaRoot) { + return Mono.from(quotaManager.getQuotasReactive(quotaRoot)) + .flatMap(quotas -> eventBus.dispatch( + EventFactory.quotaUpdated() + .randomEventId() + .user(username) + .quotaRoot(quotaRoot) + .quotaCount(quotas.getMessageQuota()) + .quotaSize(quotas.getStorageQuota()) + .instant(Instant.now()) + .build(), + NO_REGISTRATION_KEYS)); + } } diff --git a/server/container/mailbox-adapter/src/test/java/org/apache/james/adapter/mailbox/QuotaUsernameChangeTaskStepTest.java b/server/container/mailbox-adapter/src/test/java/org/apache/james/adapter/mailbox/QuotaUsernameChangeTaskStepTest.java index b952224bab..d1bf2ee9e1 100644 --- a/server/container/mailbox-adapter/src/test/java/org/apache/james/adapter/mailbox/QuotaUsernameChangeTaskStepTest.java +++ b/server/container/mailbox-adapter/src/test/java/org/apache/james/adapter/mailbox/QuotaUsernameChangeTaskStepTest.java @@ -103,7 +103,9 @@ class QuotaUsernameChangeTaskStepTest { resources.getCurrentQuotaCalculator(), quotaRootResolver, mailboxManager.getSessionProvider(), - mailboxManager); + mailboxManager, + quotaManager, + eventBus); testee = new QuotaUsernameChangeTaskStep( quotaManager, --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
