Skip to content

Commit d003d01

Browse files
committed
Feature #10786
Add the KmeliaBinsScheduledPurger to purge periodically the all the bins of the different Kmelia instances of the items (both publications and topics) that have been removed (place in the bin) at a date older than a given delay in days. The recurrence of the task and the delay are set in the org/silverpeas/kmelia/settings/kmeliaSettings.properties configuration file.
1 parent 25f315d commit d003d01

File tree

5 files changed

+215
-13
lines changed

5 files changed

+215
-13
lines changed

kmelia/kmelia-configuration/src/main/config/properties/org/silverpeas/kmelia/settings/kmeliaSettings.properties

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,16 @@ publications.sort.default = 2
111111
kmelia.stats.enable=false
112112
# The maximum number of elements retrieve for statistics purpose
113113
kmelia.stats.most.interested.query.limit=10
114+
115+
# The delay in days after which the topics and the publications in the bin of each kmelia instances
116+
# are definitively deleted. 0 to disable. If greater than 0, the automatic deletion has to be
117+
# then enabled for the bins to be clean out; for doing set a CRON value to the below property
118+
# kmelia.autoDeletionCron.
119+
kmelia.autoDeletionDelay = 0
120+
121+
# Cron to schedule the automatic deletion of old topics and publications in the bin of each
122+
# Kmelia instances. Empty to disable the scheduling (and hence the automatic deletion of older
123+
# items in the bins). If scheduling, the automatic deletion will be performed only if the property
124+
# kmelia.autoDeletionDelay is greater than 0.
125+
# If DeleteRemovedApplicationsDelay=0, the JOB is deactivated.
126+
kmelia.autoDeletionCron =

