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