Skip to content

Commit 2270ff3

Browse files
committed
GH-240 - Republication of outstanding events can now be disabled.
Via the spring.modulith.republish-outstanding-events-on-restart (boolean) property.
1 parent ff32c60 commit 2270ff3

File tree

4 files changed

+86
-3
lines changed

4 files changed

+86
-3
lines changed

spring-modulith-events/spring-modulith-events-core/src/main/java/org/springframework/modulith/events/config/EventPublicationConfiguration.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,10 @@ EventPublicationRegistry eventPublicationRegistry(EventPublicationRepository rep
6262
@Bean
6363
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
6464
static PersistentApplicationEventMulticaster applicationEventMulticaster(
65-
ObjectFactory<EventPublicationRegistry> eventPublicationRegistry) {
66-
return new PersistentApplicationEventMulticaster(() -> eventPublicationRegistry.getObject());
65+
ObjectFactory<EventPublicationRegistry> eventPublicationRegistry, ObjectFactory<Environment> environment) {
66+
67+
return new PersistentApplicationEventMulticaster(() -> eventPublicationRegistry.getObject(),
68+
() -> environment.getObject());
6769
}
6870

6971
@Bean

spring-modulith-events/spring-modulith-events-core/src/main/java/org/springframework/modulith/events/support/PersistentApplicationEventMulticaster.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import org.springframework.context.event.ApplicationListenerMethodAdapter;
3434
import org.springframework.core.ResolvableType;
3535
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
36+
import org.springframework.core.env.Environment;
3637
import org.springframework.lang.NonNull;
3738
import org.springframework.modulith.events.EventPublication;
3839
import org.springframework.modulith.events.EventPublicationRegistry;
@@ -60,8 +61,10 @@ public class PersistentApplicationEventMulticaster extends AbstractApplicationEv
6061
private static final Logger LOGGER = LoggerFactory.getLogger(PersistentApplicationEventMulticaster.class);
6162
private static final Field DECLARED_EVENT_TYPES_FIELD = ReflectionUtils
6263
.findField(ApplicationListenerMethodAdapter.class, "declaredEventTypes");
64+
static final String REPUBLISH_ON_RESTART = "spring.modulith.republish-outstanding-events-on-restart";
6365

6466
private final @NonNull Supplier<EventPublicationRegistry> registry;
67+
private final @NonNull Supplier<Environment> environment;
6568

6669
static {
6770
ReflectionUtils.makeAccessible(DECLARED_EVENT_TYPES_FIELD);
@@ -71,12 +74,16 @@ public class PersistentApplicationEventMulticaster extends AbstractApplicationEv
7174
* Creates a new {@link PersistentApplicationEventMulticaster} for the given {@link EventPublicationRegistry}.
7275
*
7376
* @param registry must not be {@literal null}.
77+
* @param environment must not be {@literal null}.
7478
*/
75-
public PersistentApplicationEventMulticaster(Supplier<EventPublicationRegistry> registry) {
79+
public PersistentApplicationEventMulticaster(Supplier<EventPublicationRegistry> registry,
80+
Supplier<Environment> environment) {
7681

7782
Assert.notNull(registry, "EventPublicationRegistry must not be null!");
83+
Assert.notNull(environment, "Environment must not be null!");
7884

7985
this.registry = registry;
86+
this.environment = environment;
8087
}
8188

8289
/*
@@ -118,6 +125,10 @@ public void multicastEvent(ApplicationEvent event, ResolvableType eventType) {
118125
@Override
119126
public void afterSingletonsInstantiated() {
120127

128+
if (Boolean.FALSE.equals(environment.get().getProperty(REPUBLISH_ON_RESTART, Boolean.class))) {
129+
return;
130+
}
131+
121132
LOGGER.debug("Looking up previously pending event publications…");
122133

123134
var publications = registry.get().findIncompletePublications();

spring-modulith-events/spring-modulith-events-core/src/main/resources/META-INF/spring-configuration-metadata.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
"type": "java.lang.boolean",
66
"description": "Whether to configure defaults for the async processing termination, namely to wait for task completion for 2 seconds. See TaskExecutionProperties for details.",
77
"defaultValue": "true"
8+
},
9+
{
10+
"name": "spring.modulith.republish-outstanding-events-on-restart",
11+
"type": "java.lang.boolean",
12+
"description": "Whether to republish outstanding event publications on restarts of the application.",
13+
"defaultValue": "true"
814
}
915
]
1016
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.modulith.events.support;
17+
18+
import static org.mockito.Mockito.*;
19+
20+
import java.util.Map;
21+
22+
import org.junit.jupiter.api.BeforeEach;
23+
import org.junit.jupiter.api.Test;
24+
import org.springframework.core.env.MapPropertySource;
25+
import org.springframework.core.env.StandardEnvironment;
26+
import org.springframework.modulith.events.EventPublicationRegistry;
27+
28+
/**
29+
* Unit tests for {@link PersistentApplicationEventMulticaster}.
30+
*
31+
* @author Oliver Drotbohm
32+
*/
33+
class PersistentApplicationEventMulticasterUnitTests {
34+
35+
PersistentApplicationEventMulticaster multicaster;
36+
37+
StandardEnvironment environment = new StandardEnvironment();
38+
EventPublicationRegistry registry = mock(EventPublicationRegistry.class);
39+
40+
@BeforeEach
41+
void setUp() {
42+
this.multicaster = new PersistentApplicationEventMulticaster(() -> registry, () -> environment);
43+
}
44+
45+
@Test // GH-240
46+
void doesNotRepublishEventsOnRestartIfExplicitlyDisabled() {
47+
48+
var source = new MapPropertySource("test",
49+
Map.of(PersistentApplicationEventMulticaster.REPUBLISH_ON_RESTART, "false"));
50+
environment.getPropertySources().addFirst(source);
51+
52+
multicaster.afterSingletonsInstantiated();
53+
54+
verify(registry, never()).findIncompletePublications();
55+
}
56+
57+
@Test // GH-240
58+
void triggersRepublicationIfExplicitlyEnabled() {
59+
60+
multicaster.afterSingletonsInstantiated();
61+
62+
verify(registry).findIncompletePublications();
63+
}
64+
}

0 commit comments

Comments
 (0)