This is an automated email from the ASF dual-hosted git repository. rcordier pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit c1b9011b699d5616bd2853c493dbee837200eaa0 Author: Quan Tran <[email protected]> AuthorDate: Wed Jan 14 10:09:39 2026 +0700 JAMES-3062 Allow ignoring non-critical groups in Event dead letters healthcheck --- .../james/events/EventDeadLettersHealthCheck.java | 21 +++++++++++--- .../EventDeadLettersHealthCheckContract.java | 32 ++++++++++++++++++++++ .../CassandraEventDeadLettersHealthCheckTest.java | 4 ++- .../MemoryEventDeadLettersHealthCheckTest.java | 4 ++- .../modules/mailbox/CassandraDeadLetterModule.java | 5 ++++ .../modules/mailbox/MemoryDeadLetterModule.java | 5 ++++ .../modules/events/PostgresDeadLetterModule.java | 5 ++++ 7 files changed, 70 insertions(+), 6 deletions(-) diff --git a/event-bus/api/src/main/java/org/apache/james/events/EventDeadLettersHealthCheck.java b/event-bus/api/src/main/java/org/apache/james/events/EventDeadLettersHealthCheck.java index 324c014d00..0dd9ce755c 100644 --- a/event-bus/api/src/main/java/org/apache/james/events/EventDeadLettersHealthCheck.java +++ b/event-bus/api/src/main/java/org/apache/james/events/EventDeadLettersHealthCheck.java @@ -19,7 +19,10 @@ package org.apache.james.events; +import java.util.Set; + import jakarta.inject.Inject; +import jakarta.inject.Named; import org.apache.james.core.healthcheck.ComponentName; import org.apache.james.core.healthcheck.HealthCheck; @@ -28,13 +31,17 @@ import org.apache.james.core.healthcheck.Result; import reactor.core.publisher.Mono; public class EventDeadLettersHealthCheck implements HealthCheck { + public static final String DEAD_LETTERS_IGNORED_GROUPS = "dead-letters-ignored-groups"; private static final ComponentName COMPONENT_NAME = new ComponentName("EventDeadLettersHealthCheck"); private final EventDeadLetters eventDeadLetters; + private final Set<Group> ignoredGroups; @Inject - public EventDeadLettersHealthCheck(EventDeadLetters eventDeadLetters) { + public EventDeadLettersHealthCheck(EventDeadLetters eventDeadLetters, + @Named(DEAD_LETTERS_IGNORED_GROUPS) Set<Group> ignoredGroups) { this.eventDeadLetters = eventDeadLetters; + this.ignoredGroups = ignoredGroups; } @Override @@ -44,9 +51,11 @@ public class EventDeadLettersHealthCheck implements HealthCheck { @Override public Mono<Result> check() { - return eventDeadLetters.containEvents() - .map(containEvents -> { - if (containEvents) { + return eventDeadLetters.groupsWithFailedEvents() + .filter(group -> !ignoredGroup(group)) + .hasElements() + .map(containsCriticalEvents -> { + if (containsCriticalEvents) { return Result.degraded(COMPONENT_NAME, "EventDeadLetters contain events. This might indicate transient failure on event processing."); } @@ -54,4 +63,8 @@ public class EventDeadLettersHealthCheck implements HealthCheck { }) .onErrorResume(e -> Mono.just(Result.unhealthy(COMPONENT_NAME, "Error checking EventDeadLettersHealthCheck", e))); } + + private boolean ignoredGroup(Group group) { + return ignoredGroups.contains(group); + } } diff --git a/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java index e0cf4a80a6..447a7467b8 100644 --- a/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java +++ b/event-bus/api/src/test/java/org/apache/james/events/EventDeadLettersHealthCheckContract.java @@ -21,6 +21,8 @@ package org.apache.james.events; import static org.assertj.core.api.Assertions.assertThat; +import java.util.Set; + import org.apache.james.core.Username; import org.apache.james.core.healthcheck.ComponentName; import org.apache.james.core.healthcheck.Result; @@ -122,4 +124,34 @@ interface EventDeadLettersHealthCheckContract { assertThat(actualResult.isUnHealthy()).isTrue(); } + + @Test + default void checkShouldReturnHealthyWhenOnlyIgnoredGroupsContainEvents() { + eventDeadLetters().store(GROUP_A, EVENT_1).block(); + + EventDeadLettersHealthCheck ignoredGroupHealthCheck = new EventDeadLettersHealthCheck(eventDeadLetters(), Set.of(GROUP_A)); + + assertThat(ignoredGroupHealthCheck.check().block().isHealthy()).isTrue(); + } + + @Test + default void checkShouldReturnDegradedWhenNonIgnoredGroupContainsEvents() { + eventDeadLetters().store(GROUP_A, EVENT_1).block(); + eventDeadLetters().store(GROUP_B, EVENT_2).block(); + + EventDeadLettersHealthCheck ignoredGroupHealthCheck = new EventDeadLettersHealthCheck(eventDeadLetters(), Set.of(GROUP_A)); + + assertThat(ignoredGroupHealthCheck.check().block().isDegraded()).isTrue(); + } + + @Test + default void checkShouldReturnDegradedWhenMixingIgnoredAndNonIgnoredEvents() { + eventDeadLetters().store(GROUP_A, EVENT_1).block(); + eventDeadLetters().store(GROUP_B, EVENT_2).block(); + + EventDeadLettersHealthCheck ignoredGroupHealthCheck = new EventDeadLettersHealthCheck(eventDeadLetters(), Set.of(GROUP_A)); + + assertThat(ignoredGroupHealthCheck.check().block().isDegraded()).isTrue(); + } + } diff --git a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java index 36e972664a..bb5ac6e95f 100644 --- a/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java +++ b/event-bus/cassandra/src/test/java/org/apache/james/events/CassandraEventDeadLettersHealthCheckTest.java @@ -19,6 +19,8 @@ package org.apache.james.events; +import java.util.Set; + import org.apache.james.backends.cassandra.CassandraCluster; import org.apache.james.backends.cassandra.CassandraClusterExtension; import org.apache.james.backends.cassandra.DockerCassandra; @@ -39,7 +41,7 @@ class CassandraEventDeadLettersHealthCheckTest implements EventDeadLettersHealth EventSerializer eventSerializer = new TestEventSerializer(); eventDeadLetters = new CassandraEventDeadLetters(new CassandraEventDeadLettersDAO(cassandraCluster.getConf(), eventSerializer), new CassandraEventDeadLettersGroupDAO(cassandraCluster.getConf())); - testee = new EventDeadLettersHealthCheck(eventDeadLetters); + testee = new EventDeadLettersHealthCheck(eventDeadLetters, Set.of()); this.dockerCassandra = dockerCassandra; } diff --git a/event-bus/in-vm/src/test/java/org/apache/james/events/MemoryEventDeadLettersHealthCheckTest.java b/event-bus/in-vm/src/test/java/org/apache/james/events/MemoryEventDeadLettersHealthCheckTest.java index bc4e5c3826..07c25803e9 100644 --- a/event-bus/in-vm/src/test/java/org/apache/james/events/MemoryEventDeadLettersHealthCheckTest.java +++ b/event-bus/in-vm/src/test/java/org/apache/james/events/MemoryEventDeadLettersHealthCheckTest.java @@ -19,6 +19,8 @@ package org.apache.james.events; +import java.util.Set; + import org.apache.commons.lang3.NotImplementedException; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; @@ -26,7 +28,7 @@ import org.junit.jupiter.api.Test; public class MemoryEventDeadLettersHealthCheckTest implements EventDeadLettersHealthCheckContract { private MemoryEventDeadLetters eventDeadLetters = new MemoryEventDeadLetters(); - private EventDeadLettersHealthCheck testee = new EventDeadLettersHealthCheck(eventDeadLetters); + private EventDeadLettersHealthCheck testee = new EventDeadLettersHealthCheck(eventDeadLetters, Set.of()); @Override public EventDeadLettersHealthCheck testee() { diff --git a/server/container/guice/cassandra/src/main/java/org/apache/james/modules/mailbox/CassandraDeadLetterModule.java b/server/container/guice/cassandra/src/main/java/org/apache/james/modules/mailbox/CassandraDeadLetterModule.java index e8d1bb2d2b..be227ed457 100644 --- a/server/container/guice/cassandra/src/main/java/org/apache/james/modules/mailbox/CassandraDeadLetterModule.java +++ b/server/container/guice/cassandra/src/main/java/org/apache/james/modules/mailbox/CassandraDeadLetterModule.java @@ -19,6 +19,8 @@ package org.apache.james.modules.mailbox; +import static org.apache.james.events.EventDeadLettersHealthCheck.DEAD_LETTERS_IGNORED_GROUPS; + import org.apache.james.backends.cassandra.components.CassandraDataDefinition; import org.apache.james.core.healthcheck.HealthCheck; import org.apache.james.events.CassandraEventDeadLetters; @@ -27,10 +29,12 @@ import org.apache.james.events.CassandraEventDeadLettersDataDefinition; import org.apache.james.events.CassandraEventDeadLettersGroupDAO; import org.apache.james.events.EventDeadLetters; import org.apache.james.events.EventDeadLettersHealthCheck; +import org.apache.james.events.Group; import com.google.inject.AbstractModule; import com.google.inject.Scopes; import com.google.inject.multibindings.Multibinder; +import com.google.inject.name.Names; public class CassandraDeadLetterModule extends AbstractModule { @Override @@ -48,5 +52,6 @@ public class CassandraDeadLetterModule extends AbstractModule { Multibinder.newSetBinder(binder(), HealthCheck.class) .addBinding() .to(EventDeadLettersHealthCheck.class); + Multibinder.newSetBinder(binder(), Group.class, Names.named(DEAD_LETTERS_IGNORED_GROUPS)); } } diff --git a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/MemoryDeadLetterModule.java b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/MemoryDeadLetterModule.java index b8aca8ce73..5c079b547b 100644 --- a/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/MemoryDeadLetterModule.java +++ b/server/container/guice/mailbox/src/main/java/org/apache/james/modules/mailbox/MemoryDeadLetterModule.java @@ -19,14 +19,18 @@ package org.apache.james.modules.mailbox; +import static org.apache.james.events.EventDeadLettersHealthCheck.DEAD_LETTERS_IGNORED_GROUPS; + import org.apache.james.core.healthcheck.HealthCheck; import org.apache.james.events.EventDeadLetters; import org.apache.james.events.EventDeadLettersHealthCheck; +import org.apache.james.events.Group; import org.apache.james.events.MemoryEventDeadLetters; import com.google.inject.AbstractModule; import com.google.inject.Scopes; import com.google.inject.multibindings.Multibinder; +import com.google.inject.name.Names; public class MemoryDeadLetterModule extends AbstractModule { @Override @@ -37,5 +41,6 @@ public class MemoryDeadLetterModule extends AbstractModule { Multibinder.newSetBinder(binder(), HealthCheck.class) .addBinding() .to(EventDeadLettersHealthCheck.class); + Multibinder.newSetBinder(binder(), Group.class, Names.named(DEAD_LETTERS_IGNORED_GROUPS)); } } diff --git a/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/events/PostgresDeadLetterModule.java b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/events/PostgresDeadLetterModule.java index ab37629a79..b58dba5aa4 100644 --- a/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/events/PostgresDeadLetterModule.java +++ b/server/container/guice/postgres-common/src/main/java/org/apache/james/modules/events/PostgresDeadLetterModule.java @@ -19,16 +19,20 @@ package org.apache.james.modules.events; +import static org.apache.james.events.EventDeadLettersHealthCheck.DEAD_LETTERS_IGNORED_GROUPS; + import org.apache.james.backends.postgres.PostgresDataDefinition; import org.apache.james.core.healthcheck.HealthCheck; import org.apache.james.events.EventDeadLetters; import org.apache.james.events.EventDeadLettersHealthCheck; +import org.apache.james.events.Group; import org.apache.james.events.PostgresEventDeadLetters; import org.apache.james.events.PostgresEventDeadLettersDataDefinition; import com.google.inject.AbstractModule; import com.google.inject.Scopes; import com.google.inject.multibindings.Multibinder; +import com.google.inject.name.Names; public class PostgresDeadLetterModule extends AbstractModule { @Override @@ -43,5 +47,6 @@ public class PostgresDeadLetterModule extends AbstractModule { Multibinder.newSetBinder(binder(), HealthCheck.class) .addBinding() .to(EventDeadLettersHealthCheck.class); + Multibinder.newSetBinder(binder(), Group.class, Names.named(DEAD_LETTERS_IGNORED_GROUPS)); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
