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