Skip to content

Commit efbe91a

Browse files
author
Emmanuel Hugonnet
committed
Bug #4666 : Technical error on delayed notification synthesis handling
- adding a unit test to verify delayed notification deletion performances - fixing a little inconsistency between JPA entity and JPA repository - passing to SQL/JPQL IN clause from batches of 5000 parameters to 500
1 parent 2a7b333 commit efbe91a

File tree

3 files changed

+148
-5
lines changed

3 files changed

+148
-5
lines changed

lib-core/src/main/java/com/silverpeas/notification/delayed/repository/DelayedNotificationRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* @author Yohann Chastagnier
3838
*/
3939
public interface DelayedNotificationRepository extends
40-
JpaRepository<DelayedNotificationData, Integer>, DelayedNotificationRepositoryCustom {
40+
JpaRepository<DelayedNotificationData, Long>, DelayedNotificationRepositoryCustom {
4141

4242
@Query("select distinct userId from DelayedNotificationData where channel in (:channels)")
4343
List<Integer> findAllUsersToBeNotified(@Param("channels") Collection<Integer> aimedChannels);

lib-core/src/main/java/com/silverpeas/util/CollectionUtil.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
*/
2424
package com.silverpeas.util;
2525

26+
import org.apache.commons.beanutils.NestedNullException;
27+
import org.apache.commons.beanutils.PropertyUtils;
28+
2629
import java.lang.reflect.InvocationTargetException;
2730
import java.util.ArrayList;
2831
import java.util.Arrays;
@@ -34,9 +37,6 @@
3437
import java.util.List;
3538
import java.util.Set;
3639

37-
import org.apache.commons.beanutils.NestedNullException;
38-
import org.apache.commons.beanutils.PropertyUtils;
39-
4040
/**
4141
* @author Yohann Chastagnier
4242
*/
@@ -72,7 +72,7 @@ public static <T> boolean isNotEmpty(final Collection<T> collection) {
7272
* @return
7373
*/
7474
public static <T> Collection<Collection<T>> split(final Collection<T> collection) {
75-
return split(collection, 5000);
75+
return split(collection, 500);
7676
}
7777

7878
/**
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* Copyright (C) 2000 - 2013 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 recieved a copy of the text describing
13+
* the FLOSS exception, and it is also available here:
14+
* "http://www.silverpeas.org/docs/core/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 <http://www.gnu.org/licenses/>.
23+
*/
24+
25+
/*
26+
* To change this template, choose Tools | Templates
27+
* and open the template in the editor.
28+
*/
29+
package com.silverpeas.notification.delayed;
30+
31+
import com.silverpeas.notification.delayed.model.DelayedNotificationData;
32+
import com.silverpeas.notification.model.NotificationResourceData;
33+
import com.stratelia.silverpeas.notificationManager.constant.NotifAction;
34+
import com.stratelia.silverpeas.notificationManager.constant.NotifChannel;
35+
import org.dbunit.database.DatabaseConnection;
36+
import org.dbunit.database.IDatabaseConnection;
37+
import org.dbunit.dataset.ReplacementDataSet;
38+
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
39+
import org.dbunit.operation.DatabaseOperation;
40+
import org.junit.Before;
41+
import org.junit.BeforeClass;
42+
import org.junit.Test;
43+
import org.junit.runner.RunWith;
44+
import org.springframework.test.context.ContextConfiguration;
45+
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
46+
import org.springframework.test.context.transaction.TransactionConfiguration;
47+
import org.springframework.transaction.annotation.Propagation;
48+
import org.springframework.transaction.annotation.Transactional;
49+
50+
import javax.inject.Inject;
51+
import javax.inject.Named;
52+
import javax.sql.DataSource;
53+
import java.math.BigDecimal;
54+
import java.util.ArrayList;
55+
import java.util.Collection;
56+
import java.util.logging.Level;
57+
import java.util.logging.Logger;
58+
59+
import static org.hamcrest.MatcherAssert.assertThat;
60+
import static org.hamcrest.Matchers.*;
61+
62+
@RunWith(SpringJUnit4ClassRunner.class)
63+
@ContextConfiguration(
64+
locations = {"/spring-delayed-notification.xml", "/spring-delayed-notification-datasource.xml"})
65+
@TransactionConfiguration(transactionManager = "jpaTransactionManager")
66+
public class DelayedNotificationManagerPerformanceTest {
67+
private static ReplacementDataSet dataSet;
68+
69+
Logger logger = Logger.getLogger(DelayedNotificationManagerPerformanceTest.class.getName());
70+
71+
public DelayedNotificationManagerPerformanceTest() {
72+
}
73+
74+
@BeforeClass
75+
public static void prepareDataSet() throws Exception {
76+
final FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
77+
dataSet = new ReplacementDataSet(builder.build(DelayedNotificationManagerPerformanceTest.class.
78+
getResourceAsStream("delayed-notification-dataset.xml")));
79+
dataSet.addReplacementObject("[NULL]", null);
80+
}
81+
82+
@Inject
83+
private DelayedNotification manager;
84+
@Inject
85+
@Named("jpaDataSource")
86+
private DataSource dataSource;
87+
88+
@Before
89+
public void generalSetUp() throws Exception {
90+
final IDatabaseConnection myConnection = new DatabaseConnection(dataSource.getConnection());
91+
DatabaseOperation.CLEAN_INSERT.execute(myConnection, dataSet);
92+
}
93+
94+
@Transactional(propagation = Propagation.REQUIRED)
95+
@Test
96+
public void testDeleteDelayedNotifications() throws Exception {
97+
Collection<Long> ids = loadDelayedNorifications(1000);
98+
99+
long start = System.currentTimeMillis();
100+
assertThat(manager.deleteDelayedNotifications(ids), is(1000));
101+
long end = System.currentTimeMillis();
102+
103+
logger.log(Level.INFO, "Deleting delayed notifications in {0} milliseconds.",
104+
new BigDecimal(String.valueOf(end - start)));
105+
}
106+
107+
@Transactional(propagation = Propagation.REQUIRES_NEW)
108+
public Collection<Long> loadDelayedNorifications(int size) {
109+
NotificationResourceData notificationResourceData =
110+
manager.getExistingResource("100", "publication", "aComponentInstanceId");
111+
112+
// 10000
113+
long start = System.currentTimeMillis();
114+
Collection<Long> result = new ArrayList<Long>(size);
115+
for (long i = 0; i < size; i++) {
116+
DelayedNotificationData data = buildDelayedNotificationData(notificationResourceData);
117+
assertThat(data.getId(), nullValue());
118+
manager.saveDelayedNotification(data);
119+
assertThat(data.getId(), notNullValue());
120+
result.add(data.getId());
121+
}
122+
long end = System.currentTimeMillis();
123+
124+
logger.log(Level.INFO, "Loading database in {0} seconds.",
125+
new BigDecimal(String.valueOf(end - start))
126+
.divide(new BigDecimal("1000"), 2, BigDecimal.ROUND_HALF_DOWN));
127+
128+
return result;
129+
}
130+
131+
private static DelayedNotificationData buildDelayedNotificationData(
132+
NotificationResourceData notificationResourceData) {
133+
final DelayedNotificationData data = new DelayedNotificationData();
134+
data.setUserId(26);
135+
data.setFromUserId(38);
136+
data.setChannel(NotifChannel.SMTP);
137+
data.setAction(NotifAction.CREATE);
138+
data.setResource(notificationResourceData);
139+
data.setLanguage("fr");
140+
data.setMessage("Ceci est un message !");
141+
return data;
142+
}
143+
}

0 commit comments

Comments
 (0)