Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit fc2d3ee

Browse files
author
FredrikSchäferVitagroup
committed
SORMAS-Foundation#3927 Deletion of old SystemEvents
1 parent ac78238 commit fc2d3ee

8 files changed

Lines changed: 129 additions & 4 deletions

File tree

sormas-api/src/main/java/de/symeda/sormas/api/ConfigFacade.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ public interface ConfigFacade {
8585

8686
int getDaysAfterEventGetsArchived();
8787

88+
int getDaysAfterSystemEventGetsDeleted();
89+
8890
GeoLatLon getCountryCenter();
8991

9092
int getMapZoom();

sormas-api/src/main/java/de/symeda/sormas/api/systemevents/SystemEventFacade.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,7 @@ public interface SystemEventFacade {
99
Date getLatestSuccessByType(SystemEventType type);
1010

1111
void saveSystemEvent(SystemEventDto dto);
12+
13+
void deleteAllDeletableSystemEvents(int daysAfterSystemEventGetsDeleted);
14+
1215
}

sormas-backend/src/main/java/de/symeda/sormas/backend/common/ConfigFacadeEjb.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ public class ConfigFacadeEjb implements ConfigFacade {
108108
public static final String DAYS_AFTER_CASE_GETS_ARCHIVED = "daysAfterCaseGetsArchived";
109109
private static final String DAYS_AFTER_EVENT_GETS_ARCHIVED = "daysAfterEventGetsArchived";
110110

111+
private static final String DAYS_AFTER_SYSTEM_EVENT_GETS_DELETED = "daysAfterSystemEventGetsDeleted";
112+
111113
private static final String GEOCODING_SERVICE_URL_TEMPLATE = "geocodingServiceUrlTemplate";
112114
private static final String GEOCODING_LONGITUDE_JSON_PATH = "geocodingLongitudeJsonPath";
113115
private static final String GEOCODING_LATITUDE_JSON_PATH = "geocodingLatitudeJsonPath";
@@ -373,6 +375,11 @@ public int getDaysAfterEventGetsArchived() {
373375
return getInt(DAYS_AFTER_EVENT_GETS_ARCHIVED, 90);
374376
}
375377

378+
@Override
379+
public int getDaysAfterSystemEventGetsDeleted() {
380+
return getInt(DAYS_AFTER_SYSTEM_EVENT_GETS_DELETED, 90);
381+
}
382+
376383
@Override
377384
public String getGeocodingServiceUrlTemplate() {
378385
return getProperty(GEOCODING_SERVICE_URL_TEMPLATE, null);

sormas-backend/src/main/java/de/symeda/sormas/backend/common/CronService.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import javax.ejb.Schedule;
2626
import javax.ejb.Singleton;
2727

28+
import de.symeda.sormas.backend.systemevent.SystemEventFacadeEjb.SystemEventFacadeEjbLocal;
2829
import org.slf4j.Logger;
2930
import org.slf4j.LoggerFactory;
3031

@@ -65,6 +66,8 @@ public class CronService {
6566
private EventFacadeEjbLocal eventFacade;
6667
@EJB
6768
private DocumentFacadeEjbLocal documentFacade;
69+
@EJB
70+
private SystemEventFacadeEjbLocal systemEventFacade;
6871

6972
@Schedule(hour = "*", minute = "*/" + TASK_UPDATE_INTERVAL, second = "0", persistent = false)
7073
public void sendNewAndDueTaskMessages() {
@@ -138,4 +141,13 @@ public void archiveEvents() {
138141
public void cleanupDeletedDocuments() {
139142
documentFacade.cleanupDeletedDocuments();
140143
}
144+
145+
@Schedule(hour = "1", minute = "30", second = "0", persistent = false)
146+
public void deleteSystemEvents() {
147+
int daysAfterSystemEventGetsDeleted = configFacade.getDaysAfterSystemEventGetsDeleted();
148+
if (daysAfterSystemEventGetsDeleted >= 1) {
149+
systemEventFacade.deleteAllDeletableSystemEvents(daysAfterSystemEventGetsDeleted);
150+
}
151+
}
152+
141153
}

sormas-backend/src/main/java/de/symeda/sormas/backend/systemevent/SystemEvent.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import javax.persistence.Temporal;
1313
import javax.persistence.TemporalType;
1414
import java.util.Date;
15+
import java.util.Objects;
1516

1617
import static de.symeda.sormas.api.EntityDto.COLUMN_LENGTH_DEFAULT;
1718

@@ -78,4 +79,24 @@ public void setAdditionalInfo(String additionalInfo) {
7879
this.additionalInfo = additionalInfo;
7980
}
8081

82+
@Override
83+
public boolean equals(Object o) {
84+
if (this == o)
85+
return true;
86+
if (o == null || getClass() != o.getClass())
87+
return false;
88+
if (!super.equals(o))
89+
return false;
90+
SystemEvent that = (SystemEvent) o;
91+
return type == that.type
92+
&& Objects.equals(startDate, that.startDate)
93+
&& Objects.equals(endDate, that.endDate)
94+
&& status == that.status
95+
&& Objects.equals(additionalInfo, that.additionalInfo);
96+
}
97+
98+
@Override
99+
public int hashCode() {
100+
return Objects.hash(super.hashCode(), type, startDate, endDate, status, additionalInfo);
101+
}
81102
}

sormas-backend/src/main/java/de/symeda/sormas/backend/systemevent/SystemEventFacadeEjb.java

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
import de.symeda.sormas.api.systemevents.SystemEventFacade;
55
import de.symeda.sormas.api.systemevents.SystemEventStatus;
66
import de.symeda.sormas.api.systemevents.SystemEventType;
7-
import de.symeda.sormas.backend.event.EventParticipant;
8-
import de.symeda.sormas.backend.labmessage.LabMessage;
9-
import de.symeda.sormas.backend.labmessage.LabMessageFacadeEjb;
7+
import de.symeda.sormas.api.utils.DateHelper;
108
import de.symeda.sormas.backend.util.DtoHelper;
119
import de.symeda.sormas.backend.util.ModelConstants;
10+
import org.slf4j.Logger;
11+
import org.slf4j.LoggerFactory;
1212

1313
import javax.ejb.EJB;
1414
import javax.ejb.LocalBean;
@@ -20,6 +20,8 @@
2020
import javax.persistence.criteria.Predicate;
2121
import javax.persistence.criteria.Root;
2222
import javax.validation.constraints.NotNull;
23+
import java.sql.Timestamp;
24+
import java.time.LocalDateTime;
2325
import java.util.Date;
2426
import java.util.List;
2527

@@ -32,6 +34,8 @@ public class SystemEventFacadeEjb implements SystemEventFacade {
3234
@EJB
3335
private SystemEventService systemEventService;
3436

37+
private final Logger logger = LoggerFactory.getLogger(getClass());
38+
3539
@Override
3640
public Date getLatestSuccessByType(SystemEventType type) {
3741
CriteriaBuilder cb = em.getCriteriaBuilder();
@@ -60,7 +64,7 @@ public void saveSystemEvent(SystemEventDto dto) {
6064

6165
}
6266

63-
private SystemEvent fromDto(@NotNull SystemEventDto source, SystemEvent target) {
67+
public SystemEvent fromDto(@NotNull SystemEventDto source, SystemEvent target) {
6468

6569
if (target == null) {
6670
target = new SystemEvent();
@@ -79,6 +83,33 @@ private SystemEvent fromDto(@NotNull SystemEventDto source, SystemEvent target)
7983

8084
}
8185

86+
@Override
87+
public void deleteAllDeletableSystemEvents(int daysAfterSystemEventGetsDeleted) {
88+
deleteAllDeletableSystemEvents(LocalDateTime.now().minusDays(daysAfterSystemEventGetsDeleted));
89+
}
90+
91+
public void deleteAllDeletableSystemEvents(LocalDateTime notChangedUntil) {
92+
93+
long startTime = DateHelper.startTime();
94+
95+
CriteriaBuilder cb = em.getCriteriaBuilder();
96+
CriteriaQuery<SystemEvent> cq = cb.createQuery(SystemEvent.class);
97+
Root<SystemEvent> systemEvent = cq.from(SystemEvent.class);
98+
99+
Timestamp notChangedTimestamp = Timestamp.valueOf(notChangedUntil);
100+
cq.where(cb.not(systemEventService.createChangeDateFilter(cb, systemEvent, notChangedTimestamp)));
101+
102+
List<SystemEvent> resultList = em.createQuery(cq).getResultList();
103+
for (SystemEvent event : resultList) {
104+
em.remove(event);
105+
}
106+
107+
logger.debug(
108+
"deleteAllDeletableSystemEvents() finished. systemEvent count = {}, {}ms",
109+
resultList.size(),
110+
DateHelper.durationMillies(startTime));
111+
}
112+
82113
@LocalBean
83114
@Stateless
84115
public static class SystemEventFacadeEjbLocal extends SystemEventFacadeEjb {

sormas-backend/src/test/java/de/symeda/sormas/backend/systemevent/SystemEventFacadeEjbTest.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,18 @@
55
import de.symeda.sormas.api.systemevents.SystemEventType;
66
import de.symeda.sormas.backend.AbstractBeanTest;
77
import de.symeda.sormas.backend.TestDataCreator;
8+
89
import org.junit.Test;
910

11+
import javax.persistence.criteria.CriteriaBuilder;
12+
import javax.persistence.criteria.CriteriaQuery;
13+
14+
import java.time.LocalDateTime;
1015
import java.util.Date;
16+
import java.util.List;
1117

1218
import static org.junit.Assert.assertEquals;
19+
import static org.junit.Assert.assertTrue;
1320

1421
public class SystemEventFacadeEjbTest extends AbstractBeanTest {
1522

@@ -32,4 +39,42 @@ public void testGetLatestSuccessByType() {
3239
assertEquals(intermediateDate, getSystemEventFacade().getLatestSuccessByType(SystemEventType.FETCH_LAB_MESSAGES));
3340
}
3441

42+
@Test
43+
public void testDeleteAllDeletableSystemEvents() throws InterruptedException {
44+
45+
LocalDateTime earliest = LocalDateTime.now();
46+
SystemEventDto systemEvent1 = creator.createSystemEvent(SystemEventType.FETCH_LAB_MESSAGES, new Date(), SystemEventStatus.ERROR);
47+
getSystemEventFacade().saveSystemEvent(systemEvent1);
48+
// Small delay for the persistence
49+
Thread.sleep(100L);
50+
51+
LocalDateTime inBetween = LocalDateTime.now();
52+
SystemEventDto systemEvent2 = creator.createSystemEvent(SystemEventType.FETCH_LAB_MESSAGES, new Date(), SystemEventStatus.SUCCESS);
53+
getSystemEventFacade().saveSystemEvent(systemEvent2);
54+
// Small delay for the persistence
55+
Thread.sleep(100L);
56+
57+
SystemEventFacadeEjb systemEventFacadeEjb = (SystemEventFacadeEjb) getSystemEventFacade();
58+
59+
systemEventFacadeEjb.deleteAllDeletableSystemEvents(earliest);
60+
assertTrue(getAllSystemEvents().size() == 2);
61+
62+
getSystemEventFacade().deleteAllDeletableSystemEvents(1);
63+
assertTrue(getAllSystemEvents().size() == 2);
64+
65+
systemEventFacadeEjb.deleteAllDeletableSystemEvents(inBetween);
66+
assertEquals(systemEventFacadeEjb.fromDto(systemEvent2, null), getAllSystemEvents().get(0));
67+
68+
getSystemEventFacade().deleteAllDeletableSystemEvents(-1);
69+
assertTrue(getAllSystemEvents().isEmpty());
70+
71+
}
72+
73+
private List<SystemEvent> getAllSystemEvents() {
74+
CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
75+
CriteriaQuery<SystemEvent> cq = cb.createQuery(SystemEvent.class);
76+
cq.from(SystemEvent.class);
77+
return getEntityManager().createQuery(cq).getResultList();
78+
}
79+
3580
}

sormas-base/setup/sormas.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ sms.auth.secret=
125125
# default: 90 (3 months)
126126
# daysAfterEventGetsArchived=
127127

128+
# Number of days after which a system event is automatically deleted
129+
# default: 90 (3 months)
130+
# daysAfterSystemEventGetsDeleted=
131+
128132
# Location of the Rscript executable. If specified, network diagrams will be enabled
129133
#rscript.executable=Rscript
130134

0 commit comments

Comments
 (0)