Skip to content

Commit 971a143

Browse files
committed
GH-294 - Introduce user API to deal with completed and incomplete event publications.
Introduce a new spring-modulith-events-api artifact to contain types that are supposed to be used by application code to deal with event publications. `EventPublication` was moved into that artifact and got everything non infrastructure related extracted from it's previous incarnation. That in turn has been renamed to `TargetEventPublication`. `CompletedEventPublications` exposes API to allow purging completed publications either by a given predicate or age (in `Duration`). The interface is implemented by `DefaultEventPublicationRegistry` and thus subject for dependency injection into user code. It primarily delegates to the corresponding methods on `EventPublicationRepository` adapting the given `Duration`s to the `Clock` instance already held internally. `IncompleteEventPublications` allows triggering the re-submission of incomplete publications by the same criteria as `CEP`. The interface is implemented by `PersistentApplicationEventMulticaster` and this subject for dependency injection into user code. `EventPublicationRepository` now also allows publications to be deleted by identifiers. The existing implementations have been adapted and batch the requests for every 100 identifiers to prevent a list too large to run into limitations of the underlying data store. Polished transactional metadata declaration in JPA- and MongoDB-based repository implementations. Tightened nullability expressions here and there.
1 parent 1fe681b commit 971a143

File tree

29 files changed

+871
-272
lines changed

29 files changed

+871
-272
lines changed

spring-modulith-events/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<name>Spring Modulith - Events</name>
1515