kmelia/kmelia-library/src/main/java/org/silverpeas/components/kmelia/service/DefaultKmeliaService.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@
173173
@Singleton
174174
@Named("kmeliaService")
175175
@Transactional(Transactional.TxType.SUPPORTS)
176-
public class DefaultKmeliaService implements KmeliaService {
176+
public class DefaultKmeliaService implements KmeliaService, KmeliaDeleter {
177177

178178
private static final String MESSAGES_PATH = "org.silverpeas.kmelia.multilang.kmeliaBundle";
179179
private static final String SETTINGS_PATH = "org.silverpeas.kmelia.settings.kmeliaSettings";
@@ -1382,7 +1382,8 @@ private boolean isClone(PublicationDetail publication) {
13821382
*
13831383
* @param pubPK the unique identifier of the publication to delete.
13841384
*/
1385-
private void deletePublication(PublicationPK pubPK) {
1385+
@Override
1386+
public void deletePublication(PublicationPK pubPK) {
13861387
KmeliaOperationContext.about(DELETION);
13871388
try {
13881389
// remove form content
@@ -1424,7 +1425,7 @@ private void sendPublicationInBasket(PublicationPK pubPK, boolean kmaxMode) {
14241425
}
14251426

14261427
// remove all links between this publication and topics
1427-
publicationService.removeAllFathers(pubPK);
1428+
publicationService.removeAllFathe<>rs(pubPK);
14281429
// add link between this publication and the basket topic
14291430
publicationService.addFather(pubPK, new NodePK(NodePK.BIN_NODE_ID, pubPK));
14301431

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
* Copyright (C) 2000 - 2025 Silverpeas
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License as
6+
* published by the Free Software Foundation, either version 3 of the
7+
* License, or (at your option) any later version.
8+
*
9+
* As a special exception to the terms and conditions of version 3.0 of
10+
* the GPL, you may redistribute this Program in connection with Free/Libre
11+
* Open Source Software ("FLOSS") applications as described in Silverpeas's
12+
* FLOSS exception. You should have received a copy of the text describing
13+
* the FLOSS exception, and it is also available here:
14+
* "https://www.silverpeas.org/legal/floss_exception.html"
15+
*
16+
* This program is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Affero General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU Affero General Public License
22+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
23+
*/
24+
25+
package org.silverpeas.components.kmelia.service;
26+
27+
import org.silverpeas.core.admin.component.model.WAComponent;
28+
import org.silverpeas.core.annotation.Service;
29+
import org.silverpeas.core.contribution.model.Contribution;
30+
import org.silverpeas.core.contribution.publication.service.PublicationService;
31+
import org.silverpeas.core.initialization.Initialization;
32+
import org.silverpeas.core.node.model.NodePK;
33+
import org.silverpeas.core.node.service.NodeService;
34+
import org.silverpeas.core.scheduler.Job;
35+
import org.silverpeas.core.scheduler.JobExecutionContext;
36+
import org.silverpeas.core.scheduler.Scheduler;
37+
import org.silverpeas.core.scheduler.SchedulerProvider;
38+
import org.silverpeas.core.scheduler.trigger.JobTrigger;
39+
import org.silverpeas.kernel.SilverpeasRuntimeException;
40+
import org.silverpeas.kernel.bundle.ResourceLocator;
41+
import org.silverpeas.kernel.bundle.SettingBundle;
42+
import org.silverpeas.kernel.logging.SilverLogger;
43+
44+
import javax.inject.Inject;
45+
import javax.transaction.Transactional;
46+
import java.time.LocalDate;
47+
import java.util.Date;
48+
49+
import static org.silverpeas.core.util.DateUtil.toLocalDate;
50+
51+
/**
52+
* A service scheduled in time to clean out periodically the bin in each Kmelia instances of the
53+
* items (both topics and publications) that have been removed since a given number of days. The
54+
* purge scheduling and the delay in days can be parameterized in the
55+
* <code>org/silverpeas/kmelia/settings/kmeliaSettings.properties</code> configuration file.
56+
*
57+
* @author mmoquillon
58+
*/
59+
@Service
60+
public class KmeliaBinsScheduledPurger implements Initialization {
61+
62+
private static final String COMPONENT_NAME = "kmelia";
63+
private static final String SETTINGS_NAME = "org.silverpeas.kmelia.settings.kmeliaSettings";
64+
private static final String JOB_NAME = "OldBinItemsDeleter";
65+
66+
@Inject
67+
private KmeliaDeleter deleter;
68+
@Inject
69+
private NodeService nodeService;
70+
@Inject
71+
private PublicationService publicationService;
72+
73+
@Override
74+
public void init() throws Exception {
75+
String cron = getSchedulingCron();
76+
if (!cron.isEmpty()) {
77+
final Scheduler scheduler = SchedulerProvider.getVolatileScheduler();
78+
scheduler.unscheduleJob(JOB_NAME);
79+
scheduler.scheduleJob(new OldBinItemsDeleter(), JobTrigger.triggerAt(cron));
80+
}
81+
new OldBinItemsDeleter().execute(JobExecutionContext.createWith(JOB_NAME, new Date()));
82+
}
83+
84+
@Override
85+
public void release() throws Exception {
86+
Scheduler scheduler = SchedulerProvider.getVolatileScheduler();
87+
if (scheduler.isJobScheduled(JOB_NAME)) {
88+
scheduler.unscheduleJob(JOB_NAME);
89+
}
90+
}
91+
92+
private String getSchedulingCron() {
93+
SettingBundle settings = ResourceLocator.getSettingBundle(SETTINGS_NAME);
94+
return settings.getString("kmelia.autoDeletionCron", "");
95+
}
96+
97+
private class OldBinItemsDeleter extends Job {
98+
99+
OldBinItemsDeleter() {
100+
super(JOB_NAME);
101+
}
102+
103+
@Transactional
104+
@Override
105+
public void execute(final JobExecutionContext context) {
106+
int delay = getDeletionDelay();
107+
if (delay > 0) {
108+
try {
109+
final LocalDate now = LocalDate.now();
110+
WAComponent.getByName(COMPONENT_NAME)
111+
.ifPresent(component ->
112+
component.getAllInstanceIds()
113+
.forEach(instanceId -> {
114+
NodePK bin = new NodePK(NodePK.BIN_NODE_ID, instanceId);
115+
nodeService.getChildrenDetails(bin).stream()
116+
.filter(node -> isOlder(node, now))
117+
.forEach(topic ->
118+
deleter.deleteTopic(topic.getNodePK()));
119+
publicationService.getDetailsByFatherPK(bin).stream()
120+
.filter(publication -> isOlder(publication, now))
121+
.forEach(publication ->
122+
deleter.deletePublication(publication.getPK()));
123+
}));
124+
125+
} catch (SilverpeasRuntimeException e) {
126+
SilverLogger.getLogger(this).error(e.getMessage(), e);
127+
}
128+
}
129+
}
130+
131+
private int getDeletionDelay() {
132+
SettingBundle settings = ResourceLocator.getSettingBundle(SETTINGS_NAME);
133+
int delay = settings.getInteger("kmelia.autoDeletionDelay", 0);
134+
return Math.max(delay, 0);
135+
}
136+
137+
private boolean isOlder(Contribution contribution, LocalDate date) {
138+
final LocalDate removeDayDateWithDelay = toLocalDate(contribution.getLastUpdateDate())
139+
.plusDays(getDeletionDelay());
140+
return removeDayDateWithDelay.isBefore(date) ||
141+
removeDayDateWithDelay.isEqual(date);
142+
}
143+
}
144+
}
145+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (C) 2000 - 2025 Silverpeas
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License as
6+
* published by the Free Software Foundation, either version 3 of the
7+
* License, or (at your option) any later version.
8+
*
9+
* As a special exception to the terms and conditions of version 3.0 of
10+
* the GPL, you may redistribute this Program in connection with Free/Libre
11+
* Open Source Software ("FLOSS") applications as described in Silverpeas's
12+
* FLOSS exception. You should have received a copy of the text describing
13+
* the FLOSS exception, and it is also available here:
14+
* "https://www.silverpeas.org/legal/floss_exception.html"
15+
*
16+
* This program is distributed in the hope that it will be useful,
17+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU Affero General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU Affero General Public License
22+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
23+
*/
24+
25+
package org.silverpeas.components.kmelia.service;
26+
27+
import org.silverpeas.core.contribution.publication.model.PublicationPK;
28+
import org.silverpeas.core.node.model.NodePK;
29+
30+
/**
31+
* Deleter of contributions managed in a Kmelia application.
32+
*
33+
* @author mmoquillon
34+
*/
35+
public interface KmeliaDeleter {
36+
37+
/**
38+
* Deletes definitively the specified topic and all descendants. Delete all links between
39+
* descendants and publications. Its publications will deleted. Delete All subscriptions and
40+
* favorites on its topics and all descendants
41+
*
42+
* @param pkToDelete the id of the topic to delete
43+
*/
44+
void deleteTopic(NodePK pkToDelete);
45+
46+
/**
47+
* Deletes definitively the specified publication.
48+
*
49+
* @param pubPK the unique identifier of the publication to delete.
50+
*/
51+
void deletePublication(PublicationPK pubPK);
52+
}
53+

kmelia/kmelia-library/src/main/java/org/silverpeas/components/kmelia/service/KmeliaService.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,6 @@ TopicDetail goTo(NodePK nodePK, String userId, boolean isTreeStructureUsed, Stri
124124
*/
125125
NodeDetail getSubTopicDetail(NodePK nodePK);
126126

127-
/**
128-
* Delete a topic and all descendants. Delete all links between descendants and publications. Its
129-
* publications will deleted. Delete All subscriptions and favorites on its topics and all
130-
* descendants
131-
*
132-
* @param nodePK the id of the topic to delete
133-
* @since 1.0
134-
*/
135-
void deleteTopic(NodePK nodePK);
136-
137127
void changeTopicStatus(String newStatus, NodePK nodePK, boolean recursiveChanges);
138128

139129
void sortSubTopics(NodePK fatherPK, boolean recursive, String[] criteria);

0 commit comments

Comments
 (0)