@Override public String validateActionRules(List<ActionRequestValue> actionRequests) { return validateActionRules( actionRequests, KEWServiceLocator.getRouteNodeService() .getActiveRouteNodeNames(getRouteHeader().getDocumentId())); }
/* (non-Javadoc) * @see org.kuali.rice.kew.actions.ActionTakenEvent#isActionCompatibleRequest(java.util.List) */ @Override public String validateActionRules() { return validateActionRules( getActionRequestService().findAllPendingRequests(routeHeader.getDocumentId()), KEWServiceLocator.getRouteNodeService() .getActiveRouteNodeNames(getRouteHeader().getDocumentId())); }
/** * Tests that the document route past the join properly when there are parallel branches that * don't generate requests. This was coded in response to a bug found while testing with ERA in * order to track it down and fix it. */ @Test public void testEmptyParallelBranches() throws Exception { WorkflowDocument document = WorkflowDocumentFactory.createDocument( getPrincipalIdForName("ewestfal"), PARALLEL_EMPTY_DOCUMENT_TYPE_NAME); document.saveDocumentData(); assertTrue("Document should be initiated", document.isInitiated()); assertEquals("Should be no action requests.", 0, document.getRootActionRequests().size()); Collection<? extends Object> nodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId()); assertEquals("Wrong number of active nodes.", 1, nodeInstances.size()); document.route(""); // should have generated a request to "bmcgough" document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("bmcgough"), document.getDocumentId()); assertTrue("Document should be enroute", document.isEnroute()); List<ActionRequestValue> actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId()); assertEquals("Incorrect pending action requests.", 1, actionRequests.size()); ActionRequestValue bRequest = actionRequests.get(0); assertNotNull("Should have been routed through node instance.", bRequest.getNodeInstance()); assertTrue(document.isApprovalRequested()); document.approve(""); // now the document should have split, passed through nodes in each branch which didn't generate // requests, // and then passed the join node and generated requests at WorkflowDocumentFinal document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("xqi"), document.getDocumentId()); assertTrue("Document should be enroute", document.isEnroute()); assertTrue(document.isApprovalRequested()); }
@Test public void testParallelRoute() throws Exception { WorkflowDocument document = WorkflowDocumentFactory.createDocument( getPrincipalIdForName("ewestfal"), DOCUMENT_TYPE_NAME); document.saveDocumentData(); assertTrue("Document should be initiated", document.isInitiated()); assertEquals("Should be no action requests.", 0, document.getRootActionRequests().size()); Collection<RouteNodeInstance> nodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId()); assertEquals("Wrong number of active nodes.", 1, nodeInstances.size()); document.route("Routing for parallel"); // should have generated a request to "bmcgough" document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("bmcgough"), document.getDocumentId()); assertTrue("Document should be enroute", document.isEnroute()); List<ActionRequestValue> actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId()); assertEquals("Incorrect pending action requests.", 1, actionRequests.size()); ActionRequestValue bRequest = actionRequests.get(0); assertNotNull("Should have been routed through node instance.", bRequest.getNodeInstance()); assertTrue(document.isApprovalRequested()); document.approve("Approving test"); // document should split at this point and generate an ack to temay and approves to rkirkend and // pmckown document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("rkirkend"), document.getDocumentId()); assertTrue("Document should be enroute", document.isEnroute()); actionRequests = KEWServiceLocator.getActionRequestService().findPendingByDoc(document.getDocumentId()); assertEquals("Incorrect pending action requests.", 3, actionRequests.size()); boolean isToTemay = false; boolean isToPmckown = false; boolean isToRkirkend = false; for (Iterator iterator = actionRequests.iterator(); iterator.hasNext(); ) { ActionRequestValue actionRequest = (ActionRequestValue) iterator.next(); if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("temay"))) { isToTemay = true; assertEquals( "Request should be activated.", ActionRequestStatus.ACTIVATED.getCode(), actionRequest.getStatus()); assertEquals( "Wrong action requested.", KewApiConstants.ACTION_REQUEST_ACKNOWLEDGE_REQ, actionRequest.getActionRequested()); assertNotNull( "Should have been routed through node instance.", actionRequest.getNodeInstance()); assertEquals( "Invalid node.", ACKNOWLEDGE_1_NODE, actionRequest.getNodeInstance().getRouteNode().getRouteNodeName()); } if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("rkirkend"))) { isToRkirkend = true; assertEquals( "Request should be activated.", ActionRequestStatus.ACTIVATED.getCode(), actionRequest.getStatus()); assertEquals( "Wrong action requested.", KewApiConstants.ACTION_REQUEST_APPROVE_REQ, actionRequest.getActionRequested()); assertNotNull( "Should have been routed through node instance.", actionRequest.getNodeInstance()); assertEquals( "Invalid node.", WORKFLOW_DOCUMENT_2_NODE, actionRequest.getNodeInstance().getRouteNode().getRouteNodeName()); } if (actionRequest.getPrincipalId().equals(getPrincipalIdForName("pmckown"))) { isToPmckown = true; assertEquals( "Request should be activated.", ActionRequestStatus.ACTIVATED.getCode(), actionRequest.getStatus()); assertEquals( "Wrong action requested.", KewApiConstants.ACTION_REQUEST_APPROVE_REQ, actionRequest.getActionRequested()); assertNotNull( "Should have been routed through node instance.", actionRequest.getNodeInstance()); assertEquals( "Invalid node.", WORKFLOW_DOCUMENT_3_NODE, actionRequest.getNodeInstance().getRouteNode().getRouteNodeName()); } } assertTrue("No request to temay.", isToTemay); assertTrue("No request to pmckown.", isToPmckown); assertTrue("No request to rkirkend.", isToRkirkend); // check that we are at both nodes, one in each branch Set<String> nodeNames = document.getNodeNames(); assertEquals("Wrong number of node names.", 2, nodeNames.size()); boolean isNode2 = false; boolean isNode3 = false; for (String name : nodeNames) { if (name.equals(WORKFLOW_DOCUMENT_2_NODE)) { isNode2 = true; } if (name.equals(WORKFLOW_DOCUMENT_3_NODE)) { isNode3 = true; } } assertTrue("Not at node2.", isNode2); assertTrue("Not at node3.", isNode3); nodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId()); assertEquals("Wrong number of active nodes.", 2, nodeInstances.size()); Iterator<RouteNodeInstance> iterator = nodeInstances.iterator(); RouteNodeInstance instance1 = (RouteNodeInstance) iterator.next(); RouteNodeInstance instance2 = (RouteNodeInstance) iterator.next(); assertNotNull("Node should be in branch.", instance1.getBranch()); assertNotNull("Node should be in branch.", instance2.getBranch()); assertTrue( "Branches should be different.", !instance1.getBranch().getBranchId().equals(instance2.getBranch().getBranchId())); document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("rkirkend"), document.getDocumentId()); assertTrue("Should have request.", document.isApprovalRequested()); document.approve("Git-r-dun"); nodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId()); assertEquals("Wrong number of active nodes.", 2, nodeInstances.size()); boolean isAtJoin = false; boolean isAtWD3 = false; for (RouteNodeInstance nodeInstance : nodeInstances) { if (nodeInstance.getRouteNode().getRouteNodeName().equals(JOIN_NODE)) { assertEquals( "Join branch should be split branch.", instance1.getBranch().getParentBranch().getBranchId(), nodeInstance.getBranch().getBranchId()); isAtJoin = true; } if (nodeInstance.getRouteNode().getRouteNodeName().equals(WORKFLOW_DOCUMENT_3_NODE)) { isAtWD3 = true; } } assertTrue("Not at join", isAtJoin); assertTrue("Not at WD3", isAtWD3); document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("pmckown"), document.getDocumentId()); assertTrue("Should have request.", document.isApprovalRequested()); document.approve("Do it."); nodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId()); assertEquals("Wrong number of active nodes.", 1, nodeInstances.size()); boolean isAtWDF = false; for (RouteNodeInstance nodeInstance : nodeInstances) { if (nodeInstance.getRouteNode().getRouteNodeName().equals(WORKFLOW_DOCUMENT_FINAL_NODE)) { isAtWDF = true; } } assertTrue("Not at WDF", isAtWDF); document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("xqi"), document.getDocumentId()); assertTrue("Should still be enroute.", document.isEnroute()); assertTrue("Should have request.", document.isApprovalRequested()); document.approve("I'm the last approver"); assertTrue("Document should be processed.", document.isProcessed()); nodeInstances = KEWServiceLocator.getRouteNodeService().getActiveNodeInstances(document.getDocumentId()); assertEquals( "The doc is processed so no node instances should be active", 0, nodeInstances.size()); document = WorkflowDocumentFactory.loadDocument( getPrincipalIdForName("temay"), document.getDocumentId()); assertTrue("Should have request.", document.isAcknowledgeRequested()); document.acknowledge(""); assertTrue(document.isFinal()); }
public void recordAction() throws InvalidActionTakenException { MDC.put("docId", getRouteHeader().getDocumentId()); updateSearchableAttributesIfPossible(); LOG.debug( "Moving document " + getRouteHeader().getDocumentId() + " to point: " + displayMovePoint(movePoint) + ", annotation: " + annotation); List actionRequests = getActionRequestService() .findAllValidRequests( getPrincipal().getPrincipalId(), getDocumentId(), KewApiConstants.ACTION_REQUEST_COMPLETE_REQ); Collection activeNodes = KEWServiceLocator.getRouteNodeService() .getActiveNodeInstances(getRouteHeader().getDocumentId()); String errorMessage = validateActionRules(actionRequests, activeNodes); if (!org.apache.commons.lang.StringUtils.isEmpty(errorMessage)) { throw new InvalidActionTakenException(errorMessage); } RouteNodeInstance startNodeInstance = determineStartNode(activeNodes, movePoint); LOG.debug("Record the move action"); Recipient delegator = findDelegatorForActionRequests(actionRequests); ActionTakenValue actionTaken = saveActionTaken(delegator); getActionRequestService().deactivateRequests(actionTaken, actionRequests); notifyActionTaken(actionTaken); // TODO this whole bit is a bit hacky at the moment if (movePoint.getStepsToMove() > 0) { Set<String> targetNodeNames = new HashSet<String>(); targetNodeNames.add(determineFutureNodeName(startNodeInstance, movePoint)); final boolean shouldIndex = getRouteHeader().getDocumentType().hasSearchableAttributes() && RouteContext.getCurrentRouteContext().isSearchIndexingRequestedForContext(); String applicationId = routeHeader.getDocumentType().getApplicationId(); DocumentOrchestrationQueue orchestrationQueue = KewApiServiceLocator.getDocumentOrchestrationQueue( routeHeader.getDocumentId(), applicationId); org.kuali.rice.kew.api.document.OrchestrationConfig orchestrationConfig = org.kuali.rice.kew.api.document.OrchestrationConfig.create( actionTaken.getActionTakenId(), targetNodeNames); DocumentProcessingOptions options = DocumentProcessingOptions.create(true, shouldIndex, false); orchestrationQueue.orchestrateDocument( routeHeader.getDocumentId(), getPrincipal().getPrincipalId(), orchestrationConfig, options); } else { String targetNodeName = determineReturnNodeName(startNodeInstance, movePoint); ReturnToPreviousNodeAction returnAction = new ReturnToPreviousNodeAction( KewApiConstants.ACTION_TAKEN_MOVE_CD, getRouteHeader(), getPrincipal(), annotation, targetNodeName, false); returnAction.recordAction(); } }
public RouteNodeService getRouteNodeService() { if (routeNodeService == null) { routeNodeService = KEWServiceLocator.getRouteNodeService(); } return routeNodeService; }