1616
<modules>
17+
<module>spring-modulith-events-api</module>
1718
<module>spring-modulith-events-core</module>
1819
<module>spring-modulith-events-jpa</module>
1920
<module>spring-modulith-events-jdbc</module>
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0"
2+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<parent>
8+
<groupId>org.springframework.modulith</groupId>
9+
<artifactId>spring-modulith-events</artifactId>
10+
<version>1.1.0-SNAPSHOT</version>
11+
</parent>
12+
13+
<name>Spring Modulith - Events - API</name>
14+
<artifactId>spring-modulith-events-api</artifactId>
15+
16+
<properties>
17+
<module.name>org.springframework.modulith.events.api</module.name>
18+
</properties>
19+
20+
<dependencies>
21+
22+
<dependency>
23+
<groupId>org.springframework.modulith</groupId>
24+
<artifactId>spring-modulith-api</artifactId>
25+
<version>${project.version}</version>
26+
</dependency>
27+
28+
<dependency>
29+
<groupId>org.springframework</groupId>
30+
<artifactId>spring-context</artifactId>
31+
</dependency>
32+
33+
</dependencies>
34+
35+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
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;
17+
18+
import java.time.Duration;
19+
import java.util.Collection;
20+
import java.util.function.Predicate;
21+
22+
/**
23+
* All {@link EventPublication}s that have already been completed.
24+
*
25+
* @author Oliver Drotbohm
26+
* @since 1.1
27+
*/
28+
public interface CompletedEventPublications {
29+
30+
/**
31+
* Returns all {@link EventPublication}s that have already been completed.
32+
*
33+
* @return will never be {@literal null}.
34+
*/
35+
Collection<? extends EventPublication> findAll();
36+
37+
/**
38+
* Deletes all {@link EventPublication}s matching the given {@link Predicate}. Note that implementations will iterate
39+
* all completed {@link EventPublication}s and apply the predicate in memory.
40+
*
41+
* @param filter must not be {@literal null}.
42+
*/
43+
void deletePublications(Predicate<EventPublication> filter);
44+
45+
/**
46+
* Deletes all {@link EventPublication}s whose completion date is older than the given {@link Duration}.
47+
*
48+
* @param duration must not be {@literal null}.
49+
*/
50+
void deletePublicationsOlderThan(Duration duration);
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
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;
17+
18+
import java.time.Instant;
19+
import java.util.Optional;
20+
import java.util.UUID;
21+
22+
import org.springframework.context.ApplicationEvent;
23+
import org.springframework.context.PayloadApplicationEvent;
24+
25+
/**
26+
* An event publication.
27+
*
28+
* @author Oliver Drotbohm
29+
* @since 1.1
30+
*/
31+
public interface EventPublication {
32+
33+
/**
34+
* Returns a unique identifier for this publication.
35+
*
36+
* @return will never be {@literal null}.
37+
*/
38+
UUID getIdentifier();
39+
40+
/**
41+
* Returns the event that is published.
42+
*
43+
* @return
44+
*/
45+
Object getEvent();
46+
47+
/**
48+
* Returns the event as Spring {@link ApplicationEvent}, effectively wrapping it into a
49+
* {@link PayloadApplicationEvent} in case it's not one already.
50+
*
51+
* @return
52+
*/
53+
default ApplicationEvent getApplicationEvent() {
54+
55+
Object event = getEvent();
56+
57+
return PayloadApplicationEvent.class.isInstance(event) //
58+
? PayloadApplicationEvent.class.cast(event)
59+
: new PayloadApplicationEvent<>(this, event);
60+
}
61+
62+
/**
63+
* Returns the time the event is published at.
64+
*
65+
* @return
66+
*/
67+
Instant getPublicationDate();
68+
69+
/**
70+
* Returns the completion date of the publication.
71+
*
72+
* @return will never be {@literal null}.
73+
*/
74+
Optional<Instant> getCompletionDate();
75+
76+
/**
77+
* Returns whether the publication of the event has completed.
78+
*
79+
* @return will never be {@literal null}.
80+
*/
81+
default boolean isPublicationCompleted() {
82+
return getCompletionDate().isPresent();
83+
}
84+
85+
/*
86+
* (non-Javadoc)
87+
* @see java.lang.Comparable#compareTo(java.lang.Object)
88+
*/
89+
default int compareTo(EventPublication that) {
90+
return this.getPublicationDate().compareTo(that.getPublicationDate());
91+
}
92+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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;
17+
18+
import java.time.Duration;
19+
import java.util.function.Predicate;
20+
21+
/**
22+
* All uncompleted event publications.
23+
*
24+
* @author Oliver Drotbohm
25+
* @since 1.1
26+
*/
27+
public interface IncompleteEventPublications {
28+
29+
/**
30+
* Triggers the re-submission of events for which incomplete {@link EventPublication}s are registered. Note, that this
31+
* will materialize <em>all</em> incomplete event publications.
32+
*
33+
* @param filter a {@link Predicate} to select the event publications for which to resubmit events.
34+
*/
35+
void resubmitIncompletePublications(Predicate<EventPublication> filter);
36+
37+
/**
38+
* Triggers the re-submission of events for which incomplete {@link EventPublication}s are registered that exceed a
39+
* certain age regarding their original publication date.
40+
*
41+
* @param duration must not be {@literal null}.
42+
*/
43+
void resubmitIncompletePublicationsOlderThan(Duration duration);
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/**
2+
* API of the event publication registry abstraction.
3+
*/
4+
@org.springframework.lang.NonNullApi
5+
package org.springframework.modulith.events;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818

1919
<dependencies>
2020

21+
<dependency>
22+
<groupId>org.springframework.modulith</groupId>
23+
<artifactId>spring-modulith-events-api</artifactId>
24+
<version>${project.version}</version>
25+
</dependency>
26+
2127
<dependency>
2228
<groupId>org.springframework</groupId>
2329
<artifactId>spring-context</artifactId>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import java.time.Instant;
1919

2020
/**
21-
* Internal interface to be able to mark {@link EventPublication} instances as completed.
21+
* Internal interface to be able to mark {@link TargetEventPublication} instances as completed.
2222
*
2323
* @author Oliver Drotbohm
2424
*/

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,15 @@
2020
import java.util.Optional;
2121
import java.util.UUID;
2222

23+
import org.springframework.lang.Nullable;
2324
import org.springframework.util.Assert;
2425

2526
/**
2627
* Default {@link Completable} implementation.
2728
*
2829
* @author Oliver Drotbohm
2930
*/
30-
class DefaultEventPublication implements EventPublication {
31+
class DefaultEventPublication implements TargetEventPublication {
3132

3233
private final UUID identifier;
3334
private final Object event;
@@ -124,7 +125,7 @@ public String toString() {
124125
* @see java.lang.Object#equals(java.lang.Object)
125126
*/
126127
@Override
127-
public boolean equals(Object obj) {
128+
public boolean equals(@Nullable Object obj) {
128129

129130
if (this == obj) {
130131
return true;

0 commit comments

Comments
 (0)