3636import org .springframework .data .mongodb .core .query .Query ;
3737import org .springframework .data .mongodb .core .query .Update ;
3838import org .springframework .data .util .TypeInformation ;
39+ import org .springframework .modulith .events .EventPublication .Status ;
3940import org .springframework .modulith .events .core .EventPublicationRepository ;
4041import org .springframework .modulith .events .core .PublicationTargetIdentifier ;
4142import org .springframework .modulith .events .core .TargetEventPublication ;
@@ -58,6 +59,10 @@ class MongoDbEventPublicationRepository implements EventPublicationRepository {
5859 private static final String ID = "id" ;
5960 private static final String LISTENER_ID = "listenerId" ;
6061 private static final String PUBLICATION_DATE = "publicationDate" ;
62+ private static final String STATUS = "status" ;
63+ private static final String COMPLETION_ATTEMPTS = "completionAttempts" ;
64+ private static final String LAST_RESUBMISSION_DATE = "lastResubmissionDate" ;
65+
6166 private static final Sort DEFAULT_SORT = Sort .by (PUBLICATION_DATE ).ascending ();
6267
6368 static final String ARCHIVE_COLLECTION = "event_publication_archive" ;
@@ -144,6 +149,36 @@ public void markCompleted(UUID identifier, Instant completionDate) {
144149 }
145150 }
146151
152+ /*
153+ * (non-Javadoc)
154+ * @see org.springframework.modulith.events.core.EventPublicationRepository#markFailed(java.util.UUID)
155+ */
156+ @ Override
157+ public void markFailed (UUID identifier ) {
158+
159+ var query = query (where (ID ).is (identifier ).and (STATUS ).ne (Status .FAILED ));
160+ var update = Update .update (STATUS , Status .FAILED );
161+
162+ mongoTemplate .findAndModify (query , update , MongoDbEventPublication .class , collection );
163+ }
164+
165+ /*
166+ * (non-Javadoc)
167+ * @see org.springframework.modulith.events.core.EventPublicationRepository#markResubmitted(java.util.UUID, java.time.Instant)
168+ */
169+ @ Override
170+ public boolean markResubmitted (UUID identifier , Instant resubmissionDate ) {
171+
172+ var query = query (where (ID ).is (identifier ).and (STATUS ).ne (Status .RESUBMITTED ));
173+ var update = Update .update (STATUS , Status .RESUBMITTED )
174+ .inc (COMPLETION_ATTEMPTS , 1 )
175+ .set (LAST_RESUBMISSION_DATE , resubmissionDate );
176+
177+ var result = mongoTemplate .updateFirst (query , update , MongoDbEventPublication .class , collection );
178+
179+ return result .getModifiedCount () == 1 ;
180+ }
181+
147182 /*
148183 * (non-Javadoc)
149184 * @see org.springframework.modulith.events.core.EventPublicationRepository#findIncompletePublications()
@@ -188,6 +223,48 @@ public List<TargetEventPublication> findCompletedPublications() {
188223 return readMapped (defaultQuery (where (COMPLETION_DATE ).ne (null )), archiveCollection );
189224 }
190225
226+ /*
227+ * (non-Javadoc)
228+ * @see org.springframework.modulith.events.core.EventPublicationRepository#findFailedPublications(org.springframework.modulith.events.core.EventPublicationRepository.FailedCriteria)
229+ */
230+ @ Override
231+ public List <TargetEventPublication > findFailedPublications (FailedCriteria criteria ) {
232+
233+ var statusFailed = where (STATUS ).is (Status .FAILED );
234+ var noStatusAndCompletionDate = where (STATUS ).isNull ().and (COMPLETION_DATE ).isNull ();
235+ var baseCriteria = new Criteria ().orOperator (statusFailed , noStatusAndCompletionDate );
236+
237+ // Apply date delimiter
238+ var reference = criteria .getPublicationDateReference ();
239+
240+ if (reference != null ) {
241+ baseCriteria .and (PUBLICATION_DATE ).lt (reference );
242+ }
243+
244+ // Apply limit
245+ var limit = criteria .getMaxItemsToRead ();
246+
247+ if (limit > Integer .MAX_VALUE ) {
248+ throw new IllegalArgumentException ("Number of items to read needs to fit into an integer!" );
249+ }
250+
251+ return readMapped (defaultQuery (baseCriteria ).limit ((int ) limit ));
252+ }
253+
254+ /*
255+ * (non-Javadoc)
256+ * @see org.springframework.modulith.events.core.EventPublicationRepository#countByStatus(org.springframework.modulith.events.EventPublication.Status)
257+ */
258+ @ Override
259+ public int countByStatus (Status status ) {
260+
261+ var collection = status == Status .COMPLETED && completionMode == CompletionMode .ARCHIVE
262+ ? archiveCollection
263+ : this .collection ;
264+
265+ return (int ) mongoTemplate .count (query (where (STATUS ).is (status )), MongoDbEventPublication .class , collection );
266+ }
267+
191268 /*
192269 * (non-Javadoc)
193270 * @see org.springframework.modulith.events.core.EventPublicationRepository#deletePublications(java.util.List)
@@ -250,7 +327,11 @@ private static MongoDbEventPublication domainToDocument(TargetEventPublication p
250327 publication .getIdentifier (), //
251328 publication .getPublicationDate (), //
252329 publication .getTargetIdentifier ().getValue (), //
253- publication .getEvent ());
330+ publication .getEvent (), //
331+ publication .getCompletionDate ().orElse (null ), //
332+ publication .getStatus (), //
333+ publication .getLastResubmissionDate (), //
334+ publication .getCompletionAttempts ());
254335 }
255336
256337 private static TargetEventPublication documentToDomain (MongoDbEventPublication document ) {
@@ -323,22 +404,27 @@ public boolean isPublicationCompleted() {
323404
324405 @ Override
325406 public void markCompleted (Instant instant ) {
326- this .publication .completionDate = instant ;
407+ this .publication .markCompleted ( instant ) ;
327408 }
328409
329410 @ Override
330411 public Status getStatus () {
412+
413+ if (publication .status != null ) {
414+ return publication .status ;
415+ }
416+
331417 return publication .completionDate != null ? Status .COMPLETED : Status .PUBLISHED ;
332418 }
333419
334420 @ Override
335421 public int getCompletionAttempts () {
336- return 1 ;
422+ return publication . completionAttempts ;
337423 }
338424
339425 @ Override
340426 public @ Nullable Instant getLastResubmissionDate () {
341- return null ;
427+ return publication . lastResubmissionDate ;
342428 }
343429
344430 /*
0 commit comments