This is the codeAbility Sharing Platform! Learn more about the codeAbility Sharing Platform.

Skip to content
Snippets Groups Projects
Commit 99393dbd authored by Michael Breu's avatar Michael Breu :speech_balloon:
Browse files

Resolve "Sharing Plattform stürzt jeden Tag um 10 Uhr ab,"

parent 0bed4004
Branches
2 merge requests!266merge development into master,!256Resolve "Sharing Plattform stürzt jeden Tag um 10 Uhr ab,"
...@@ -3,10 +3,11 @@ package at.ac.uibk.gitsearch.repository.jpa; ...@@ -3,10 +3,11 @@ package at.ac.uibk.gitsearch.repository.jpa;
import at.ac.uibk.gitsearch.domain.PersistentAuditEvent; import at.ac.uibk.gitsearch.domain.PersistentAuditEvent;
import java.time.Instant; import java.time.Instant;
import java.util.List; import java.util.List;
import java.util.stream.Stream;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
/** /**
* Spring Data JPA repository for the {@link PersistentAuditEvent} entity. * Spring Data JPA repository for the {@link PersistentAuditEvent} entity.
...@@ -18,7 +19,13 @@ public interface PersistenceAuditEventRepository extends JpaRepository<Persisten ...@@ -18,7 +19,13 @@ public interface PersistenceAuditEventRepository extends JpaRepository<Persisten
Page<PersistentAuditEvent> findAllByAuditEventDateBetween(Instant fromDate, Instant toDate, Pageable pageable); Page<PersistentAuditEvent> findAllByAuditEventDateBetween(Instant fromDate, Instant toDate, Pageable pageable);
List<PersistentAuditEvent> findByAuditEventDateBefore(Instant before); List<PersistentAuditEvent> findTop1000ByAuditEventDateBefore(Instant before);
Stream<PersistentAuditEvent> streamByAuditEventDateBefore(Instant before); /**
* @Deprecated due to https://hibernate.atlassian.net/browse/HHH-5528
*/
@Deprecated
@Modifying
@Query("delete from PersistentAuditEvent ae where ae.auditEventDate < ?1")
int deleteInBulkByRoleId(Instant before);
} }
package at.ac.uibk.gitsearch.service; package at.ac.uibk.gitsearch.service;
import at.ac.uibk.gitsearch.domain.PersistentAuditEvent;
import at.ac.uibk.gitsearch.repository.jpa.AuditEventConverter; import at.ac.uibk.gitsearch.repository.jpa.AuditEventConverter;
import at.ac.uibk.gitsearch.repository.jpa.PersistenceAuditEventRepository; import at.ac.uibk.gitsearch.repository.jpa.PersistenceAuditEventRepository;
import java.time.Instant; import java.time.Instant;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -12,7 +14,12 @@ import org.springframework.data.domain.Page; ...@@ -12,7 +14,12 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import tech.jhipster.config.JHipsterProperties; import tech.jhipster.config.JHipsterProperties;
/** /**
...@@ -24,22 +31,29 @@ import tech.jhipster.config.JHipsterProperties; ...@@ -24,22 +31,29 @@ import tech.jhipster.config.JHipsterProperties;
@Transactional @Transactional
public class AuditEventService { public class AuditEventService {
private final Logger log = LoggerFactory.getLogger(AuditEventService.class); @SuppressWarnings("unused")
private static final Logger LOGGER = LoggerFactory.getLogger(AuditEventService.class);
private final JHipsterProperties jHipsterProperties; private final JHipsterProperties jHipsterProperties;
private final PersistenceAuditEventRepository persistenceAuditEventRepository; private final PersistenceAuditEventRepository persistenceAuditEventRepository;
private final TransactionTemplate isolatedTransactionTemplate;
private final AuditEventConverter auditEventConverter; private final AuditEventConverter auditEventConverter;
public AuditEventService( public AuditEventService(
PersistenceAuditEventRepository persistenceAuditEventRepository, PersistenceAuditEventRepository persistenceAuditEventRepository,
AuditEventConverter auditEventConverter, AuditEventConverter auditEventConverter,
JHipsterProperties jhipsterProperties JHipsterProperties jhipsterProperties,
PlatformTransactionManager platformTransactionManager
) { ) {
this.persistenceAuditEventRepository = persistenceAuditEventRepository; this.persistenceAuditEventRepository = persistenceAuditEventRepository;
this.auditEventConverter = auditEventConverter; this.auditEventConverter = auditEventConverter;
this.jHipsterProperties = jhipsterProperties; this.jHipsterProperties = jhipsterProperties;
isolatedTransactionTemplate = new TransactionTemplate(platformTransactionManager);
isolatedTransactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
} }
/** /**
...@@ -49,13 +63,28 @@ public class AuditEventService { ...@@ -49,13 +63,28 @@ public class AuditEventService {
*/ */
@Scheduled(cron = "0 0 23 * * ?") @Scheduled(cron = "0 0 23 * * ?")
public void removeOldAuditEvents() { public void removeOldAuditEvents() {
persistenceAuditEventRepository boolean next = true;
.streamByAuditEventDateBefore(Instant.now().minus(jHipsterProperties.getAuditEvents().getRetentionPeriod(), ChronoUnit.DAYS))
.forEach(auditEvent -> { while (next) {
log.debug("Deleting audit data {}", auditEvent); next =
persistenceAuditEventRepository.delete(auditEvent); isolatedTransactionTemplate.execute(
persistenceAuditEventRepository.flush(); new TransactionCallback<Boolean>() {
}); @Override
public Boolean doInTransaction(TransactionStatus status) {
final List<PersistentAuditEvent> auditEventDeleteCandidates = persistenceAuditEventRepository.findTop1000ByAuditEventDateBefore(
Instant.now().minus(jHipsterProperties.getAuditEvents().getRetentionPeriod(), ChronoUnit.DAYS)
);
persistenceAuditEventRepository.deleteAll(auditEventDeleteCandidates);
return !auditEventDeleteCandidates.isEmpty();
}
}
);
}
// not working, due to https://hibernate.atlassian.net/browse/HHH-5528
// int count = persistenceAuditEventRepository.deleteInBulkByRoleId(
// Instant.now().minus(jHipsterProperties.getAuditEvents().getRetentionPeriod(), ChronoUnit.DAYS)
// );
// LOGGER.info("cleaned up {} outdated AuditEnvets", count);
} }
@Transactional(readOnly = true) @Transactional(readOnly = true)
......
...@@ -13,9 +13,17 @@ import java.util.concurrent.TimeUnit; ...@@ -13,9 +13,17 @@ import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.Timeout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import tech.jhipster.config.JHipsterProperties; import tech.jhipster.config.JHipsterProperties;
/** /**
...@@ -25,6 +33,11 @@ import tech.jhipster.config.JHipsterProperties; ...@@ -25,6 +33,11 @@ import tech.jhipster.config.JHipsterProperties;
@Transactional @Transactional
public class AuditEventServiceIT { public class AuditEventServiceIT {
private final Logger log = LoggerFactory.getLogger(AuditEventServiceIT.class);
@Autowired
private PlatformTransactionManager platformTransactionManager;
@Autowired @Autowired
private AuditEventService auditEventService; private AuditEventService auditEventService;
...@@ -40,13 +53,16 @@ public class AuditEventServiceIT { ...@@ -40,13 +53,16 @@ public class AuditEventServiceIT {
private PersistentAuditEvent auditEventNew; private PersistentAuditEvent auditEventNew;
private static final int MAX_OUTDATEDVALUES = 4500;
@BeforeEach @BeforeEach
public void init() { public void init() {
log.info("Preparing {} outdated AuditEvents", MAX_OUTDATEDVALUES);
auditEventsOld = new ArrayList<>(); auditEventsOld = new ArrayList<>();
for (int i = 1; i <= 1000; i++) { for (int i = 1; i <= MAX_OUTDATEDVALUES; i++) {
PersistentAuditEvent auditEventOld = new PersistentAuditEvent(); PersistentAuditEvent auditEventOld = new PersistentAuditEvent();
auditEventOld.setAuditEventDate( auditEventOld.setAuditEventDate(
Instant.now().minus(jHipsterProperties.getAuditEvents().getRetentionPeriod() + i, ChronoUnit.DAYS) Instant.now().minus((jHipsterProperties.getAuditEvents().getRetentionPeriod() + 1) * 24 + i, ChronoUnit.HOURS)
); );
auditEventOld.setPrincipal("test-user-old"); auditEventOld.setPrincipal("test-user-old");
auditEventOld.setAuditEventType("test-type"); auditEventOld.setAuditEventType("test-type");
...@@ -54,6 +70,7 @@ public class AuditEventServiceIT { ...@@ -54,6 +70,7 @@ public class AuditEventServiceIT {
auditEventOld.getData().put("someDate", "someValue" + i); auditEventOld.getData().put("someDate", "someValue" + i);
auditEventsOld.add(auditEventOld); auditEventsOld.add(auditEventOld);
} }
log.info("Prepared {} outdated AuditEvents", MAX_OUTDATEDVALUES);
auditEventWithinRetention = new PersistentAuditEvent(); auditEventWithinRetention = new PersistentAuditEvent();
auditEventWithinRetention.setAuditEventDate( auditEventWithinRetention.setAuditEventDate(
Instant.now().minus(jHipsterProperties.getAuditEvents().getRetentionPeriod() - 1, ChronoUnit.DAYS) Instant.now().minus(jHipsterProperties.getAuditEvents().getRetentionPeriod() - 1, ChronoUnit.DAYS)
...@@ -69,16 +86,30 @@ public class AuditEventServiceIT { ...@@ -69,16 +86,30 @@ public class AuditEventServiceIT {
@Test @Test
@Timeout(value = 5, unit = TimeUnit.MINUTES) @Timeout(value = 5, unit = TimeUnit.MINUTES)
@Transactional @DirtiesContext
public void verifyOldAuditEventsAreDeleted() { public void verifyOldAuditEventsAreDeleted() {
persistenceAuditEventRepository.deleteAll(); TransactionTemplate isolatedTransactionTemplate = new TransactionTemplate(platformTransactionManager);
auditEventsOld.forEach(auditEventOld -> persistenceAuditEventRepository.save(auditEventOld)); isolatedTransactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
persistenceAuditEventRepository.save(auditEventWithinRetention);
persistenceAuditEventRepository.save(auditEventNew); isolatedTransactionTemplate.execute(
new TransactionCallback<Boolean>() {
@Override
public Boolean doInTransaction(TransactionStatus status) {
persistenceAuditEventRepository.deleteAll();
auditEventsOld.forEach(auditEventOld -> persistenceAuditEventRepository.save(auditEventOld));
persistenceAuditEventRepository.save(auditEventWithinRetention);
persistenceAuditEventRepository.save(auditEventNew);
return true;
}
}
);
log.info("Saved {} outdated AuditEvents", MAX_OUTDATEDVALUES);
assertThat(persistenceAuditEventRepository.findAll().size()).isGreaterThan(MAX_OUTDATEDVALUES);
persistenceAuditEventRepository.flush();
auditEventService.removeOldAuditEvents(); auditEventService.removeOldAuditEvents();
persistenceAuditEventRepository.flush(); // persistenceAuditEventRepository.flush();
assertThat(persistenceAuditEventRepository.findAll().size()).isEqualTo(2); assertThat(persistenceAuditEventRepository.findAll().size()).isEqualTo(2);
assertThat(persistenceAuditEventRepository.findByPrincipal("test-user-old")).isEmpty(); assertThat(persistenceAuditEventRepository.findByPrincipal("test-user-old")).isEmpty();
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment