1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.rice.kew.routemanager;
17
18 import org.junit.Test;
19 import org.kuali.rice.kew.api.KewApiServiceLocator;
20 import org.kuali.rice.kew.api.WorkflowDocument;
21 import org.kuali.rice.kew.api.WorkflowDocumentFactory;
22 import org.kuali.rice.kew.api.action.ActionRequest;
23 import org.kuali.rice.kew.api.action.InvalidActionTakenException;
24 import org.kuali.rice.kew.api.document.DocumentProcessingQueue;
25 import org.kuali.rice.kew.api.document.node.RouteNodeInstance;
26 import org.kuali.rice.kew.routeheader.DocumentRouteHeaderValue;
27 import org.kuali.rice.kew.service.KEWServiceLocator;
28 import org.kuali.rice.kew.test.KEWTestCase;
29 import org.kuali.rice.kew.test.TestUtilities;
30 import org.kuali.rice.kim.api.group.Group;
31 import org.kuali.rice.kim.api.services.KimApiServiceLocator;
32 import org.kuali.rice.ksb.messaging.service.KSBXMLService;
33 import org.kuali.rice.test.BaselineTestCase;
34
35 import javax.xml.namespace.QName;
36 import java.util.Collection;
37 import java.util.List;
38
39 import static org.junit.Assert.*;
40
41 @BaselineTestCase.BaselineMode(BaselineTestCase.Mode.CLEAR_DB)
42 public class ExceptionRoutingTest extends KEWTestCase {
43
44 protected void loadTestData() throws Exception {
45 loadXmlFile("RouteManagerConfig.xml");
46 }
47
48 protected void setUpAfterDataLoad() throws Exception {
49 super.setUpAfterDataLoad();
50
51 ExceptionRoutingTestPostProcessor.THROW_DO_ACTION_TAKEN_EXCEPTION = false;
52 ExceptionRoutingTestPostProcessor.THROW_ROUTE_DELETE_ROUTE_HEADER_EXCEPTION = false;
53 ExceptionRoutingTestPostProcessor.THROW_ROUTE_STATUS_CHANGE_EXCEPTION = false;
54 ExceptionRoutingTestPostProcessor.THROW_ROUTE_STATUS_LEVEL_EXCEPTION = false;
55 ExceptionRoutingTestPostProcessor.TRANSITIONED_OUT_OF_EXCEPTION_ROUTING = false;
56 ExceptionRoutingTestPostProcessor.BLOW_UP_ON_TRANSITION_INTO_EXCEPTION = false;
57 }
58
59 @Test public void testSequentialExceptionRouting() throws Exception {
60 WorkflowDocument doc = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), "ExceptionRoutingSequentialDoc");
61 try {
62 doc.route("");
63 fail("should have thrown routing exception");
64 } catch (Exception e) {
65 }
66
67 TestUtilities.getExceptionThreader().join();
68
69 doc = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), doc.getDocumentId());
70 assertTrue("Document should be in exception status", doc.isException());
71
72 List<ActionRequest> actionRequests = KewApiServiceLocator.getWorkflowDocumentService().getRootActionRequests(doc.getDocumentId());
73
74 assertEquals("Should be a single exception request", 1, actionRequests.size());
75 for (ActionRequest actionRequest : actionRequests) {
76 Group group = KimApiServiceLocator.getGroupService().getGroup(actionRequest.getGroupId());
77 assertTrue("Request should be an exception request.", actionRequest.isExceptionRequest());
78 assertTrue("Complete should be requested", actionRequest.isCompleteRequest());
79 assertTrue("Request should be a workgroup request", actionRequest.isGroupRequest());
80 assertEquals("Request should be to 'ExceptionRoutingGroup'", "ExceptionRoutingGroup", group.getName());
81 assertNotNull("annotation cannot be null", actionRequest.getAnnotation());
82 assertFalse("annotation cannot be empty", "".equals(actionRequest.getAnnotation()));
83 }
84
85 }
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 @Test public void testInvalidActionsInExceptionRouting() throws Exception {
113 WorkflowDocument doc = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), "ExceptionRoutingSequentialDoc");
114 try {
115 doc.route("");
116 fail("should have thrown routing exception");
117 } catch (Exception e) {
118 log.info("Expected exception occurred: " + e);
119 }
120
121 TestUtilities.getExceptionThreader().join();
122
123 doc = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), doc.getDocumentId());
124 assertTrue("Document should be in exception status", doc.isException());
125
126 try {
127 doc.route("routing a document that is in exception routing");
128 fail("Succeeded in routing document that is in exception routing");
129 } catch (InvalidActionTakenException iate) {
130 log.info("Expected exception occurred: " + iate);
131 }
132 }
133
134 @Test public void testParallelExceptionRouting() throws Exception {
135 WorkflowDocument doc = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("user1"), "ExceptionRoutingParallelDoc");
136 doc.route("");
137 doc = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), doc.getDocumentId());
138 assertTrue("User should have an approve request", doc.isApprovalRequested());
139 doc = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), doc.getDocumentId());
140 assertTrue("User should have an approve request", doc.isApprovalRequested());
141 List<RouteNodeInstance> nodes = KewApiServiceLocator.getWorkflowDocumentService().getActiveRouteNodeInstances(
142 doc.getDocumentId());
143
144
145 assertEquals("There should be two active nodes", 2, nodes.size());
146 TestUtilities.assertAtNode(doc, "RouteNode1");
147 TestUtilities.assertAtNode(doc, "RouteNode3");
148
149 try {
150 doc.approve("");
151 fail("should have generated routing exception");
152 } catch (Exception e) {
153 }
154
155 TestUtilities.getExceptionThreader().join();
156 List<ActionRequest> actionRequests = KewApiServiceLocator.getWorkflowDocumentService().getRootActionRequests(doc.getDocumentId());
157 RouteNodeInstance routeNode1 = null;
158 for (RouteNodeInstance nodeInstanceVO : nodes) {
159 if (nodeInstanceVO.getName().equals("RouteNode1")) {
160 routeNode1 = nodeInstanceVO;
161 }
162 }
163 assertNotNull("Could not locate the routeNode1 node instance.", routeNode1);
164
165 boolean hasCompleteRequest = false;
166 for (ActionRequest actionRequest : actionRequests) {
167 if (actionRequest.isCompleteRequest()) {
168 Group group = KimApiServiceLocator.getGroupService().getGroup(actionRequest.getGroupId());
169 assertTrue("Complete should be requested", actionRequest.isCompleteRequest());
170 assertTrue("Request should be a workgroup request", actionRequest.isGroupRequest());
171 assertNull("For exception routing, node instance should have a null id.", actionRequest.getRouteNodeInstanceId());
172
173 assertEquals("Request should be to 'ExceptionRoutingGroup'", "ExceptionRoutingGroup", group.getName());
174 hasCompleteRequest = true;
175 }
176 }
177 assertTrue("Document should have had a complete request", hasCompleteRequest);
178 ExplodingRuleAttribute.dontExplode=true;
179
180
181 Collection actionItems = KEWServiceLocator.getActionListService().findByDocumentId(doc.getDocumentId());
182 assertEquals("There should only be action items for the member of our exception workgroup", 1, actionItems.size());
183
184 doc = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("user3"), doc.getDocumentId());
185 assertTrue("Document should be routing for completion to member of exception workgroup", doc.isCompletionRequested());
186 assertTrue("Document should be in exception status", doc.isException());
187 doc.complete("");
188
189 doc = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("bmcgough"), doc.getDocumentId());
190 doc.approve("");
191
192 doc = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("ewestfal"), doc.getDocumentId());
193 doc.approve("");
194
195 doc = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), doc.getDocumentId());
196 doc.approve("");
197
198 doc = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), doc.getDocumentId());
199 doc.approve("");
200
201 assertTrue("Document should be final", doc.isFinal());
202 }
203
204
205
206
207
208
209
210 @Test public void testExceptionInTransitionFromStart() throws Exception {
211
212 WorkflowDocument doc = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), "AdhocTransitionTestDocument");
213
214 ExceptionRoutingTestPostProcessor.THROW_ROUTE_STATUS_LEVEL_EXCEPTION = true;
215
216 try {
217 doc.route("");
218 fail("We should be in exception routing");
219 } catch (Exception e) {
220 }
221
222 TestUtilities.getExceptionThreader().join();
223 doc = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), doc.getDocumentId());
224 assertTrue("document should be in exception routing", doc.isException());
225 }
226
227
228
229
230
231
232
233 @Test public void testRequeueOfExceptionDocument() throws Exception {
234 WorkflowDocument document = WorkflowDocumentFactory.createDocument(getPrincipalIdForName("rkirkend"), "AdhocTransitionTestDocument");
235 document.route("");
236 assertFalse("Document should not be in exception routing.", document.isException());
237
238
239 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
240 assertTrue("Jhopf should have an approve.", document.isApprovalRequested());
241
242
243 ExceptionRoutingTestPostProcessor.THROW_ROUTE_STATUS_CHANGE_EXCEPTION = true;
244 try {
245 document.approve("");
246 fail("We should be in exception routing");
247 } catch (Exception e) {
248 }
249
250 TestUtilities.waitForExceptionRouting();
251 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
252 assertTrue("document should be in exception routing", document.isException());
253
254
255
256
257 ExceptionRoutingTestPostProcessor.THROW_ROUTE_STATUS_CHANGE_EXCEPTION = false;
258 assertFalse("Should not have transitioned out of exception routing yet.", ExceptionRoutingTestPostProcessor.TRANSITIONED_OUT_OF_EXCEPTION_ROUTING);
259
260 DocumentRouteHeaderValue routeHeaderValue = KEWServiceLocator.getRouteHeaderService().getRouteHeader(document.getDocumentId());
261 String applicationId = routeHeaderValue.getDocumentType().getApplicationId();
262 DocumentProcessingQueue documentProcessingQueue = KewApiServiceLocator.getDocumentProcessingQueue(document.getDocumentId(), applicationId);
263 documentProcessingQueue.process(String.valueOf(document.getDocumentId()));
264
265
266 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("rkirkend"), document.getDocumentId());
267 assertTrue("document should be in exception routing", document.isException());
268 assertFalse("document shouldn't have transitioned out of exception routing.", ExceptionRoutingTestPostProcessor.TRANSITIONED_OUT_OF_EXCEPTION_ROUTING);
269
270
271 ExceptionRoutingTestPostProcessor.THROW_ROUTE_STATUS_CHANGE_EXCEPTION = false;
272 assertTrue("rkirkend should be in the exception workgroup.", document.isCompletionRequested());
273 document.complete("Completing out of exception routing.");
274
275
276
277
278 document = WorkflowDocumentFactory.loadDocument(getPrincipalIdForName("jhopf"), document.getDocumentId());
279 assertTrue(document.isApprovalRequested());
280 document.approve("");
281
282
283 assertTrue("Document should be FINAL.", document.isFinal());
284
285
286 assertTrue("Document should have transitioned out of exception routing.", ExceptionRoutingTestPostProcessor.TRANSITIONED_OUT_OF_EXCEPTION_ROUTING);
287 }
288
289 }