Skip to content

Commit

Permalink
GH-806 - Add archive support for JPA (one test failing)
Browse files Browse the repository at this point in the history
  • Loading branch information
ciberkleid committed Oct 24, 2024
1 parent 643ef03 commit 5a3e3ec
Show file tree
Hide file tree
Showing 4 changed files with 311 additions and 165 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.springframework.modulith.events.jpa;

import jakarta.persistence.Entity;
import jakarta.persistence.Table;

import java.time.Instant;
import java.util.UUID;

/**
* JPA entity to represent archived event publications.
*
* @author Oliver Drotbohm
*/
@Entity
@Table(name = "EVENT_PUBLICATION_ARCHIVE")
class ArchivedJpaEventPublication extends JpaEventPublication {

/**
* Creates a new {@link ArchivedJpaEventPublication} for the given publication date, listener id, serialized event and event
* type.
*
* @param id
* @param publicationDate must not be {@literal null}.
* @param listenerId must not be {@literal null} or empty.
* @param serializedEvent must not be {@literal null} or empty.
* @param eventType must not be {@literal null}.
*/
public ArchivedJpaEventPublication(UUID id, Instant publicationDate, String listenerId, String serializedEvent, Class<?> eventType) {
super(id, publicationDate, listenerId, serializedEvent, eventType);
}

public ArchivedJpaEventPublication() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@
*/
package org.springframework.modulith.events.jpa;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.*;

import java.time.Instant;
import java.util.UUID;
Expand All @@ -34,6 +31,7 @@
*/
@Entity
@Table(name = "EVENT_PUBLICATION")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
class JpaEventPublication {

final @Id @Column(length = 16) UUID id;
Expand Down Expand Up @@ -68,7 +66,7 @@ class JpaEventPublication {
this.eventType = eventType;
}

JpaEventPublication() {
protected JpaEventPublication() {

this.id = null;
this.publicationDate = null;
Expand All @@ -77,9 +75,11 @@ class JpaEventPublication {
this.eventType = null;
}

JpaEventPublication markCompleted() {
ArchivedJpaEventPublication archive(Instant instant) {

this.completionDate = Instant.now();
return this;
var result = new ArchivedJpaEventPublication(id, publicationDate, listenerId, serializedEvent, eventType);
result.completionDate = instant;

return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
* @author Oliver Drotbohm
* @author Dmitry Belyaev
* @author Björn Kieling
* @author Cora Iberkleid
*/
@Transactional
class JpaEventPublicationRepository implements EventPublicationRepository {
Expand All @@ -53,7 +54,7 @@ class JpaEventPublicationRepository implements EventPublicationRepository {

private static String COMPLETE = """
select p
from JpaEventPublication p
from %s p
where
p.completionDate is not null
order by
Expand Down Expand Up @@ -113,14 +114,14 @@ class JpaEventPublicationRepository implements EventPublicationRepository {

private static final String DELETE_COMPLETED = """
delete
from JpaEventPublication p
from %s p
where
p.completionDate is not null
""";

private static final String DELETE_COMPLETED_BEFORE = """
delete
from JpaEventPublication p
from %s p
where
p.completionDate < ?1
""";
Expand All @@ -131,6 +132,8 @@ class JpaEventPublicationRepository implements EventPublicationRepository {
private final EventSerializer serializer;
private final CompletionMode completionMode;

private final String getCompleted, deleteCompleted, deleteCompletedBefore;

/**
* Creates a new {@link JpaEventPublicationRepository} for the given {@link EntityManager} and
* {@link EventSerializer}.
Expand All @@ -148,7 +151,15 @@ public JpaEventPublicationRepository(EntityManager entityManager, EventSerialize
this.entityManager = entityManager;
this.serializer = serializer;
this.completionMode = completionMode;
}

var archiveEntityName = completionMode == CompletionMode.ARCHIVE
? ArchivedJpaEventPublication.class.getSimpleName()
: JpaEventPublication.class.getSimpleName();

this.getCompleted = COMPLETE.formatted(archiveEntityName);
this.deleteCompleted = DELETE_COMPLETED.formatted(archiveEntityName);
this.deleteCompletedBefore = DELETE_COMPLETED_BEFORE.formatted(archiveEntityName);
}

/*
* (non-Javadoc)
Expand Down Expand Up @@ -179,6 +190,18 @@ public void markCompleted(Object event, PublicationTargetIdentifier identifier,
.setParameter(2, identifierValue)
.executeUpdate();

} else if (completionMode == CompletionMode.ARCHIVE) {

var publication = entityManager.createQuery(BY_EVENT_AND_LISTENER_ID, JpaEventPublication.class)
.setParameter(1, serializedEvent)
.setParameter(2, identifierValue)
.getSingleResult();

var archived = publication.archive(completionDate);

entityManager.remove(publication);
entityManager.persist(archived);

} else {

entityManager.createQuery(MARK_COMPLETED_BY_EVENT_AND_LISTENER_ID)
Expand All @@ -202,6 +225,15 @@ public void markCompleted(UUID identifier, Instant completionDate) {
.setParameter(1, identifier)
.executeUpdate();

} else if (completionMode == CompletionMode.ARCHIVE) {

var publication = entityManager.find(JpaEventPublication.class, identifier);

var archived = publication.archive(completionDate);

entityManager.remove(publication);
entityManager.persist(archived);

} else {

entityManager.createQuery(MARK_COMPLETED_BY_ID)
Expand Down Expand Up @@ -260,7 +292,11 @@ public Optional<TargetEventPublication> findIncompletePublicationsByEventAndTarg
@Override
public List<TargetEventPublication> findCompletedPublications() {

return entityManager.createQuery(COMPLETE, JpaEventPublication.class)
var type = completionMode == CompletionMode.ARCHIVE
? ArchivedJpaEventPublication.class
: JpaEventPublication.class;

return entityManager.createQuery(getCompleted, type)
.getResultList()
.stream()
.map(this::entityToDomain)
Expand All @@ -285,7 +321,7 @@ public void deletePublications(List<UUID> identifiers) {
*/
@Override
public void deleteCompletedPublications() {
entityManager.createQuery(DELETE_COMPLETED).executeUpdate();
entityManager.createQuery(deleteCompleted).executeUpdate();
}

/*
Expand All @@ -297,7 +333,7 @@ public void deleteCompletedPublicationsBefore(Instant instant) {

Assert.notNull(instant, "Instant must not be null!");

entityManager.createQuery(DELETE_COMPLETED_BEFORE)
entityManager.createQuery(deleteCompletedBefore)
.setParameter(1, instant)
.executeUpdate();
}
Expand Down Expand Up @@ -341,6 +377,7 @@ private static class JpaEventPublicationAdapter implements TargetEventPublicatio

private final JpaEventPublication publication;
private final EventSerializer serializer;
private Object deserializedEvent;

/**
* Creates a new {@link JpaEventPublicationAdapter} for the given {@link JpaEventPublication} and
Expand Down Expand Up @@ -373,7 +410,12 @@ public UUID getIdentifier() {
*/
@Override
public Object getEvent() {
return serializer.deserialize(publication.serializedEvent, publication.eventType);

if (deserializedEvent == null) {
this.deserializedEvent = serializer.deserialize(publication.serializedEvent, publication.eventType);
}

return deserializedEvent;
}

/*
Expand Down
Loading

0 comments on commit 5a3e3ec

Please sign in to comment.