Skip to content

Commit a55ebe9

Browse files
author
mihaita.tinta
committed
wip failed attempt info
Signed-off-by: mihaita.tinta <mihaita.tinta@ing.com>
1 parent b594b69 commit a55ebe9

File tree

17 files changed

+798
-431
lines changed

17 files changed

+798
-431
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.springframework.modulith.events;
1717

1818
import java.time.Instant;
19+
import java.util.List;
1920
import java.util.Optional;
2021
import java.util.UUID;
2122

@@ -73,6 +74,12 @@ default ApplicationEvent getApplicationEvent() {
7374
*/
7475
Optional<Instant> getCompletionDate();
7576

77+
/**
78+
* Returns the list of failed attempts to publish the event
79+
* @return will never be {@literal null}.
80+
*/
81+
List<FailedAttemptInfo> getFailedAttempts();
82+
7683
/**
7784
* Returns whether the publication of the event has completed.
7885
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.springframework.modulith.events;
2+
3+
import java.time.Instant;
4+
5+
public interface FailedAttemptInfo {
6+
/**
7+
* Returns the time the event is published at.
8+
*
9+
* @return will never be {@literal null}.
10+
*/
11+
Instant getPublicationDate();
12+
13+
/**
14+
* Returns the exception causing the publication to fail
15+
*
16+
* @return will never be {@literal null}.
17+
*/
18+
Throwable getFailureReason();
19+
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,12 @@ interface Completable {
3030
* @param instant must not be {@literal null}.
3131
*/
3232
void markCompleted(Instant instant);
33+
34+
/**
35+
* Stores the reason why the publication failed
36+
*
37+
* @param instant must not be {@literal null}.
38+
* @param exception must not be {@literal null}.
39+
*/
40+
void markFailed(Instant instant, Throwable exception);
3341
}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,20 @@
1616
package org.springframework.modulith.events.core;
1717

1818
import java.time.Instant;
19+
import java.util.ArrayList;
20+
import java.util.Collection;
21+
import java.util.Collections;
22+
import java.util.List;
1923
import java.util.Objects;
2024
import java.util.Optional;
2125
import java.util.UUID;
2226

2327
import org.springframework.lang.Nullable;
28+
import org.springframework.modulith.events.FailedAttemptInfo;
2429
import org.springframework.util.Assert;
2530

31+
import static java.util.Collections.unmodifiableList;
32+
2633
/**
2734
* Default {@link Completable} implementation.
2835
*
@@ -36,6 +43,7 @@ class DefaultEventPublication implements TargetEventPublication {
3643
private final Instant publicationDate;
3744

3845
private Optional<Instant> completionDate;
46+
private List<FailedAttemptInfo> failedAttempts;
3947

4048
/**
4149
* Creates a new {@link DefaultEventPublication} for the given event and {@link PublicationTargetIdentifier}.
@@ -100,6 +108,11 @@ public Optional<Instant> getCompletionDate() {
100108
return completionDate;
101109
}
102110

111+
@Override
112+
public List<FailedAttemptInfo> getFailedAttempts() {
113+
return failedAttempts == null ? List.of() : unmodifiableList(failedAttempts);
114+
}
115+
103116
/*
104117
* (non-Javadoc)
105118
* @see org.springframework.modulith.events.CompletableEventPublication#markCompleted(java.time.Instant)
@@ -109,6 +122,15 @@ public void markCompleted(Instant instant) {
109122
this.completionDate = Optional.of(instant);
110123
}
111124

125+
126+
@Override
127+
public void markFailed(Instant instant, Throwable exception) {
128+
if (failedAttempts == null) {
129+
failedAttempts = new ArrayList<>();
130+
}
131+
failedAttempts.add(new DefaultFailedAttemptInfo(instant, exception));
132+
}
133+
112134
/*
113135
* (non-Javadoc)
114136
* @see java.lang.Object#toString()

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ public void markCompleted(Object event, PublicationTargetIdentifier targetIdenti
136136
* @see org.springframework.modulith.events.core.EventPublicationRegistry#markFailed(java.lang.Object, org.springframework.modulith.events.core.PublicationTargetIdentifier)
137137
*/
138138
@Override
139-
public void markFailed(Object event, PublicationTargetIdentifier targetIdentifier) {
139+
public void markFailed(Object event, PublicationTargetIdentifier targetIdentifier, Throwable o_O) {
140140
inProgress.unregister(event, targetIdentifier);
141141
}
142142

@@ -266,14 +266,14 @@ PublicationsInProgress getPublicationsInProgress() {
266266
* Marks the given {@link TargetEventPublication} as failed.
267267
*
268268
* @param publication must not be {@literal null}.
269-
* @see #markFailed(Object, PublicationTargetIdentifier)
269+
* @see #markFailed(Object, PublicationTargetIdentifier, Throwable)
270270
* @since 1.3
271271
*/
272-
void markFailed(TargetEventPublication publication) {
272+
void markFailed(TargetEventPublication publication, Throwable exception) {
273273

274274
Assert.notNull(publication, "TargetEventPublication must not be null!");
275275

276-
markFailed(publication.getEvent(), publication.getTargetIdentifier());
276+
markFailed(publication.getEvent(), publication.getTargetIdentifier(), exception);
277277
}
278278

279279
private static String getConfirmationMessage(Collection<?> publications) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright 2017-2025 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.core;
17+
18+
import org.springframework.modulith.events.FailedAttemptInfo;
19+
20+
import java.time.Instant;
21+
22+
/**
23+
* Default {@link FailedAttemptInfo} implementation.
24+
* @param publicationDate - when the event failed to be published
25+
* @param exception - the reason of publication failure
26+
*/
27+
record DefaultFailedAttemptInfo(Instant publicationDate, Throwable exception) implements FailedAttemptInfo {
28+
29+
@Override
30+
public Instant getPublicationDate() {
31+
return publicationDate;
32+
}
33+
34+
@Override
35+
public Throwable getFailureReason() {
36+
return exception;
37+
}
38+
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,10 @@ public interface EventPublicationRegistry {
7373
*
7474
* @param event must not be {@literal null}.
7575
* @param targetIdentifier must not be {@literal null}.
76+
* @param exception cause of failing publication
7677
* @since 1.3
7778
*/
78-
void markFailed(Object event, PublicationTargetIdentifier targetIdentifier);
79+
void markFailed(Object event, PublicationTargetIdentifier targetIdentifier, Throwable exception);
7980

8081
/**
8182
* Deletes all completed {@link TargetEventPublication}s that have been completed before the given {@link Duration}.

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ default void markCompleted(TargetEventPublication publication, Instant completio
6565
*/
6666
void markCompleted(Object event, PublicationTargetIdentifier identifier, Instant completionDate);
6767

68+
/**
69+
* Marks the publication for the given event and {@link PublicationTargetIdentifier} as failed.
70+
*
71+
* @param identifier must not be {@literal null}.
72+
* @param exception cause of failing publication
73+
* @since 1.3
74+
*/
75+
void markFailed(UUID identifier, Instant failedDate, Throwable exception);
76+
6877
/**
6978
* Marks the publication with the given identifier completed at the given {@link Instant}.
7079
*

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -204,15 +204,15 @@ public int getOrder() {
204204
return Ordered.HIGHEST_PRECEDENCE + 10;
205205
}
206206

207-
private void handleFailure(Method method, Object event, Throwable o_O) {
207+
private void handleFailure(Method method, Object event, Throwable exception) {
208208

209-
markFailed(method, event);
209+
markFailed(method, event, exception);
210210

211211
if (LOG.isDebugEnabled()) {
212-
LOG.debug("Invocation of listener {} failed. Leaving event publication uncompleted.", method, o_O);
212+
LOG.debug("Invocation of listener {} failed. Leaving event publication uncompleted.", method, exception);
213213
} else {
214214
LOG.info("Invocation of listener {} failed with message {}. Leaving event publication uncompleted.",
215-
method, o_O.getMessage());
215+
method, exception.getMessage());
216216
}
217217
}
218218

@@ -224,12 +224,12 @@ private void markCompleted(Method method, Object event) {
224224
registry.get().markCompleted(event, identifier);
225225
}
226226

227-
private void markFailed(Method method, Object event) {
227+
private void markFailed(Method method, Object event, Throwable exception) {
228228

229-
// Mark publication complete if the method is a transactional event listener.
229+
// Mark publication failed if the method is a transactional event listener.
230230
String adapterId = LISTENER_IDS.get(method);
231231
PublicationTargetIdentifier identifier = PublicationTargetIdentifier.of(adapterId);
232-
registry.get().markFailed(event, identifier);
232+
registry.get().markFailed(event, identifier, exception);
233233
}
234234

235235
@SuppressWarnings("null")

spring-modulith-events/spring-modulith-events-core/src/test/java/org/springframework/modulith/events/core/DefaultEventPublicationRegistryUnitTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,10 @@ void removesFailingResubmissionFromInProgressPublications() {
6666

6767
var registry = createRegistry(Instant.now());
6868
var identifier = PublicationTargetIdentifier.of("id");
69+
var error = new IllegalArgumentException("some error");
6970

7071
var failedPublications = registry.store(new Object(), Stream.of(identifier)).stream()
71-
.peek(registry::markFailed)
72+
.peek(e -> registry.markFailed(e, error))
7273
.toList();
7374

7475
// Failed completions are not present in the in progress ones

0 commit comments

Comments
 (0)