Skip to content

Commit 576b8f5

Browse files
committed
GH-342 - Allow disabling event externalization.
We now expose spring.modulith.events.externalization.enabled that can be set to false to disable the event externalization completely. Useful in test cases, for example.
1 parent 69fd64d commit 576b8f5

File tree

11 files changed

+235
-1
lines changed

11 files changed

+235
-1
lines changed

spring-modulith-events/spring-modulith-events-amqp/src/main/java/org/springframework/modulith/events/amqp/RabbitEventExternalizerConfiguration.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.springframework.boot.autoconfigure.AutoConfiguration;
2424
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
2525
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
26+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2627
import org.springframework.context.annotation.Bean;
2728
import org.springframework.context.expression.BeanFactoryResolver;
2829
import org.springframework.expression.spel.support.StandardEvaluationContext;
@@ -40,6 +41,9 @@
4041
@AutoConfiguration
4142
@AutoConfigureAfter(EventExternalizationAutoConfiguration.class)
4243
@ConditionalOnClass(RabbitTemplate.class)
44+
@ConditionalOnProperty(name = "spring.modulith.events.externalization.enabled",
45+
havingValue = "true",
46+
matchIfMissing = true)
4347
class RabbitEventExternalizerConfiguration {
4448

4549
private static final Logger logger = LoggerFactory.getLogger(RabbitEventExternalizerConfiguration.class);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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.amqp;
17+
18+
import static org.assertj.core.api.Assertions.*;
19+
import static org.mockito.Mockito.*;
20+
21+
import org.junit.jupiter.api.Test;
22+
import org.springframework.amqp.rabbit.core.RabbitMessageOperations;
23+
import org.springframework.boot.autoconfigure.AutoConfigurations;
24+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
25+
import org.springframework.modulith.events.EventExternalizationConfiguration;
26+
import org.springframework.modulith.events.support.DelegatingEventExternalizer;
27+
28+
/**
29+
* Integration tests for {@link RabbitEventExternalizerConfiguration}.
30+
*
31+
* @author Oliver Drotbohm
32+
* @since 1.1
33+
*/
34+
class RabbitEventExternalizerConfigurationIntegrationTests {
35+
36+
@Test // GH-342
37+
void registersExternalizerByDefault() {
38+
39+
basicSetup()
40+
.run(ctxt -> {
41+
assertThat(ctxt).hasSingleBean(DelegatingEventExternalizer.class);
42+
});
43+
}
44+
45+
@Test // GH-342
46+
void disablesExternalizationIfConfigured() {
47+
48+
basicSetup()
49+
.withPropertyValues("spring.modulith.events.externalization.enabled=false")
50+
.run(ctxt -> {
51+
assertThat(ctxt).doesNotHaveBean(DelegatingEventExternalizer.class);
52+
});
53+
}
54+
55+
private ApplicationContextRunner basicSetup() {
56+
57+
return new ApplicationContextRunner()
58+
.withConfiguration(
59+
AutoConfigurations.of(RabbitEventExternalizerConfiguration.class))
60+
.withBean(EventExternalizationConfiguration.class, () -> EventExternalizationConfiguration.disabled())
61+
.withBean(RabbitMessageOperations.class, () -> mock(RabbitMessageOperations.class));
62+
}
63+
}

spring-modulith-events/spring-modulith-events-api/src/main/java/org/springframework/modulith/events/EventExternalizationConfiguration.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,15 @@ public static Selector externalizing() {
7777
return new Selector();
7878
}
7979

80+
/**
81+
* Disables event externalization by not matching any events at all.
82+
*
83+
* @return will never be {@literal null}.
84+
*/
85+
public static EventExternalizationConfiguration disabled() {
86+
return externalizing().select(__ -> false).build();
87+
}
88+
8089
/**
8190
* A {@link Predicate} to select all events annotated as to be externalized. The currently supported annotations are:
8291
* <ul>

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,14 @@
2323
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
2424
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
2525
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
26+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2627
import org.springframework.context.ApplicationListener;
2728
import org.springframework.context.annotation.Bean;
2829
import org.springframework.context.annotation.Role;
2930
import org.springframework.context.event.EventListenerFactory;
3031
import org.springframework.core.Ordered;
3132
import org.springframework.modulith.events.EventExternalizationConfiguration;
3233
import org.springframework.modulith.events.core.ConditionalEventListener;
33-
import org.springframework.modulith.events.support.PersistentApplicationEventMulticaster;
3434
import org.springframework.transaction.event.TransactionalApplicationListenerMethodAdapter;
3535
import org.springframework.transaction.event.TransactionalEventListenerFactory;
3636

@@ -40,6 +40,9 @@
4040
* @author Oliver Drotbohm
4141
* @since 1.1
4242
*/
43+
@ConditionalOnProperty(name = "spring.modulith.events.externalization.enabled",
44+
havingValue = "true",
45+
matchIfMissing = true)
4346
@AutoConfiguration
4447
@AutoConfigureAfter(EventPublicationConfiguration.class)
4548
public class EventExternalizationAutoConfiguration {

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
@@ -11,6 +11,12 @@
1111
"type": "java.lang.boolean",
1212
"description": "Whether to republish outstanding event publications on restarts of the application.",
1313
"defaultValue": "false"
14+
},
15+
{
16+
"name": "spring.modulith.events.externalization.enabled",
17+
"type": "java.lang.boolean",
18+
"description": "Whether to enable event externalization.",
19+
"defaultValue": "true"
1420
}
1521
]
1622
}

