Skip to content

Commit

Permalink
feat: Old messages are deleted after a configurable time (default is …
Browse files Browse the repository at this point in the history
…after 180 days) with all associated data.

- Integrates scheduled jobs which deletes the old messages.
- Sets the default property values in application.properties.
- Extends the repositories for the necessary methods.

PR #773
  • Loading branch information
jekutzsche authored May 4, 2022
1 parent eadb139 commit d768632
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public class IrisMessage extends Aggregate<IrisMessage, IrisMessage.IrisMessageI

private boolean isRead;

@OneToMany(mappedBy = "message", cascade = CascadeType.ALL, orphanRemoval = true)
@OneToMany(mappedBy = "message", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
private List<IrisMessageData> dataAttachments = new ArrayList<>();

@EqualsAndHashCode(callSuper = false)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package iris.client_bff.iris_messages;

import iris.client_bff.iris_messages.IrisMessage.IrisMessageIdentifier;
import lombok.Getter;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.time.Duration;
import java.time.Instant;
import java.util.stream.Collectors;

import javax.transaction.Transactional;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConstructorBinding;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
* This class collects all old events and deletes this.
*
* @author Jens Kutzsche
*/
@Component
@Slf4j
@RequiredArgsConstructor
class IrisMessageDeleteJob {

private final @NonNull IrisMessageRepository messageRepo;
private final @NonNull Properties properties;

@Transactional
@Scheduled(cron = "${iris.client.message.delete-cron:-}")
void deleteMessages() {

var refDate = Instant.now().minus(properties.getDeleteAfter());

var oldMessages = messageRepo.findByMetadataCreatedIsBefore(refDate).toList();

if (oldMessages.isEmpty()) {
return;
}

log.debug("{} IRIS message(s) are deleted with period {} after their creation!",
oldMessages.size(),
properties.getDeleteAfter(),
oldMessages.get(0).getCreatedAt());

messageRepo.deleteAll(oldMessages);

log.info("{} IRIS message(s) (IDs: {}) were deleted with period {} after their creation at {}!",
oldMessages.size(),
oldMessages.stream()
.map(IrisMessage::getId)
.map(IrisMessageIdentifier::toString)
.collect(Collectors.joining(", ")),
properties.getDeleteAfter(),
oldMessages.get(0).getCreatedAt());
}

@ConstructorBinding
@RequiredArgsConstructor
@ConfigurationProperties("iris.client.message")
@Getter
public static class Properties {

/**
* Defines the {@link Duration} after that a IRIS message will be deleted starting from the creation date.
*/
private final Duration deleteAfter;
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package iris.client_bff.iris_messages;

import java.time.Instant;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.util.Streamable;

public interface IrisMessageRepository extends JpaRepository<IrisMessage, IrisMessage.IrisMessageIdentifier> {

Expand All @@ -15,4 +18,11 @@ public interface IrisMessageRepository extends JpaRepository<IrisMessage, IrisMe
Page<IrisMessage> findAllByFolderIdOrderByIsReadAsc(IrisMessageFolder.IrisMessageFolderIdentifier folder,
Pageable pageable);

/**
* Returns the {@link IrisMessage}s created before the given {@link Instant}.
*
* @param refDate must not be {@literal null}.
* @return
*/
Streamable<IrisMessage> findByMetadataCreatedIsBefore(Instant refDate);
}
2 changes: 2 additions & 0 deletions iris-client-bff/src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ iris.client.vaccinfo.delete-after=6m
iris.client.vaccinfo.delete-cron=0 32 1 * * *
iris.client.vaccinfo.announcement.delete-after=2h
iris.client.vaccinfo.announcement.delete-cron=0 10 * * * *
iris.client.message.delete-after=180d
iris.client.message.delete-cron=0 33 1 * * *
iris.client.message.build-recipient-list.delay=900000

iris.client.vaccinfo.expiration-duration=2h
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package iris.client_bff.iris_messages;

import static java.time.Duration.*;
import static org.assertj.core.api.Assertions.*;

import iris.client_bff.IrisWebIntegrationTest;
import iris.client_bff.core.IrisDateTimeProvider;
import lombok.RequiredArgsConstructor;

import org.junit.jupiter.api.Test;

/**
* @author Jens Kutzsche
*/
@IrisWebIntegrationTest
@RequiredArgsConstructor
class IrisMessageDeleteJobIntegrationTests {

private final IrisMessageRepository messageRepo;
private final IrisMessageDataRepository dataRepo;
private final IrisMessageFolderRepository folderRepo;
private final IrisDateTimeProvider dateTimeProvider;
private final IrisMessageDeleteJob deleteJob;

@Test
void testDeleteMessages() {

var messagesSize = messageRepo.findAll().size();
var dataSize = dataRepo.findAll().size();

// in time
dateTimeProvider.setDelta(ofDays(-179));

createMessage();

// to old
dateTimeProvider.setDelta(ofDays(-181));

createMessage();

dateTimeProvider.reset();

// extra element from data initialization
assertThat(messageRepo.findAll()).hasSize(messagesSize + 2);
assertThat(dataRepo.findAll()).hasSize(dataSize + 2);

deleteJob.deleteMessages();

assertThat(messageRepo.findAll()).hasSize(messagesSize + 1);
assertThat(dataRepo.findAll()).hasSize(dataSize + 1);
}

private void createMessage() {

var testData = new IrisMessageTestData();

var folder = this.folderRepo.findFirstByContextAndParentFolderIsNull(IrisMessageContext.INBOX).get();

messageRepo.save(testData.getTestInboxMessage(folder));
}
}

0 comments on commit d768632

Please sign in to comment.