View Javadoc
1   /**
2    * Copyright 2005-2014 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.kns.service.impl;
17  
18  import org.apache.commons.lang.StringUtils;
19  import org.junit.Test;
20  import org.kuali.rice.kim.api.identity.Person;
21  import org.kuali.rice.kns.KNSTestCase;
22  import org.kuali.rice.kns.authorization.AuthorizationConstants;
23  import org.kuali.rice.krad.UserSession;
24  import org.kuali.rice.krad.document.Document;
25  import org.kuali.rice.krad.document.authorization.PessimisticLock;
26  import org.kuali.rice.krad.maintenance.MaintenanceDocument;
27  import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
28  import org.kuali.rice.krad.service.PessimisticLockService;
29  import org.kuali.rice.krad.service.impl.PessimisticLockServiceImpl;
30  import org.kuali.rice.krad.test.document.AccountType2MaintainableImpl;
31  import org.kuali.rice.krad.util.GlobalVariables;
32  import org.kuali.rice.krad.util.KRADConstants;
33  import org.kuali.rice.test.BaselineTestCase;
34  
35  import java.io.Serializable;
36  import java.util.HashMap;
37  import java.util.List;
38  import java.util.Map;
39  
40  import static org.junit.Assert.*;
41  
42  /**
43   * PessimisticLockServiceTest tests {@link PessimisticLockServiceImpl} for maintainable
44   *
45   * @deprecated KNS test class, convert to KRAD equivalent if applicable.
46   */
47  @Deprecated
48  @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.NONE)
49  public class PessimisticLockServiceTest extends KNSTestCase {
50  
51      String sessionId = "ad4d6c83-4d0f-4309-a528-c2f81ec00395";
52  
53      @Override
54      public void setUp() throws Exception {
55          super.setUp();
56          GlobalVariables.setUserSession(new UserSession("quickstart"));
57          GlobalVariables.getUserSession().setKualiSessionId(sessionId);
58      }
59  
60      /**
61       * tests the PessimisticLockService's ability to establish pessimistic locks for maintenance documents (via
62       * maintainables) that
63       * support custom lock descriptors
64       *
65       * @throws Exception
66       */
67      @Test
68      public void testPessimisticLockingWithCustomMaintainableLockDescriptors() throws Exception {
69          MaintenanceDocument maintDoc = (MaintenanceDocument) KRADServiceLocatorWeb.getDocumentService().getNewDocument(
70                  "AccountType2MaintenanceDocument");
71          assertTrue("The AccountType2MaintenanceDocument should be using pessimistic locking",
72                  KRADServiceLocatorWeb.getDataDictionaryService().getDataDictionary().getDocumentEntry(
73                          maintDoc.getNewMaintainableObject().getDataObjectClass().getSimpleName()
74                                  + "MaintenanceDocument").getUsePessimisticLocking());
75          assertTrue("The AccountType2MaintenanceDocument should be using custom lock descriptors",
76                  maintDoc.useCustomLockDescriptors());
77          assertTrue("The AccountType2MaintenanceDocument's new maintainable uses the wrong class",
78                  maintDoc.getNewMaintainableObject() instanceof AccountType2MaintainableImpl);
79          AccountType2MaintainableImpl newMaint = (AccountType2MaintainableImpl) maintDoc.getNewMaintainableObject();
80          assertTrue("The AccountType2MaintainableImpl should be using custom lock descriptors",
81                  newMaint.useCustomLockDescriptors());
82  
83          // Perform the custom lock descriptor unit testing operations.
84          assertCustomLockDescriptorsAreWorking(maintDoc, AccountType2MaintainableImpl.ACCT_TYPE_2_MAINT_FIELDS_TO_EDIT,
85                  AccountType2MaintainableImpl.EDIT_CODE_ONLY, AccountType2MaintainableImpl.EDIT_NAME_ONLY);
86      }
87  
88      /**
89       * A convenience method for testing the custom lock descriptors of documents (and on the maintainables of
90       * maintenance documents).
91       *
92       * @param testDoc The document to test pessimistic locking on (or the maintenance document with maintainables to
93       * test on).
94       * @param LOCK_KEY The UserSession object key to use for storing the lock descriptor's key.
95       * @param LOCK_VALUE1 One possible object to store in a UserSession for generating lock descriptors on the testDoc.
96       * @param LOCK_VALUE2 Another possible object to store in a UserSession for generating lock descriptors on the
97       * testDoc.
98       * @throws Exception
99       */
100     private void assertCustomLockDescriptorsAreWorking(Document testDoc, final String LOCK_KEY,
101             final Serializable LOCK_VALUE1, final Serializable LOCK_VALUE2) throws Exception {
102         PessimisticLockService lockService = KRADServiceLocatorWeb.getPessimisticLockService();
103 
104         // Have "quickstart" establish a pessimistic lock on the document by using a custom lock descriptor that only locks part of the document.
105         UserSession quickstartSession = new UserSession("quickstart");
106         Person[] allPersons = {quickstartSession.getPerson(), null};
107         Map<String, String> editMode = new HashMap<String, String>();
108         editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
109         GlobalVariables.getUserSession().addObject(LOCK_KEY, LOCK_VALUE1);
110         String[] allDescriptors = {testDoc.getCustomLockDescriptor(quickstartSession.getPerson()), null};
111         assertNotNull("The document should have generated a custom lock descriptor", allDescriptors[0]);
112         Map<?, ?> finalModes = lockService.establishLocks(testDoc, editMode, quickstartSession.getPerson());
113 
114         // Verify that the lock was actually established and that the expected custom lock descriptor was used.
115         assertCorrectLocksAreInPlace(true, finalModes, 1, testDoc.getPessimisticLocks(), allPersons, allDescriptors);
116 
117         // Attempt to establish the same lock again, which should change nothing since "quickstart" already has the lock.
118         editMode = new HashMap<String, String>();
119         editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
120         GlobalVariables.getUserSession().addObject(LOCK_KEY, LOCK_VALUE1);
121         lockService.establishLocks(testDoc, editMode, quickstartSession.getPerson());
122         assertCorrectLocksAreInPlace(false, null, 1, testDoc.getPessimisticLocks(), allPersons, allDescriptors);
123 
124         // Now check to make sure that a different user (such as "admin") cannot establish a lock using the same lock descriptor.
125         UserSession adminSession = new UserSession("admin");
126         editMode = new HashMap<String, String>();
127         editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
128         GlobalVariables.getUserSession().addObject(LOCK_KEY, LOCK_VALUE1);
129         assertEquals("The document should have generated the same lock descriptors for both 'quickstart' and 'admin'",
130                 allDescriptors[0], testDoc.getCustomLockDescriptor(adminSession.getPerson()));
131         finalModes = lockService.establishLocks(testDoc, editMode, adminSession.getPerson());
132         assertCorrectLocksAreInPlace(false, finalModes, 1, testDoc.getPessimisticLocks(), allPersons, allDescriptors);
133 
134         // Ensure that "admin" can establish a lock that has a different lock descriptor.
135         allPersons[1] = adminSession.getPerson();
136         editMode = new HashMap<String, String>();
137         editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
138         GlobalVariables.getUserSession().addObject(LOCK_KEY, LOCK_VALUE2);
139         allDescriptors[1] = testDoc.getCustomLockDescriptor(adminSession.getPerson());
140         assertNotNull("The document should have generated a custom lock descriptor", allDescriptors[1]);
141         assertNotSame("'quickstart' and 'admin' should have different custom lock descriptors now", allDescriptors[0],
142                 allDescriptors[1]);
143         finalModes = lockService.establishLocks(testDoc, editMode, adminSession.getPerson());
144         assertCorrectLocksAreInPlace(true, finalModes, 2, testDoc.getPessimisticLocks(), allPersons, allDescriptors);
145 
146         // Verify that "quickstart" cannot acquire the lock owned by "admin".
147         editMode = new HashMap<String, String>();
148         editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
149         GlobalVariables.getUserSession().addObject(LOCK_KEY, LOCK_VALUE2);
150         lockService.establishLocks(testDoc, editMode, quickstartSession.getPerson());
151         assertCorrectLocksAreInPlace(false, null, 2, testDoc.getPessimisticLocks(), allPersons, allDescriptors);
152 
153         // After "admin" releases his lock, check to make sure that "quickstart" can now acquire it.
154         lockService.releaseAllLocksForUser(testDoc.getPessimisticLocks(), allPersons[1], allDescriptors[1]);
155         testDoc.refreshPessimisticLocks();
156         assertCorrectLocksAreInPlace(false, null, 1, testDoc.getPessimisticLocks(), allPersons, allDescriptors);
157         allPersons[1] = allPersons[0];
158         editMode = new HashMap<String, String>();
159         editMode.put(AuthorizationConstants.EditMode.FULL_ENTRY, KRADConstants.KUALI_DEFAULT_TRUE_VALUE);
160         GlobalVariables.getUserSession().addObject(LOCK_KEY, LOCK_VALUE2);
161         finalModes = lockService.establishLocks(testDoc, editMode, quickstartSession.getPerson());
162         assertCorrectLocksAreInPlace(true, finalModes, 2, testDoc.getPessimisticLocks(), allPersons, allDescriptors);
163 
164         // Release all the locks when done.
165         GlobalVariables.getUserSession().removeObject(LOCK_KEY);
166         lockService.releaseAllLocksForUser(testDoc.getPessimisticLocks(), allPersons[0]);
167         testDoc.refreshPessimisticLocks();
168         assertTrue("There should not be any pessimistic locks present on the document",
169                 testDoc.getPessimisticLocks().isEmpty());
170     }
171 
172     /**
173      * A convenience method for checking to ensure that the proper pessimistic locks are in place.
174      *
175      * @param latestUserHasFullEntry Indicates if the map returned by PessimisticLockService.establishLocks should have
176      * a true "fullEntry" parameter.
177      * @param finalModes The map returned by the call to PessimisticLockService.establishLocks. This parameter can be
178      * null if checking it is not needed.
179      * @param expectedLockQuantity The expected number of pessimistic locks.
180      * @param pessimisticLocks The list of pessimistic locks to check for proper quantity and proper state.
181      * @param expectedOwners The users who are expected to own the corresponding locks in the previous list.
182      * @param expectedDescriptors The expected lock descriptors for the corresponding locks in the other list. This
183      * parameter can be set to null if
184      * the pessimistic locks are not using custom lock descriptors or if custom lock descriptors are not the concern of
185      * the test.
186      * @throws Exception
187      */
188     private void assertCorrectLocksAreInPlace(boolean latestUserHasFullEntry, Map<?, ?> finalModes,
189             int expectedLockQuantity, List<PessimisticLock> pessimisticLocks, Person[] expectedOwners,
190             String[] expectedDescriptors) throws Exception {
191         // Ensure that the last user to attempt to establish locks has the expected finalModes entry (or lack of it).
192         if (finalModes != null) {
193             assertEquals(
194                     "The last user that tried to establish locks does not have the expected status on their full entry privileges",
195                     latestUserHasFullEntry, StringUtils.equalsIgnoreCase(KRADConstants.KUALI_DEFAULT_TRUE_VALUE,
196                     (String) (finalModes.get(AuthorizationConstants.EditMode.FULL_ENTRY))));
197         }
198         // Ensure that the expected number of locks are present.
199         assertEquals("The wrong number of pessimistic locks are in place", expectedLockQuantity,
200                 pessimisticLocks.size());
201         // Verify that each lock has the expected owners.
202         for (int i = pessimisticLocks.size() - 1; i > -1; i--) {
203             assertTrue("The lock at index " + i + " did not have the expected owner of " + expectedOwners[i]
204                     .getPrincipalName(), pessimisticLocks.get(i).isOwnedByUser(expectedOwners[i]));
205             if (expectedDescriptors != null) {
206                 assertTrue("The lock at index "
207                         + i
208                         + " did not have the expected lock descriptor of "
209                         + expectedDescriptors[i], pessimisticLocks.get(i).getLockDescriptor().equals(
210                         expectedDescriptors[i]));
211             }
212         }
213     }
214 }