diff --git a/spring-modulith-events/spring-modulith-events-amqp/src/main/java/org/springframework/modulith/events/amqp/RabbitEventExternalizerConfiguration.java b/spring-modulith-events/spring-modulith-events-amqp/src/main/java/org/springframework/modulith/events/amqp/RabbitEventExternalizerConfiguration.java
index 5106b924..541b6dca 100644
--- a/spring-modulith-events/spring-modulith-events-amqp/src/main/java/org/springframework/modulith/events/amqp/RabbitEventExternalizerConfiguration.java
+++ b/spring-modulith-events/spring-modulith-events-amqp/src/main/java/org/springframework/modulith/events/amqp/RabbitEventExternalizerConfiguration.java
@@ -23,6 +23,7 @@
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.expression.spel.support.StandardEvaluationContext;
@@ -40,6 +41,9 @@
@AutoConfiguration
@AutoConfigureAfter(EventExternalizationAutoConfiguration.class)
@ConditionalOnClass(RabbitTemplate.class)
+@ConditionalOnProperty(name = "spring.modulith.events.externalization.enabled",
+ havingValue = "true",
+ matchIfMissing = true)
class RabbitEventExternalizerConfiguration {
private static final Logger logger = LoggerFactory.getLogger(RabbitEventExternalizerConfiguration.class);
diff --git a/spring-modulith-events/spring-modulith-events-amqp/src/test/java/org/springframework/modulith/events/amqp/RabbitEventExternalizerConfigurationIntegrationTests.java b/spring-modulith-events/spring-modulith-events-amqp/src/test/java/org/springframework/modulith/events/amqp/RabbitEventExternalizerConfigurationIntegrationTests.java
new file mode 100644
index 00000000..2570e6b3
--- /dev/null
+++ b/spring-modulith-events/spring-modulith-events-amqp/src/test/java/org/springframework/modulith/events/amqp/RabbitEventExternalizerConfigurationIntegrationTests.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.modulith.events.amqp;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.amqp.rabbit.core.RabbitMessageOperations;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.modulith.events.EventExternalizationConfiguration;
+import org.springframework.modulith.events.support.DelegatingEventExternalizer;
+
+/**
+ * Integration tests for {@link RabbitEventExternalizerConfiguration}.
+ *
+ * @author Oliver Drotbohm
+ * @since 1.1
+ */
+class RabbitEventExternalizerConfigurationIntegrationTests {
+
+ @Test // GH-342
+ void registersExternalizerByDefault() {
+
+ basicSetup()
+ .run(ctxt -> {
+ assertThat(ctxt).hasSingleBean(DelegatingEventExternalizer.class);
+ });
+ }
+
+ @Test // GH-342
+ void disablesExternalizationIfConfigured() {
+
+ basicSetup()
+ .withPropertyValues("spring.modulith.events.externalization.enabled=false")
+ .run(ctxt -> {
+ assertThat(ctxt).doesNotHaveBean(DelegatingEventExternalizer.class);
+ });
+ }
+
+ private ApplicationContextRunner basicSetup() {
+
+ return new ApplicationContextRunner()
+ .withConfiguration(
+ AutoConfigurations.of(RabbitEventExternalizerConfiguration.class))
+ .withBean(EventExternalizationConfiguration.class, () -> EventExternalizationConfiguration.disabled())
+ .withBean(RabbitMessageOperations.class, () -> mock(RabbitMessageOperations.class));
+ }
+}
diff --git a/spring-modulith-events/spring-modulith-events-api/src/main/java/org/springframework/modulith/events/EventExternalizationConfiguration.java b/spring-modulith-events/spring-modulith-events-api/src/main/java/org/springframework/modulith/events/EventExternalizationConfiguration.java
index 85287038..aaab7b72 100644
--- a/spring-modulith-events/spring-modulith-events-api/src/main/java/org/springframework/modulith/events/EventExternalizationConfiguration.java
+++ b/spring-modulith-events/spring-modulith-events-api/src/main/java/org/springframework/modulith/events/EventExternalizationConfiguration.java
@@ -77,6 +77,15 @@ public static Selector externalizing() {
return new Selector();
}
+ /**
+ * Disables event externalization by not matching any events at all.
+ *
+ * @return will never be {@literal null}.
+ */
+ public static EventExternalizationConfiguration disabled() {
+ return externalizing().select(__ -> false).build();
+ }
+
/**
* A {@link Predicate} to select all events annotated as to be externalized. The currently supported annotations are:
*
diff --git a/spring-modulith-events/spring-modulith-events-core/src/main/java/org/springframework/modulith/events/config/EventExternalizationAutoConfiguration.java b/spring-modulith-events/spring-modulith-events-core/src/main/java/org/springframework/modulith/events/config/EventExternalizationAutoConfiguration.java
index ebd5872c..f9d61467 100644
--- a/spring-modulith-events/spring-modulith-events-core/src/main/java/org/springframework/modulith/events/config/EventExternalizationAutoConfiguration.java
+++ b/spring-modulith-events/spring-modulith-events-core/src/main/java/org/springframework/modulith/events/config/EventExternalizationAutoConfiguration.java
@@ -23,6 +23,7 @@
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Role;
@@ -30,7 +31,6 @@
import org.springframework.core.Ordered;
import org.springframework.modulith.events.EventExternalizationConfiguration;
import org.springframework.modulith.events.core.ConditionalEventListener;
-import org.springframework.modulith.events.support.PersistentApplicationEventMulticaster;
import org.springframework.transaction.event.TransactionalApplicationListenerMethodAdapter;
import org.springframework.transaction.event.TransactionalEventListenerFactory;
@@ -40,6 +40,9 @@
* @author Oliver Drotbohm
* @since 1.1
*/
+@ConditionalOnProperty(name = "spring.modulith.events.externalization.enabled",
+ havingValue = "true",
+ matchIfMissing = true)
@AutoConfiguration
@AutoConfigureAfter(EventPublicationConfiguration.class)
public class EventExternalizationAutoConfiguration {
diff --git a/spring-modulith-events/spring-modulith-events-core/src/main/resources/META-INF/spring-configuration-metadata.json b/spring-modulith-events/spring-modulith-events-core/src/main/resources/META-INF/spring-configuration-metadata.json
index 392fa49d..446c0d78 100644
--- a/spring-modulith-events/spring-modulith-events-core/src/main/resources/META-INF/spring-configuration-metadata.json
+++ b/spring-modulith-events/spring-modulith-events-core/src/main/resources/META-INF/spring-configuration-metadata.json
@@ -11,6 +11,12 @@
"type": "java.lang.boolean",
"description": "Whether to republish outstanding event publications on restarts of the application.",
"defaultValue": "false"
+ },
+ {
+ "name": "spring.modulith.events.externalization.enabled",
+ "type": "java.lang.boolean",
+ "description": "Whether to enable event externalization.",
+ "defaultValue": "true"
}
]
}
diff --git a/spring-modulith-events/spring-modulith-events-jms/src/main/java/org/springframework/modulith/events/jms/JmsEventExternalizerConfiguration.java b/spring-modulith-events/spring-modulith-events-jms/src/main/java/org/springframework/modulith/events/jms/JmsEventExternalizerConfiguration.java
index 234b629b..3af0631b 100644
--- a/spring-modulith-events/spring-modulith-events-jms/src/main/java/org/springframework/modulith/events/jms/JmsEventExternalizerConfiguration.java
+++ b/spring-modulith-events/spring-modulith-events-jms/src/main/java/org/springframework/modulith/events/jms/JmsEventExternalizerConfiguration.java
@@ -20,6 +20,7 @@
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.jms.core.JmsOperations;
import org.springframework.modulith.events.EventExternalizationConfiguration;
@@ -36,6 +37,9 @@
@AutoConfiguration
@AutoConfigureAfter(EventExternalizationAutoConfiguration.class)
@ConditionalOnClass(JmsOperations.class)
+@ConditionalOnProperty(name = "spring.modulith.events.externalization.enabled",
+ havingValue = "true",
+ matchIfMissing = true)
class JmsEventExternalizerConfiguration {
private static final Logger logger = LoggerFactory.getLogger(JmsEventExternalizerConfiguration.class);
diff --git a/spring-modulith-events/spring-modulith-events-jms/src/test/java/org/springframework/modulith/events/jms/JmsEventExternalizerConfigurationIntegrationTests.java b/spring-modulith-events/spring-modulith-events-jms/src/test/java/org/springframework/modulith/events/jms/JmsEventExternalizerConfigurationIntegrationTests.java
new file mode 100644
index 00000000..1ffdcdcf
--- /dev/null
+++ b/spring-modulith-events/spring-modulith-events-jms/src/test/java/org/springframework/modulith/events/jms/JmsEventExternalizerConfigurationIntegrationTests.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.modulith.events.jms;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.jms.core.JmsOperations;
+import org.springframework.modulith.events.EventExternalizationConfiguration;
+import org.springframework.modulith.events.core.EventSerializer;
+import org.springframework.modulith.events.support.DelegatingEventExternalizer;
+
+/**
+ * Integration tests for {@link JmsEventExternalizerConfiguration}.
+ *
+ * @author Oliver Drotbohm
+ * @since 1.1
+ */
+class JmsEventExternalizerConfigurationIntegrationTests {
+
+ @Test // GH-342
+ void registersExternalizerByDefault() {
+
+ basicSetup()
+ .run(ctxt -> {
+ assertThat(ctxt).hasSingleBean(DelegatingEventExternalizer.class);
+ });
+ }
+
+ @Test // GH-342
+ void disablesExternalizationIfConfigured() {
+
+ basicSetup()
+ .withPropertyValues("spring.modulith.events.externalization.enabled=false")
+ .run(ctxt -> {
+ assertThat(ctxt).doesNotHaveBean(DelegatingEventExternalizer.class);
+ });
+ }
+
+ private ApplicationContextRunner basicSetup() {
+
+ return new ApplicationContextRunner()
+ .withConfiguration(
+ AutoConfigurations.of(JmsEventExternalizerConfiguration.class))
+ .withBean(EventExternalizationConfiguration.class, () -> EventExternalizationConfiguration.disabled())
+ .withBean(EventSerializer.class, () -> mock(EventSerializer.class))
+ .withBean(JmsOperations.class, () -> mock(JmsOperations.class));
+ }
+}
diff --git a/spring-modulith-events/spring-modulith-events-kafka/pom.xml b/spring-modulith-events/spring-modulith-events-kafka/pom.xml
index f2f0fb63..5cc709cf 100644
--- a/spring-modulith-events/spring-modulith-events-kafka/pom.xml
+++ b/spring-modulith-events/spring-modulith-events-kafka/pom.xml
@@ -40,6 +40,14 @@
true
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
diff --git a/spring-modulith-events/spring-modulith-events-kafka/src/main/java/org/springframework/modulith/events/kafka/KafkaEventExternalizerConfiguration.java b/spring-modulith-events/spring-modulith-events-kafka/src/main/java/org/springframework/modulith/events/kafka/KafkaEventExternalizerConfiguration.java
index 5bb00688..e06fc791 100644
--- a/spring-modulith-events/spring-modulith-events-kafka/src/main/java/org/springframework/modulith/events/kafka/KafkaEventExternalizerConfiguration.java
+++ b/spring-modulith-events/spring-modulith-events-kafka/src/main/java/org/springframework/modulith/events/kafka/KafkaEventExternalizerConfiguration.java
@@ -21,6 +21,7 @@
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.expression.BeanFactoryResolver;
import org.springframework.expression.spel.support.StandardEvaluationContext;
@@ -37,9 +38,13 @@
* @author Oliver Drotbohm
* @since 1.1
*/
+
@AutoConfiguration
@AutoConfigureAfter(EventExternalizationAutoConfiguration.class)
@ConditionalOnClass(KafkaTemplate.class)
+@ConditionalOnProperty(name = "spring.modulith.events.externalization.enabled",
+ havingValue = "true",
+ matchIfMissing = true)
class KafkaEventExternalizerConfiguration {
private static final Logger logger = LoggerFactory.getLogger(KafkaEventExternalizerConfiguration.class);
diff --git a/spring-modulith-events/spring-modulith-events-kafka/src/test/java/org/springframework/modulith/events/kafka/KafkaEventExternalizerConfigurationIntegrationTests.java b/spring-modulith-events/spring-modulith-events-kafka/src/test/java/org/springframework/modulith/events/kafka/KafkaEventExternalizerConfigurationIntegrationTests.java
new file mode 100644
index 00000000..891eaa0f
--- /dev/null
+++ b/spring-modulith-events/spring-modulith-events-kafka/src/test/java/org/springframework/modulith/events/kafka/KafkaEventExternalizerConfigurationIntegrationTests.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2023 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.modulith.events.kafka;
+
+import static org.assertj.core.api.Assertions.*;
+import static org.mockito.Mockito.*;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.kafka.core.KafkaOperations;
+import org.springframework.modulith.events.EventExternalizationConfiguration;
+import org.springframework.modulith.events.support.DelegatingEventExternalizer;
+
+/**
+ * Integration tests for {@link KafkaEventExternalizerConfiguration}.
+ *
+ * @author Oliver Drotbohm
+ * @since 1.1
+ */
+class KafkaEventExternalizerConfigurationIntegrationTests {
+
+ @Test // GH-342
+ void registersExternalizerByDefault() {
+
+ basicSetup()
+ .run(ctxt -> {
+ assertThat(ctxt).hasSingleBean(DelegatingEventExternalizer.class);
+ });
+ }
+
+ @Test // GH-342
+ void disablesExternalizationIfConfigured() {
+
+ basicSetup()
+ .withPropertyValues("spring.modulith.events.externalization.enabled=false")
+ .run(ctxt -> {
+ assertThat(ctxt).doesNotHaveBean(DelegatingEventExternalizer.class);
+ });
+ }
+
+ private ApplicationContextRunner basicSetup() {
+
+ return new ApplicationContextRunner()
+ .withConfiguration(
+ AutoConfigurations.of(KafkaEventExternalizerConfiguration.class))
+ .withBean(EventExternalizationConfiguration.class, () -> EventExternalizationConfiguration.disabled())
+ .withBean(KafkaOperations.class, () -> mock(KafkaOperations.class));
+ }
+}
diff --git a/src/docs/antora/modules/ROOT/pages/appendix.adoc b/src/docs/antora/modules/ROOT/pages/appendix.adoc
index eddca2ae..af9f776f 100644
--- a/src/docs/antora/modules/ROOT/pages/appendix.adoc
+++ b/src/docs/antora/modules/ROOT/pages/appendix.adoc
@@ -13,6 +13,10 @@
|`true`
|Whether to configure defaults for the async processing termination, namely to wait for task completion for 2 seconds. See `TaskExecutionProperties` for details.
+|`spring.modulith.events.externalization.enabled`
+|`true`
+|Whether to enable event externalization.
+
|`spring.modulith.events.jdbc.schema-initialization.enabled`
|`false`
|Whether to initialize the JDBC event publication schema.