Skip to content

Commit 43022fb

Browse files
committed
GH-970 - Prevent archiving JPA entity from being included in non-archiving setups.\n\nFixes GH-970.
1 parent 283e350 commit 43022fb

File tree

7 files changed

+146
-52
lines changed

7 files changed

+146
-52
lines changed

spring-modulith-events/spring-modulith-events-jpa/src/main/java/org/springframework/modulith/events/jpa/JpaEventPublication.java

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@
1616
package org.springframework.modulith.events.jpa;
1717

1818
import jakarta.persistence.Column;
19-
import jakarta.persistence.Entity;
2019
import jakarta.persistence.Id;
2120
import jakarta.persistence.MappedSuperclass;
22-
import jakarta.persistence.Table;
2321

2422
import java.time.Instant;
2523
import java.util.Objects;
2624
import java.util.UUID;
2725

26+
import org.springframework.modulith.events.jpa.archiving.ArchivedJpaEventPublication;
27+
import org.springframework.modulith.events.jpa.updating.DefaultJpaEventPublication;
2828
import org.springframework.modulith.events.support.CompletionMode;
2929
import org.springframework.util.Assert;
3030

@@ -37,15 +37,15 @@
3737
* @author Cora Iberkleid
3838
*/
3939
@MappedSuperclass
40-
abstract class JpaEventPublication {
40+
public abstract class JpaEventPublication {
4141

4242
final @Id @Column(length = 16) UUID id;
4343
final Instant publicationDate;
4444
final String listenerId;
4545
final String serializedEvent;
4646
final Class<?> eventType;
4747

48-
Instant completionDate;
48+
protected Instant completionDate;
4949

5050
/**
5151
* Creates a new {@link JpaEventPublication} for the given publication date, listener id, serialized event and event
@@ -56,7 +56,7 @@ abstract class JpaEventPublication {
5656
* @param serializedEvent must not be {@literal null} or empty.
5757
* @param eventType must not be {@literal null}.
5858
*/
59-
private JpaEventPublication(UUID id, Instant publicationDate, String listenerId, String serializedEvent,
59+
protected JpaEventPublication(UUID id, Instant publicationDate, String listenerId, String serializedEvent,
6060
Class<?> eventType) {
6161

6262
Assert.notNull(id, "Identifier must not be null!");
@@ -128,30 +128,4 @@ public boolean equals(Object obj) {
128128
public int hashCode() {
129129
return id.hashCode();
130130
}
131-
132-
@Entity(name = "DefaultJpaEventPublication")
133-
@Table(name = "EVENT_PUBLICATION")
134-
private static class DefaultJpaEventPublication extends JpaEventPublication {
135-
136-
private DefaultJpaEventPublication(UUID id, Instant publicationDate, String listenerId, String serializedEvent,
137-
Class<?> eventType) {
138-
super(id, publicationDate, listenerId, serializedEvent, eventType);
139-
}
140-
141-
@SuppressWarnings("unused")
142-
DefaultJpaEventPublication() {}
143-
}
144-
145-
@Entity(name = "ArchivedJpaEventPublication")
146-
@Table(name = "EVENT_PUBLICATION_ARCHIVE")
147-
private static class ArchivedJpaEventPublication extends JpaEventPublication {
148-
149-
private ArchivedJpaEventPublication(UUID id, Instant publicationDate, String listenerId, String serializedEvent,
150-
Class<?> eventType) {
151-
super(id, publicationDate, listenerId, serializedEvent, eventType);
152-
}
153-
154-
@SuppressWarnings("unused")
155-
ArchivedJpaEventPublication() {}
156-
}
157131
}

spring-modulith-events/spring-modulith-events-jpa/src/main/java/org/springframework/modulith/events/jpa/JpaEventPublicationAutoConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
2121
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
2222
import org.springframework.modulith.events.config.EventPublicationAutoConfiguration;
23+
import org.springframework.modulith.events.jpa.updating.DefaultJpaEventPublication;
2324

2425
/**
2526
* Auto-configuration for JPA based event publication. Registers this class' package as auto-configuration package, so
@@ -29,5 +30,5 @@
2930
*/
3031
@AutoConfiguration
3132
@AutoConfigureBefore({ HibernateJpaAutoConfiguration.class, EventPublicationAutoConfiguration.class })
32-
@AutoConfigurationPackage
33+
@AutoConfigurationPackage(basePackageClasses = DefaultJpaEventPublication.class)
3334
class JpaEventPublicationAutoConfiguration extends JpaEventPublicationConfiguration {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2024 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.jpa.archiving;
17+
18+
import jakarta.persistence.Entity;
19+
import jakarta.persistence.Table;
20+
21+
import java.time.Instant;
22+
import java.util.UUID;
23+
24+
import org.springframework.modulith.events.jpa.JpaEventPublication;
25+
26+
@Entity(name = "ArchivedJpaEventPublication")
27+
@Table(name = "EVENT_PUBLICATION_ARCHIVE")
28+
public class ArchivedJpaEventPublication extends JpaEventPublication {
29+
30+
public ArchivedJpaEventPublication(UUID id, Instant publicationDate, String listenerId, String serializedEvent,
31+
Class<?> eventType) {
32+
super(id, publicationDate, listenerId, serializedEvent, eventType);
33+
}
34+
35+
@SuppressWarnings("unused")
36+
ArchivedJpaEventPublication() {}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2024 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.jpa.archiving;
17+
18+
import org.springframework.boot.autoconfigure.AutoConfiguration;
19+
import org.springframework.boot.autoconfigure.AutoConfigurationPackage;
20+
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
21+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
22+
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
23+
import org.springframework.modulith.events.config.EventPublicationAutoConfiguration;
24+
import org.springframework.modulith.events.support.CompletionMode;
25+
26+
/**
27+
* Auto-configuration adding the current package as auto-configuration package for {@link ArchivedJpaEventPublication}
28+
* to be included in the JPA setup.
29+
*
30+
* @author Oliver Drotbohm
31+
* @since 1.3.1
32+
*/
33+
@ConditionalOnProperty(name = CompletionMode.PROPERTY, havingValue = "archive")
34+
@AutoConfiguration
35+
@AutoConfigureBefore({ HibernateJpaAutoConfiguration.class, EventPublicationAutoConfiguration.class })
36+
@AutoConfigurationPackage
37+
class ArchivingAutoConfiguration {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright 2024 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.jpa.updating;
17+
18+
import jakarta.persistence.Entity;
19+
import jakarta.persistence.Table;
20+
21+
import java.time.Instant;
22+
import java.util.UUID;
23+
24+
import org.springframework.modulith.events.jpa.JpaEventPublication;
25+
26+
@Entity(name = "DefaultJpaEventPublication")
27+
@Table(name = "EVENT_PUBLICATION")
28+
public class DefaultJpaEventPublication extends JpaEventPublication {
29+
30+
public DefaultJpaEventPublication(UUID id, Instant publicationDate, String listenerId, String serializedEvent,
31+
Class<?> eventType) {
32+
super(id, publicationDate, listenerId, serializedEvent, eventType);
33+
}
34+
35+
@SuppressWarnings("unused")
36+
DefaultJpaEventPublication() {}
37+
}
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
org.springframework.modulith.events.jpa.JpaEventPublicationAutoConfiguration
2+
org.springframework.modulith.events.jpa.archiving.ArchivingAutoConfiguration

spring-modulith-events/spring-modulith-events-jpa/src/test/java/org/springframework/modulith/events/jpa/JpaEventPublicationAutoConfigurationIntegrationTests.java

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,42 +16,49 @@
1616
package org.springframework.modulith.events.jpa;
1717

1818
import static org.assertj.core.api.Assertions.*;
19+
import static org.mockito.Mockito.*;
1920

2021
import example.ExampleApplication;
2122

2223
import org.junit.jupiter.api.Test;
23-
import org.springframework.beans.factory.BeanFactory;
2424
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
25-
import org.springframework.boot.test.context.SpringBootTest;
26-
import org.springframework.test.context.bean.override.mockito.MockitoBean;
25+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
2726
import org.springframework.modulith.events.core.EventSerializer;
28-
import org.springframework.test.context.ContextConfiguration;
29-
import org.springframework.test.context.TestConstructor;
30-
import org.springframework.test.context.TestConstructor.AutowireMode;
27+
import org.springframework.modulith.events.jpa.archiving.ArchivedJpaEventPublication;
28+
import org.springframework.modulith.events.jpa.updating.DefaultJpaEventPublication;
29+
import org.springframework.modulith.events.support.CompletionMode;
3130

3231
/**
3332
* @author Oliver Drotbohm
3433
*/
35-
@SpringBootTest
36-
@ContextConfiguration(classes = ExampleApplication.class)
37-
@TestConstructor(autowireMode = AutowireMode.ALL)
3834
class JpaEventPublicationAutoConfigurationIntegrationTests {
3935

40-
private final BeanFactory factory;
36+
String examplePackage = ExampleApplication.class.getPackageName();
37+
String eventPublicationPackage = DefaultJpaEventPublication.class.getPackageName();
38+
String archivingPackage = ArchivedJpaEventPublication.class.getPackageName();
4139

42-
@MockitoBean EventSerializer serializer;
40+
@Test // GH-10
41+
void registersJpaEventPublicationPackageForAutoConfiguration() {
42+
assertAutoConfigurationPackages(null, examplePackage, eventPublicationPackage);
43+
}
4344

44-
JpaEventPublicationAutoConfigurationIntegrationTests(BeanFactory factory) {
45-
this.factory = factory;
46-
}
45+
@Test // GH-964
46+
void registersArchivingJpaEventPublicationPackageForAutoConfiguration() {
47+
assertAutoConfigurationPackages("ARCHIVE", examplePackage, eventPublicationPackage, archivingPackage);
48+
}
4749

48-
@Test // GH-10
49-
void registersJpaEventPublicationPackageForAutoConfiguration() {
50+
private void assertAutoConfigurationPackages(String propertyValue, String... packages) {
51+
52+
var runner = new ApplicationContextRunner();
5053

51-
var examplePackage = ExampleApplication.class.getPackageName();
52-
var eventPublicationPackage = JpaEventPublication.class.getPackageName();
54+
if (propertyValue != null) {
55+
runner = runner.withPropertyValues(CompletionMode.PROPERTY + "=" + propertyValue);
56+
}
5357

54-
assertThat(AutoConfigurationPackages.get(factory))
55-
.containsExactlyInAnyOrder(examplePackage, eventPublicationPackage);
58+
runner.withBean(EventSerializer.class, () -> mock(EventSerializer.class))
59+
.withUserConfiguration(ExampleApplication.class)
60+
.run(context -> {
61+
assertThat(AutoConfigurationPackages.get(context)).containsExactlyInAnyOrder(packages);
62+
});
5663
}
5764
}

0 commit comments

Comments
 (0)