spring-modulith-events/spring-modulith-events-jms/src/main/java/org/springframework/modulith/events/jms/JmsEventExternalizerConfiguration.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.springframework.boot.autoconfigure.AutoConfiguration;
2121
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
2222
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
23+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2324
import org.springframework.context.annotation.Bean;
2425
import org.springframework.jms.core.JmsOperations;
2526
import org.springframework.modulith.events.EventExternalizationConfiguration;
@@ -36,6 +37,9 @@
3637
@AutoConfiguration
3738
@AutoConfigureAfter(EventExternalizationAutoConfiguration.class)
3839
@ConditionalOnClass(JmsOperations.class)
40+
@ConditionalOnProperty(name = "spring.modulith.events.externalization.enabled",
41+
havingValue = "true",
42+
matchIfMissing = true)
3943
class JmsEventExternalizerConfiguration {
4044

4145
private static final Logger logger = LoggerFactory.getLogger(JmsEventExternalizerConfiguration.class);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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.jms;
17+
18+
import static org.assertj.core.api.Assertions.*;
19+
import static org.mockito.Mockito.*;
20+
21+
import org.junit.jupiter.api.Test;
22+
import org.springframework.boot.autoconfigure.AutoConfigurations;
23+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
24+
import org.springframework.jms.core.JmsOperations;
25+
import org.springframework.modulith.events.EventExternalizationConfiguration;
26+
import org.springframework.modulith.events.core.EventSerializer;
27+
import org.springframework.modulith.events.support.DelegatingEventExternalizer;
28+
29+
/**
30+
* Integration tests for {@link JmsEventExternalizerConfiguration}.
31+
*
32+
* @author Oliver Drotbohm
33+
* @since 1.1
34+
*/
35+
class JmsEventExternalizerConfigurationIntegrationTests {
36+
37+
@Test // GH-342
38+
void registersExternalizerByDefault() {
39+
40+
basicSetup()
41+
.run(ctxt -> {
42+
assertThat(ctxt).hasSingleBean(DelegatingEventExternalizer.class);
43+
});
44+
}
45+
46+
@Test // GH-342
47+
void disablesExternalizationIfConfigured() {
48+
49+
basicSetup()
50+
.withPropertyValues("spring.modulith.events.externalization.enabled=false")
51+
.run(ctxt -> {
52+
assertThat(ctxt).doesNotHaveBean(DelegatingEventExternalizer.class);
53+
});
54+
}
55+
56+
private ApplicationContextRunner basicSetup() {
57+
58+
return new ApplicationContextRunner()
59+
.withConfiguration(
60+
AutoConfigurations.of(JmsEventExternalizerConfiguration.class))
61+
.withBean(EventExternalizationConfiguration.class, () -> EventExternalizationConfiguration.disabled())
62+
.withBean(EventSerializer.class, () -> mock(EventSerializer.class))
63+
.withBean(JmsOperations.class, () -> mock(JmsOperations.class));
64+
}
65+
}

spring-modulith-events/spring-modulith-events-kafka/pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@
4040
<optional>true</optional>
4141
</dependency>
4242

43+
<!-- Testing -->
44+
45+
<dependency>
46+
<groupId>org.springframework.boot</groupId>
47+
<artifactId>spring-boot-starter-test</artifactId>
48+
<scope>test</scope>
49+
</dependency>
50+
4351
</dependencies>
4452

4553
</project>

spring-modulith-events/spring-modulith-events-kafka/src/main/java/org/springframework/modulith/events/kafka/KafkaEventExternalizerConfiguration.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.springframework.boot.autoconfigure.AutoConfiguration;
2222
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
2323
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
24+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
2425
import org.springframework.context.annotation.Bean;
2526
import org.springframework.context.expression.BeanFactoryResolver;
2627
import org.springframework.expression.spel.support.StandardEvaluationContext;
@@ -37,9 +38,13 @@
3738
* @author Oliver Drotbohm
3839
* @since 1.1
3940
*/
41+
4042
@AutoConfiguration
4143
@AutoConfigureAfter(EventExternalizationAutoConfiguration.class)
4244
@ConditionalOnClass(KafkaTemplate.class)
45+
@ConditionalOnProperty(name = "spring.modulith.events.externalization.enabled",
46+
havingValue = "true",
47+
matchIfMissing = true)
4348
class KafkaEventExternalizerConfiguration {
4449

4550
private static final Logger logger = LoggerFactory.getLogger(KafkaEventExternalizerConfiguration.class);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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.kafka;
17+
18+
import static org.assertj.core.api.Assertions.*;
19+
import static org.mockito.Mockito.*;
20+
21+
import org.junit.jupiter.api.Test;
22+
import org.springframework.boot.autoconfigure.AutoConfigurations;
23+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
24+
import org.springframework.kafka.core.KafkaOperations;
25+
import org.springframework.modulith.events.EventExternalizationConfiguration;
26+
import org.springframework.modulith.events.support.DelegatingEventExternalizer;
27+
28+
/**
29+
* Integration tests for {@link KafkaEventExternalizerConfiguration}.
30+
*
31+
* @author Oliver Drotbohm
32+
* @since 1.1
33+
*/
34+
class KafkaEventExternalizerConfigurationIntegrationTests {
35+
36+
@Test // GH-342
37+
void registersExternalizerByDefault() {
38+
39+
basicSetup()
40+
.run(ctxt -> {
41+
assertThat(ctxt).hasSingleBean(DelegatingEventExternalizer.class);
42+
});
43+
}
44+
45+
@Test // GH-342
46+
void disablesExternalizationIfConfigured() {
47+
48+
basicSetup()
49+
.withPropertyValues("spring.modulith.events.externalization.enabled=false")
50+
.run(ctxt -> {
51+
assertThat(ctxt).doesNotHaveBean(DelegatingEventExternalizer.class);
52+
});
53+
}
54+
55+
private ApplicationContextRunner basicSetup() {
56+
57+
return new ApplicationContextRunner()
58+
.withConfiguration(
59+
AutoConfigurations.of(KafkaEventExternalizerConfiguration.class))
60+
.withBean(EventExternalizationConfiguration.class, () -> EventExternalizationConfiguration.disabled())
61+
.withBean(KafkaOperations.class, () -> mock(KafkaOperations.class));
62+
}
63+
}

0 commit comments

Comments
 (0)