This is an automated email from the ASF dual-hosted git repository.
Arsnael pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
The following commit(s) were added to refs/heads/master by this push:
new 1e7039687d [FIX] Quota recomputation should trigger Quotaupdate event
(#3054)
1e7039687d is described below
commit 1e7039687dd3c03a326658244189eb71ed7c782c
Author: Benoit TELLIER <[email protected]>
AuthorDate: Mon Jun 1 04:10:23 2026 +0200
[FIX] Quota recomputation should trigger Quotaupdate event (#3054)
---
...CassandraRecomputeCurrentQuotasServiceTest.java | 17 ++++++++++-
.../task/JPARecomputeCurrentQuotasServiceTest.java | 18 +++++++++++-
.../MemoryRecomputeCurrentQuotasServiceTest.java | 4 ++-
.../PostgresRecomputeCurrentQuotasServiceTest.java | 19 ++++++++++++-
.../task/RecomputeMailboxCurrentQuotasService.java | 33 +++++++++++++++++++++-
5 files changed, 86 insertions(+), 5 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));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]