1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.krad.service;
17
18 import org.apache.commons.lang.StringUtils;
19 import org.junit.Test;
20 import org.kuali.rice.kew.api.exception.WorkflowException;
21 import org.kuali.rice.kim.api.KimConstants.PermissionNames;
22 import org.kuali.rice.kim.api.identity.Person;
23 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
24 import org.kuali.rice.kns.authorization.AuthorizationConstants;
25 import org.kuali.rice.krad.UserSession;
26 import org.kuali.rice.krad.document.Document;
27 import org.kuali.rice.krad.maintenance.MaintenanceDocument;
28 import org.kuali.rice.krad.document.authorization.PessimisticLock;
29 import org.kuali.rice.krad.exception.AuthorizationException;
30 import org.kuali.rice.krad.service.impl.PessimisticLockServiceImpl;
31 import org.kuali.rice.krad.test.document.AccountRequestDocument;
32 import org.kuali.rice.krad.test.document.AccountRequestDocument2;
33 import org.kuali.rice.krad.util.GlobalVariables;
34 import org.kuali.rice.krad.util.KRADConstants;
35 import org.kuali.rice.krad.util.KRADPropertyConstants;
36 import org.kuali.rice.test.BaselineTestCase;
37 import org.kuali.rice.test.data.UnitTestData;
38 import org.kuali.rice.test.data.UnitTestSql;
39 import org.kuali.rice.krad.test.KRADTestCase;
40
41 import java.io.Serializable;
42 import java.util.ArrayList;
43 import java.util.Arrays;
44 import java.util.Collections;
45 import java.util.HashMap;
46 import java.util.HashSet;
47 import java.util.List;
48 import java.util.Map;
49 import java.util.Set;
50
51 import static org.junit.Assert.*;
52
53
54
55
56
57
58
59 @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.NONE)
60 public class PessimisticLockServiceTest extends KRADTestCase {
61
62 String sessionId = "ad4d6c83-4d0f-4309-a528-c2f81ec00396";
63
64 @Override
65 public void setUp() throws Exception {
66 super.setUp();
67 GlobalVariables.setUserSession(new UserSession("quickstart"));
68 GlobalVariables.getUserSession().setKualiSessionId(sessionId);
69 }
70
71
72
73
74
75
76
77 @UnitTestData(
78 sqlStatements = {
79 @UnitTestSql("DELETE FROM KRNS_PESSIMISTIC_LOCK_T"),
80 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1111, '4f6bc9e2-7df8-102c-97b6-ed716fdaf540', 0, NULL, '1234', {d '2007-07-01'}, 'employee', 'aa5d6c83-4d0f-4309-a528-c2f81ec00396')"),
81 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1112, '5add9cba-7df8-102c-97b6-ed716fdaf540', 0, NULL, '1235', {d '2007-10-01'}, 'frank', 'dd4d6c83-4d0f-4309-a528-c2f81ec00396')"),
82 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1113, '69e42b8e-7df8-102c-97b6-ed716fdaf540', 0, NULL, '1236', {d '2007-08-01'}, 'fred', 'ad4d6c83-4d0f-4309-a528-c2f81ec00396')"),
83 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1114, '76504650-7df8-102c-97b6-ed716fdaf540', 0, NULL, '1237', {d '2007-08-01'}, 'fred', 'ad4d6c83-4d0f-4309-a528-c2f81ec00396')")
84 }
85 )
86 @Test
87 public void testDeleteLocks() throws Exception {
88
89 List<PessimisticLock> locks = (List<PessimisticLock>) KRADServiceLocator.getBusinessObjectService().findAll(PessimisticLock.class);
90 assertEquals("Should be 4 locks in DB", 4, locks.size());
91
92 String userId = "employee";
93 String[] lockIdsToVerify = new String[]{"1112", "1113"};
94 assertFalse("User " + userId + " should not be member of pessimistic lock admin permission", KimApiServiceLocator.getPermissionService().isAuthorized(new UserSession(userId).getPerson().getPrincipalId(), KRADConstants.KNS_NAMESPACE, PermissionNames.ADMIN_PESSIMISTIC_LOCKING,
95 Collections.<String, String>emptyMap() ) );
96 verifyDelete(userId, Arrays.asList(lockIdsToVerify), AuthorizationException.class, true);
97 userId = "frank";
98 lockIdsToVerify = new String[]{"1111", "1113"};
99 assertFalse("User " + userId + " should not be member of pessimistic lock admin permission", KimApiServiceLocator.getPermissionService().isAuthorized(new UserSession(userId).getPerson().getPrincipalId(), KRADConstants.KNS_NAMESPACE, PermissionNames.ADMIN_PESSIMISTIC_LOCKING, Collections.<String, String>emptyMap() ) );
100 verifyDelete(userId, Arrays.asList(lockIdsToVerify), AuthorizationException.class, true);
101 userId = "fred";
102 lockIdsToVerify = new String[]{"1111", "1112"};
103 assertFalse("User " + userId + " should not be member of pessimistic lock admin permission", KimApiServiceLocator.getPermissionService().isAuthorized(new UserSession(userId).getPerson().getPrincipalId(), KRADConstants.KNS_NAMESPACE, PermissionNames.ADMIN_PESSIMISTIC_LOCKING, Collections.<String, String>emptyMap() ) );
104 verifyDelete(userId, Arrays.asList(lockIdsToVerify), AuthorizationException.class, true);
105
106 verifyDelete("employee", Arrays.asList(new String[]{"1111"}), null, false);
107 verifyDelete("frank", Arrays.asList(new String[]{"1112"}), null, false);
108 verifyDelete("fred", Arrays.asList(new String[]{"1113"}), null, false);
109 locks = (List<PessimisticLock>) KRADServiceLocator.getBusinessObjectService().findAll(PessimisticLock.class);
110 assertEquals("Should be 1 lock left in DB", 1, locks.size());
111
112
113 userId = "fran";
114 assertTrue("User " + userId + " should be member of pessimistic lock admin permission", KimApiServiceLocator.getPermissionService().isAuthorized(new UserSession(userId).getPerson().getPrincipalId(), KRADConstants.KNS_NAMESPACE, PermissionNames.ADMIN_PESSIMISTIC_LOCKING, Collections.<String, String>emptyMap() ) );
115 userId = "admin";
116 assertTrue("User " + userId + " should be member of pessimistic lock admin permission", KimApiServiceLocator.getPermissionService().isAuthorized(new UserSession(userId).getPerson().getPrincipalId(), KRADConstants.KNS_NAMESPACE, PermissionNames.ADMIN_PESSIMISTIC_LOCKING, Collections.<String, String>emptyMap() ) );
117 verifyDelete(userId, Arrays.asList(new String[]{"1114"}), null, false);
118 locks = (List<PessimisticLock>) KRADServiceLocator.getBusinessObjectService().findAll(PessimisticLock.class);
119 assertEquals("Should be 0 locks left in DB", 0, locks.size());
120 }
121
122
123
124
125
126
127
128
129
130
131
132 private void verifyDelete(String userId, List<String> lockIds, Class expectedException, boolean expectException) throws WorkflowException {
133 GlobalVariables.setUserSession(new UserSession(userId));
134 for (String lockId : lockIds) {
135 try {
136 KRADServiceLocatorWeb.getPessimisticLockService().delete(lockId);
137 if (expectException) {
138 fail("Expected exception when deleting lock with id '" + lockId + "' for user '" + userId + "'");
139 }
140 } catch (Exception e) {
141 if (!expectException) {
142 fail("Did not expect exception when deleting lock with id '" + lockId + "' for user '" + userId + "' but got exception of type '" + e.getClass().getName() + "'");
143 }
144 if (expectedException != null) {
145
146 if (!expectedException.isAssignableFrom(e.getClass())) {
147 fail("Expected exception of type '" + expectedException.getName() + "' when deleting lock with id '" + lockId + "' for user '" + userId + "' but got exception of type '" + e.getClass().getName() + "'");
148 }
149 }
150 }
151 }
152 }
153
154
155
156
157
158
159 @Test
160 public void testGenerateNewLocks() throws Exception {
161 PessimisticLockService lockService = KRADServiceLocatorWeb.getPessimisticLockService();
162
163
164 String documentNumber = "1243";
165 PessimisticLock lock = lockService.generateNewLock(documentNumber);
166 assertNotNull("Generated lock should have id", lock.getId());
167 assertEquals("Document Number should match", documentNumber, lock.getDocumentNumber());
168 assertNotNull("Generated lock should have a generated timestamp ", lock.getGeneratedTimestamp());
169 assertEquals("Generated lock should have default lock descriptor", PessimisticLock.DEFAULT_LOCK_DESCRIPTOR, lock.getLockDescriptor());
170 assertEquals("Generated lock should be owned by current user", GlobalVariables.getUserSession().getPerson().getPrincipalName(), lock.getOwnedByUser().getPrincipalName());
171 Map primaryKeys = new HashMap();
172 primaryKeys.put(KRADPropertyConstants.ID, lock.getId());
173 lock = null;
174 lock = (PessimisticLock) KRADServiceLocator.getBusinessObjectService().findByPrimaryKey(PessimisticLock.class, primaryKeys);
175 assertNotNull("Generated lock should be available from BO Service", lock);
176 assertNotNull("Generated lock should have id", lock.getId());
177 assertEquals("Document Number should match", documentNumber, lock.getDocumentNumber());
178 assertNotNull("Generated lock should have a generated timestamp ", lock.getGeneratedTimestamp());
179 assertEquals("Generated lock should have default lock descriptor", PessimisticLock.DEFAULT_LOCK_DESCRIPTOR, lock.getLockDescriptor());
180 assertEquals("Generated lock should be owned by current user", GlobalVariables.getUserSession().getPerson().getPrincipalName(), lock.getOwnedByUser().getPrincipalName());
181
182
183 lock = null;
184 documentNumber = "4321";
185 String lockDescriptor = "this is a test lock descriptor";
186 lock = lockService.generateNewLock(documentNumber, lockDescriptor);
187 assertNotNull("Generated lock should have id", lock.getId());
188 assertEquals("Document Number should match", documentNumber, lock.getDocumentNumber());
189 assertNotNull("Generated lock should have a generated timestamp ", lock.getGeneratedTimestamp());
190 assertEquals("Generated lock should have lock descriptor set", lockDescriptor, lock.getLockDescriptor());
191 assertEquals("Generated lock should be owned by current user", GlobalVariables.getUserSession().getPerson().getPrincipalName(), lock.getOwnedByUser().getPrincipalName());
192 primaryKeys = new HashMap();
193 primaryKeys.put(KRADPropertyConstants.ID, lock.getId());
194 lock = null;
195 lock = (PessimisticLock) KRADServiceLocator.getBusinessObjectService().findByPrimaryKey(PessimisticLock.class, primaryKeys);
196 assertNotNull("Generated lock should be available from BO Service", lock);
197 assertNotNull("Generated lock should have id", lock.getId());
198 assertEquals("Document Number should match", documentNumber, lock.getDocumentNumber());
199 assertNotNull("Generated lock should have a generated timestamp ", lock.getGeneratedTimestamp());
200 assertEquals("Generated lock should have lock descriptor set", lockDescriptor, lock.getLockDescriptor());
201 assertEquals("Generated lock should be owned by current user", GlobalVariables.getUserSession().getPerson().getPrincipalName(), lock.getOwnedByUser().getPrincipalName());
202 }
203
204
205
206
207
208
209 @UnitTestData(
210 sqlStatements = {
211 @UnitTestSql("DELETE FROM KRNS_PESSIMISTIC_LOCK_T"),
212 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1111, 'fbcb0362-7dfb-102c-97b6-ed716fdaf540', 0, NULL, '1234', {d '2007-07-01'}, 'fran', 'aa5d6c83-4d0f-4309-a528-c2f81ec00396')"),
213 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1112, '055bef4a-7dfc-102c-97b6-ed716fdaf540', 0, NULL, '1237', {d '2007-10-01'}, 'frank', 'dd5d6c83-4d0f-4309-a528-c2f81ec00396')"),
214 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1113, '0e0144ec-7dfc-102c-97b6-ed716fdaf540', 0, NULL, '1236', {d '2007-10-01'}, 'frank', 'dd5d6c83-4d0f-4309-a528-c2f81ec00396')"),
215 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1114, '1891526c-7dfc-102c-97b6-ed716fdaf540', 0, NULL, '1237', {d '2007-08-01'}, 'fred', 'ab4d6c83-4d0f-4309-a528-c2f81ec00396')")
216 }
217 )
218 @Test
219 public void testGetPessimisticLocksForDocument() throws Exception {
220 PessimisticLockService lockService = KRADServiceLocatorWeb.getPessimisticLockService();
221 String docId = "1234";
222 assertEquals("Document " + docId + " expected lock count incorrect", 1, lockService.getPessimisticLocksForDocument(docId).size());
223 docId = "1237";
224 assertEquals("Document " + docId + " expected lock count incorrect", 2, lockService.getPessimisticLocksForDocument(docId).size());
225 docId = "1236";
226 assertEquals("Document " + docId + " expected lock count incorrect", 1, lockService.getPessimisticLocksForDocument(docId).size());
227 docId = "3948";
228 assertEquals("Document " + docId + " expected lock count incorrect", 0, lockService.getPessimisticLocksForDocument(docId).size());
229 }
230
231
232
233
234
235
236 @UnitTestData(
237 sqlStatements = {
238 @UnitTestSql("DELETE FROM KRNS_PESSIMISTIC_LOCK_T"),
239 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1111, '24c40cd2-7dfc-102c-97b6-ed716fdaf540', 0, NULL, '1234', {d '2007-07-01'}, 'fran', 'ad4d6c83-4d0f-4309-a528-c2f81ec00396')"),
240 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1112, '32602e8e-7dfc-102c-97b6-ed716fdaf540', 0, NULL, '1235', {d '2007-10-01'}, 'fran', 'bc5d6c66-4d0f-4309-a528-c2f81ec00396')"),
241 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1113, '3acfc1ce-7dfc-102c-97b6-ed716fdaf540', 0, NULL, '1236', {d '2007-10-01'}, 'fran', 'ad4d6c83-4d0f-4309-a528-c2f81ec00396')"),
242 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1114, '463cc642-7dfc-102c-97b6-ed716fdaf540', 0, NULL, '1237', {d '2007-08-01'}, 'fran', 'bc5d6c66-4d0f-4309-a528-c2f81ec00396')")
243 }
244 )
245 @Test
246 public void testGetPessimisticLocksForSession() throws Exception {
247 List<PessimisticLock> locks = KRADServiceLocatorWeb.getPessimisticLockService().getPessimisticLocksForSession(sessionId);
248 assertEquals("Should return 2 locks for session " + sessionId, 2, locks.size());
249
250 ArrayList<String> documentNumbers = new ArrayList<String>();
251 for (PessimisticLock lock : locks) {
252 documentNumbers.add(lock.getDocumentNumber());
253 }
254 assertTrue("Locks should contain a lock for document number 1234 but contained " + documentNumbers, documentNumbers.contains("1234"));
255 assertTrue("Locks should contain a lock for document number 1236 but contained " + documentNumbers, documentNumbers.contains("1236"));
256 }
257
258
259
260
261
262
263 @UnitTestData(
264 sqlStatements = {
265 @UnitTestSql("DELETE FROM KRNS_PESSIMISTIC_LOCK_T"),
266 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1111, '24c40cd2-7dfc-102c-97b6-ed716fdaf540', 0, NULL, '1234', {d '2007-07-01'}, 'fran', 'ad4d6c83-4d0f-4309-a528-c2f81ec00396')"),
267 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1112, '32602e8e-7dfc-102c-97b6-ed716fdaf540', 0, NULL, '1235', {d '2007-10-01'}, 'frank', 'bc5d6c66-4d0f-4309-a528-c2f81ec00396')"),
268 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1113, '3acfc1ce-7dfc-102c-97b6-ed716fdaf540', 0, NULL, '1236', {d '2007-10-01'}, 'frank', 'bc5d6c66-4d0f-4309-a528-c2f81ec00396')"),
269 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1114, '463cc642-7dfc-102c-97b6-ed716fdaf540', 0, NULL, '1237', {d '2007-08-01'}, 'fred', 'dd5d6c66-4d0f-4309-a528-c2f81ec00396')"),
270 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1115, '4e66c4b2-7dfc-102c-97b6-ed716fdaf540', 0, 'Temporary Lock', '1234', {d '2007-07-01'}, 'fran', 'ad4d6c83-4d0f-4309-a528-c2f81ec00396')"),
271 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1116, '55d99b02-7dfc-102c-97b6-ed716fdaf540', 0, 'Temporary Lock', '1235', {d '2007-10-01'}, 'frank', 'bc5d6c66-4d0f-4309-a528-c2f81ec00396')"),
272 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1117, '5e47fb26-7dfc-102c-97b6-ed716fdaf540', 0, 'Temporary Lock', '1236', {d '2007-10-01'}, 'frank', 'bc5d6c66-4d0f-4309-a528-c2f81ec00396')"),
273 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1118, '65c366d8-7dfc-102c-97b6-ed716fdaf540', 0, 'Temporary Lock', '1237', {d '2007-08-01'}, 'fred', 'dd5d6c66-4d0f-4309-a528-c2f81ec00396')")
274 }
275 )
276 @Test
277 public void testReleaseAllLocksForUser() throws Exception {
278 String lockDescriptor = "Temporary Lock";
279 List<PessimisticLock> locks = (List<PessimisticLock>) KRADServiceLocator.getBusinessObjectService().findAll(PessimisticLock.class);
280 assertEquals("Should be 8 manually inserted locks", 8, locks.size());
281
282 KRADServiceLocatorWeb.getPessimisticLockService().releaseAllLocksForUser(locks, KimApiServiceLocator.getPersonService().getPerson("fran"), lockDescriptor);
283 locks = (List<PessimisticLock>) KRADServiceLocator.getBusinessObjectService().findAll(PessimisticLock.class);
284 assertEquals("Should be 7 locks left after releasing locks for fran using lock descriptor " + lockDescriptor, 7, locks.size());
285
286 KRADServiceLocatorWeb.getPessimisticLockService().releaseAllLocksForUser(locks, KimApiServiceLocator.getPersonService().getPerson("frank"), lockDescriptor);
287 locks = (List<PessimisticLock>) KRADServiceLocator.getBusinessObjectService().findAll(PessimisticLock.class);
288 assertEquals("Should be 5 locks left after releasing locks for fran and frank using lock descriptor " + lockDescriptor, 5, locks.size());
289
290 KRADServiceLocatorWeb.getPessimisticLockService().releaseAllLocksForUser(locks, KimApiServiceLocator.getPersonService().getPerson("fred"), lockDescriptor);
291 locks = (List<PessimisticLock>) KRADServiceLocator.getBusinessObjectService().findAll(PessimisticLock.class);
292 assertEquals("Should be 4 locks left after releasing locks for fran, frank, and fred using lock descriptor " + lockDescriptor, 4, locks.size());
293
294 KRADServiceLocatorWeb.getPessimisticLockService().releaseAllLocksForUser(locks, KimApiServiceLocator.getPersonService().getPerson("fran"));
295 locks = (List<PessimisticLock>) KRADServiceLocator.getBusinessObjectService().findAll(PessimisticLock.class);
296 assertEquals("Should be 3 locks left after releasing locks for fran with no lock descriptor", 3, locks.size());
297
298 KRADServiceLocatorWeb.getPessimisticLockService().releaseAllLocksForUser(locks, KimApiServiceLocator.getPersonService().getPerson("frank"));
299 locks = (List<PessimisticLock>) KRADServiceLocator.getBusinessObjectService().findAll(PessimisticLock.class);
300 assertEquals("Should be 1 lock left after releasing locks for fran and frank with no lock descriptor", 1, locks.size());
301
302 KRADServiceLocatorWeb.getPessimisticLockService().releaseAllLocksForUser(locks, KimApiServiceLocator.getPersonService().getPerson("fred"));
303 locks = (List<PessimisticLock>) KRADServiceLocator.getBusinessObjectService().findAll(PessimisticLock.class);
304 assertEquals("Should be no locks left after releasing locks for fran, frank, and fred with no lock descriptor", 0, locks.size());
305 }
306
307
308
309
310
311
312 @UnitTestData(
313 sqlStatements = {
314 @UnitTestSql("DELETE FROM KRNS_PESSIMISTIC_LOCK_T"),
315 @UnitTestSql("INSERT INTO KRNS_PESSIMISTIC_LOCK_T (PESSIMISTIC_LOCK_ID,OBJ_ID,VER_NBR,LOCK_DESC_TXT,DOC_HDR_ID,GNRT_DT,PRNCPL_ID,SESN_ID) VALUES (1111, '73f340de-7dfc-102c-97b6-ed716fdaf540', 0, NULL, '1234', {d '2007-07-01'}, 'fran', 'ad4d6c83-4d0f-4309-a528-c2f81ec00396')")
316 }
317 )
318 @Test
319 public void testSaveLock() throws Exception {
320 String lockDescriptor = "new test lock descriptor";
321
322 Map primaryKeys = new HashMap();
323 primaryKeys.put(KRADPropertyConstants.ID, Long.valueOf("1111"));
324 PessimisticLock lock = (PessimisticLock) KRADServiceLocator.getBusinessObjectService().findByPrimaryKey(PessimisticLock.class, primaryKeys);
325 lock.setLockDescriptor(lockDescriptor);
326 KRADServiceLocatorWeb.getPessimisticLockService().save(lock);
327
328
329 PessimisticLock savedLock = (PessimisticLock) KRADServiceLocator.getBusinessObjectService().findByPrimaryKey(PessimisticLock.class, primaryKeys);
330 assertEquals("Lock descriptor is not correct from lock that was saved", lockDescriptor, savedLock.getLockDescriptor());
331 }
332
333
334
335
336
337
338 @Test
339 public void testEstablishLocks() throws Exception {
340 PessimisticLockService lockService = KRADServiceLocatorWeb.getPessimisticLockService();
341 AccountRequestDocument accountDoc = (AccountRequestDocument) KRADServiceLocatorWeb.getDocumentService().getNewDocument("AccountRequest");
342
343 assertTrue("The AccountRequestDocument should be using pessimistic locking",
344 KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getDocumentEntry(accountDoc.getClass().getName()).getUsePessimisticLocking());
345
346
347 UserSession quickstartSession = new UserSession("quickstart");
348 Person[] quickstartPerson = { quickstartSession.getPerson() };
349 Map<String,String> editMode = new HashMap<String,String>();
350 editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
351 Map <?,?> finalModes = lockService.establishLocks(accountDoc, editMode, quickstartSession.getPerson());
352
353
354 assertCorrectLocksAreInPlace(true, finalModes, 1, accountDoc.getPessimisticLocks(), quickstartPerson, null);
355
356
357 UserSession adminSession = new UserSession("admin");
358 Set<String> documentActions = new HashSet<String>(Arrays.asList(new String[] { KRADConstants.KUALI_ACTION_CAN_CANCEL,
359 KRADConstants.KUALI_ACTION_CAN_SAVE, KRADConstants.KUALI_ACTION_CAN_ROUTE, KRADConstants.KUALI_ACTION_CAN_BLANKET_APPROVE }));
360 Set<?> finalActions = lockService.getDocumentActions(accountDoc, adminSession.getPerson(), documentActions);
361 assertFalse("'admin' should not be able to cancel the locked document", finalActions.contains(KRADConstants.KUALI_ACTION_CAN_CANCEL));
362 assertFalse("'admin' should not be able to save the locked document", finalActions.contains(KRADConstants.KUALI_ACTION_CAN_SAVE));
363 assertFalse("'admin' should not be able to route the locked document", finalActions.contains(KRADConstants.KUALI_ACTION_CAN_ROUTE));
364 assertFalse("'admin' should not be able to blanket approve the locked document", finalActions.contains(KRADConstants.KUALI_ACTION_CAN_BLANKET_APPROVE));
365
366
367 documentActions = new HashSet<String>(Arrays.asList(new String[] {
368 KRADConstants.KUALI_ACTION_CAN_CANCEL, KRADConstants.KUALI_ACTION_CAN_SAVE, KRADConstants.KUALI_ACTION_CAN_ROUTE }));
369 finalActions = lockService.getDocumentActions(accountDoc, quickstartSession.getPerson(), documentActions);
370 assertTrue("'quickstart' should have had cancel privileges", finalActions.contains(KRADConstants.KUALI_ACTION_CAN_CANCEL));
371 assertTrue("'quickstart' should have had save privileges", finalActions.contains(KRADConstants.KUALI_ACTION_CAN_SAVE));
372 assertTrue("'quickstart' should have had route privileges", finalActions.contains(KRADConstants.KUALI_ACTION_CAN_ROUTE));
373
374
375 editMode = new HashMap<String,String>();
376 editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
377 finalModes = lockService.establishLocks(accountDoc, editMode, adminSession.getPerson());
378 assertCorrectLocksAreInPlace(false, finalModes, 1, accountDoc.getPessimisticLocks(), quickstartPerson, null);
379
380
381 editMode = new HashMap<String,String>();
382 editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
383 finalModes = lockService.establishLocks(accountDoc, editMode, quickstartSession.getPerson());
384 assertCorrectLocksAreInPlace(true, finalModes, 1, accountDoc.getPessimisticLocks(), quickstartPerson, null);
385 }
386
387
388
389
390
391
392 @Test
393 public void testWorkflowPessimisticLocking() throws Exception {
394 PessimisticLockService lockService = KRADServiceLocatorWeb.getPessimisticLockService();
395 AccountRequestDocument accountDoc = (AccountRequestDocument) KRADServiceLocatorWeb.getDocumentService().getNewDocument("AccountRequest");
396 assertTrue("The AccountRequestDocument should be using pessimistic locking",
397 KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getDocumentEntry(accountDoc.getClass().getName()).getUsePessimisticLocking());
398
399
400 UserSession systemSession = new UserSession(KRADConstants.SYSTEM_USER);
401 Person[] systemPerson = { systemSession.getPerson() };
402 lockService.establishWorkflowPessimisticLocking(accountDoc);
403 assertCorrectLocksAreInPlace(false, null, 1, accountDoc.getPessimisticLocks(), systemPerson, null);
404
405
406 UserSession adminSession = new UserSession("admin");
407 Map<String,String> editMode = new HashMap<String,String>();
408 editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
409 Map<?,?> finalModes = lockService.establishLocks(accountDoc, editMode, adminSession.getPerson());
410 assertCorrectLocksAreInPlace(false, finalModes, 1, accountDoc.getPessimisticLocks(), systemPerson, null);
411
412
413 lockService.releaseWorkflowPessimisticLocking(accountDoc);
414 assertTrue("There should not be any pessimistic locks present on the document", accountDoc.getPessimisticLocks().isEmpty());
415 }
416
417
418
419
420
421
422 @Test
423 public void testPessimisticLockingWithCustomDocumentLockDescriptors() throws Exception {
424 AccountRequestDocument2 accountDoc2 = (AccountRequestDocument2) KRADServiceLocatorWeb.getDocumentService().getNewDocument("AccountRequest2");
425 assertTrue("The AccountRequestDocument2 should be using pessimistic locking", KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary(
426 ).getDocumentEntry(accountDoc2.getClass().getName()).getUsePessimisticLocking());
427 assertTrue("The AccountRequestDocument2 should be using custom lock descriptors", accountDoc2.useCustomLockDescriptors());
428
429
430 assertCustomLockDescriptorsAreWorking(accountDoc2, AccountRequestDocument2.ACCT_REQ_DOC_2_EDITABLE_FIELDS,
431 AccountRequestDocument2.EDIT_ALL_BUT_REASONS, AccountRequestDocument2.EDIT_REASONS_ONLY);
432 }
433
434
435
436
437
438
439
440
441
442
443
444 private void assertCustomLockDescriptorsAreWorking(Document testDoc, final String LOCK_KEY, final Serializable LOCK_VALUE1,
445 final Serializable LOCK_VALUE2) throws Exception {
446 PessimisticLockService lockService = KRADServiceLocatorWeb.getPessimisticLockService();
447
448
449 UserSession quickstartSession = new UserSession("quickstart");
450 Person[] allPersons = { quickstartSession.getPerson(), null };
451 Map<String,String> editMode = new HashMap<String,String>();
452 editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
453 GlobalVariables.getUserSession().addObject(LOCK_KEY, LOCK_VALUE1);
454 String[] allDescriptors = { testDoc.getCustomLockDescriptor(quickstartSession.getPerson()), null };
455 assertNotNull("The document should have generated a custom lock descriptor", allDescriptors[0]);
456 Map <?,?> finalModes = lockService.establishLocks(testDoc, editMode, quickstartSession.getPerson());
457
458
459 assertCorrectLocksAreInPlace(true, finalModes, 1, testDoc.getPessimisticLocks(), allPersons, allDescriptors);
460
461
462 editMode = new HashMap<String,String>();
463 editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
464 GlobalVariables.getUserSession().addObject(LOCK_KEY, LOCK_VALUE1);
465 lockService.establishLocks(testDoc, editMode, quickstartSession.getPerson());
466 assertCorrectLocksAreInPlace(false, null, 1, testDoc.getPessimisticLocks(), allPersons, allDescriptors);
467
468
469 UserSession adminSession = new UserSession("admin");
470 editMode = new HashMap<String,String>();
471 editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
472 GlobalVariables.getUserSession().addObject(LOCK_KEY, LOCK_VALUE1);
473 assertEquals("The document should have generated the same lock descriptors for both 'quickstart' and 'admin'",
474 allDescriptors[0], testDoc.getCustomLockDescriptor(adminSession.getPerson()));
475 finalModes = lockService.establishLocks(testDoc, editMode, adminSession.getPerson());
476 assertCorrectLocksAreInPlace(false, finalModes, 1, testDoc.getPessimisticLocks(), allPersons, allDescriptors);
477
478
479 allPersons[1] = adminSession.getPerson();
480 editMode = new HashMap<String,String>();
481 editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
482 GlobalVariables.getUserSession().addObject(LOCK_KEY, LOCK_VALUE2);
483 allDescriptors[1] = testDoc.getCustomLockDescriptor(adminSession.getPerson());
484 assertNotNull("The document should have generated a custom lock descriptor", allDescriptors[1]);
485 assertNotSame("'quickstart' and 'admin' should have different custom lock descriptors now", allDescriptors[0], allDescriptors[1]);
486 finalModes = lockService.establishLocks(testDoc, editMode, adminSession.getPerson());
487 assertCorrectLocksAreInPlace(true, finalModes, 2, testDoc.getPessimisticLocks(), allPersons, allDescriptors);
488
489
490 editMode = new HashMap<String,String>();
491 editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
492 GlobalVariables.getUserSession().addObject(LOCK_KEY, LOCK_VALUE2);
493 lockService.establishLocks(testDoc, editMode, quickstartSession.getPerson());
494 assertCorrectLocksAreInPlace(false, null, 2, testDoc.getPessimisticLocks(), allPersons, allDescriptors);
495
496
497 lockService.releaseAllLocksForUser(testDoc.getPessimisticLocks(), allPersons[1], allDescriptors[1]);
498 testDoc.refreshPessimisticLocks();
499 assertCorrectLocksAreInPlace(false, null, 1, testDoc.getPessimisticLocks(), allPersons, allDescriptors);
500 allPersons[1] = allPersons[0];
501 editMode = new HashMap<String,String>();
502 editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
503 GlobalVariables.getUserSession().addObject(LOCK_KEY, LOCK_VALUE2);
504 finalModes = lockService.establishLocks(testDoc, editMode, quickstartSession.getPerson());
505 assertCorrectLocksAreInPlace(true, finalModes, 2, testDoc.getPessimisticLocks(), allPersons, allDescriptors);
506
507
508 GlobalVariables.getUserSession().removeObject(LOCK_KEY);
509 lockService.releaseAllLocksForUser(testDoc.getPessimisticLocks(), allPersons[0]);
510 testDoc.refreshPessimisticLocks();
511 assertTrue("There should not be any pessimistic locks present on the document", testDoc.getPessimisticLocks().isEmpty());
512 }
513
514
515
516
517
518
519
520
521
522
523
524
525
526 private void assertCorrectLocksAreInPlace(boolean latestUserHasFullEntry, Map<?,?> finalModes, int expectedLockQuantity,
527 List<PessimisticLock> pessimisticLocks, Person[] expectedOwners, String[] expectedDescriptors) throws Exception {
528
529 if (finalModes != null) {
530 assertEquals("The last user that tried to establish locks does not have the expected status on their full entry privileges",
531 latestUserHasFullEntry, StringUtils.equalsIgnoreCase(KRADConstants.KUALI_DEFAULT_TRUE_VALUE, (String)(finalModes.get(
532 AuthorizationConstants.EditMode.FULL_ENTRY))));
533 }
534
535 assertEquals("The wrong number of pessimistic locks are in place", expectedLockQuantity, pessimisticLocks.size());
536
537 for (int i = pessimisticLocks.size() - 1; i > -1; i--) {
538 assertTrue("The lock at index " + i + " did not have the expected owner of " + expectedOwners[i].getPrincipalName(),
539 pessimisticLocks.get(i).isOwnedByUser(expectedOwners[i]));
540 if (expectedDescriptors != null) {
541 assertTrue("The lock at index " + i + " did not have the expected lock descriptor of " + expectedDescriptors[i],
542 pessimisticLocks.get(i).getLockDescriptor().equals(expectedDescriptors[i]));
543 }
544 }
545 }
546 }