/*
* This file is part of the WfMOpen project.
* Copyright (C) 2001-2003 Danet GmbH (www.danet.de), GS-AN.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: AuditTests.java 3205 2009-09-27 17:13:47Z mlipp $
*
* $Log$
* Revision 1.6 2007/01/26 14:38:12 drmlipp
* Minor updated to process close event delivery.
*
* Revision 1.5 2006/10/19 13:52:26 drmlipp
* Fixed sorting problems.
*
* Revision 1.4 2006/09/29 12:32:10 drmlipp
* Consistently using WfMOpen as projct name now.
*
* Revision 1.3 2005/04/22 15:11:06 drmlipp
* Merged changes from 1.3 branch up to 1.3p15.
*
* Revision 1.1.1.3.6.4 2005/04/21 12:51:38 drmlipp
* Fixed test.
*
* Revision 1.1.1.3.6.3 2005/04/18 11:11:36 drmlipp
* More event handling optimization.
*
* Revision 1.2 2005/04/08 11:28:06 drmlipp
* Merged changes from 1.3 branch up to 1.3p6.
*
* Revision 1.1.1.3.6.2 2005/04/07 20:47:40 drmlipp
* Fixed assertion.
*
* Revision 1.1.1.3.6.1 2005/04/07 12:13:04 drmlipp
* Added event subscriber with filter.
*
* Revision 1.1.1.3 2004/08/18 15:18:47 drmlipp
* Update to 1.2
*
* Revision 1.27 2004/05/05 09:44:07 lipp
* Finished SAX based process creation (no cleanup of old code, yet).
*
* Revision 1.26 2004/01/27 11:45:33 lipp
* Preserve newlines when reading process definitions.
*
* Revision 1.25 2003/10/21 21:00:45 lipp
* Moved EJBClientTest to new junit sub-package.
*
* Revision 1.24 2003/10/08 11:52:55 huaiyang
* make test weblogic compatible.
*
* Revision 1.23 2003/09/19 13:12:29 lipp
* Adapted to closed.completed having a substate.
*
* Revision 1.22 2003/06/27 09:44:13 lipp
* Fixed copyright/license information.
*
* Revision 1.21 2003/05/12 19:01:03 lipp
* Fixed process definition version().
*
* Revision 1.20 2003/04/26 16:46:55 lipp
* Made unittests and systemtests coexist in eclipse.
*
* Revision 1.19 2003/04/16 19:25:04 lipp
* Adapted to jdk 1.4
*
* Revision 1.18 2003/04/08 15:22:16 lipp
* Fixed tests.
*
* Revision 1.17 2003/03/07 15:09:09 lipp
* Minor fixes.
*
* Revision 1.16 2003/02/27 15:14:40 lipp
* Some fixes.
*
* Revision 1.15 2003/02/25 17:36:05 lipp
* Fixed assertion.
*
* Revision 1.14 2003/02/25 17:08:27 lipp
* Reorganized requester implementation.
*
* Revision 1.13 2003/02/14 10:08:25 lipp
* Improved messages.
*
* Revision 1.12 2003/02/06 16:40:21 lipp
* Fixed a state handling bug (must not expose running state for manually
* started activity).
*
* Revision 1.11 2003/02/05 15:57:06 lipp
* Replaced DummyRequester with DefaultRequester.
*
* Revision 1.10 2002/11/21 10:32:06 lipp
* Fixed test case.
*
* Revision 1.9 2002/11/19 15:14:52 lipp
* New transition manager.
*
* Revision 1.8 2002/10/23 07:29:15 lipp
* Adapted to state handling changes.
*
* Revision 1.7 2002/10/17 08:04:58 barzik
* initial tests finished
*
* Revision 1.6 2002/10/11 13:41:54 barzik
* adopted to asynch. behaviour of server
*
* Revision 1.5 2002/10/09 09:40:56 barzik
* now using the WorkflowServiceFactory
*
* Revision 1.4 2002/10/08 12:10:04 barzik
* extended to "changeAssignmentAuditEvent" verification test
*
* Revision 1.3 2002/10/07 12:02:50 barzik
* test case "changeActivityResult"
*
* Revision 1.2 2002/10/02 10:59:09 barzik
* extended testcase
*
* Revision 1.1 2002/10/01 12:45:26 barzik
* Initial implementation
*
*
*/
package process;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.security.auth.login.LoginException;
import de.danet.an.util.junit.EJBClientTest;
import de.danet.an.workflow.omgcore.ProcessData;
import de.danet.an.workflow.omgcore.WfActivity;
import de.danet.an.workflow.omgcore.WfAssignmentAuditEvent;
import de.danet.an.workflow.omgcore.WfAuditEvent;
import de.danet.an.workflow.omgcore.WfAuditHandler;
import de.danet.an.workflow.omgcore.WfCreateProcessAuditEvent;
import de.danet.an.workflow.omgcore.WfDataAuditEvent;
import de.danet.an.workflow.omgcore.WfExecutionObject;
import de.danet.an.workflow.omgcore.WfProcess;
import de.danet.an.workflow.omgcore.WfRequester;
import de.danet.an.workflow.omgcore.WfStateAuditEvent;
import de.danet.an.workflow.api.DefaultRequester;
import de.danet.an.workflow.api.EventSubscriber;
import de.danet.an.workflow.api.FactoryConfigurationError;
import de.danet.an.workflow.api.ProcessClosedAuditEvent;
import de.danet.an.workflow.api.ProcessDefinitionDirectory;
import de.danet.an.workflow.api.ProcessMgr;
import de.danet.an.workflow.api.WorkflowService;
import de.danet.an.workflow.api.WorkflowServiceFactory;
import common.UTLoginContext;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* Testing audit event handling. This test suite does not make any senseful
* things, rather than forcing the creation of several audit events in order
* to test that they've been created and written the appropriate database
* tables.
*/
public class AuditTests extends TestCase {
private static UTLoginContext plc = null;
static {
try {
plc = new UTLoginContext();
plc.login();
} catch (LoginException e) {
throw new IllegalStateException (e.getMessage ());
}
}
private static final String OPEN_RUNNING
= WfExecutionObject.OpenState.RUNNING.toString();
private static final String OPEN_NOT_RUNNING
= WfExecutionObject.OpenState.NOT_RUNNING.toString();
private static final String CLOSED_COMPLETED
= WfExecutionObject.ClosedState.COMPLETED.toString();
private static final String CLOSED_ABORTED
= WfExecutionObject.ClosedState.ABORTED.toString();
private static WorkflowService wfsCache = null;
private WorkflowService workflowService() {
if (wfsCache == null) {
try {
WorkflowServiceFactory wfsf
= WorkflowServiceFactory.newInstance ();
wfsCache = wfsf.newWorkflowService();
} catch (FactoryConfigurationError e) {
throw new IllegalStateException (e.getMessage());
}
}
return wfsCache;
}
private WfDataAuditEvent dae = null;
private WfDataAuditEvent dae2 = null;
private WfStateAuditEvent sae = null;
private WfCreateProcessAuditEvent cpae = null;
private WfAssignmentAuditEvent aae = null;
/* ********************************************************************* */
/* Test suite resources */
/* ********************************************************************* */
/**
*
*/
private WfProcess process = null;
/* ********************************************************************* */
/* Test suite */
/* ********************************************************************* */
/**
* Constructor of this TestCase
* @param name the name of the test case
*/
public AuditTests(String name) {
super (name);
}
/**
* The definition of the test suite. There's one test case per event type.
* However, not all test cases are currently doing something.
* @return the test suite
*/
public static Test suite() {
TestSuite suite = new TestSuite();
suite.addTest (new AuditTests("importProcessDefinitions"));
suite.addTest
(new AuditTests("createProcessAndProcessContextChanged"));
suite.addTest(new AuditTests("changeActivityResult"));
suite.addTest(new AuditTests("waitForCompletion"));
suite.addTest(new AuditTests("testFilters"));
suite.addTest(new AuditTests("testStateFilter"));
suite.addTest(new AuditTests("testClosedFilter"));
return new EJBClientTest (plc, suite);
}
/* ********************************************************************* */
/* Test cases */
/* ********************************************************************* */
/**
* Test case 1: Creates a process - calling AbstractProcess.init()
* @throws Exception ...
*/
public void createProcessAndProcessContextChanged() throws Exception {
// create the required process
WfRequester req = new DefaultRequester (workflowService());
process = createProcess("ut-procdef-audit", "auditTest", req);
assertTrue(process!=null);
// wait some time because of asynchronous processing
long anfang = System.currentTimeMillis();
Thread.sleep(5000);
long diff = (System.currentTimeMillis() - anfang)/1000;
//displayAuditEvents(events);
checkAuditEventsForCreateProcess(process);
}
/**
* Checks the collection of audit events for test case "createProcess"
* @param auditEvents the audit events to display
*/
private void checkAuditEventsForCreateProcess(WfProcess process)
throws Exception {
// check audit event(s)
Collection auditEvents = process.history();
assertTrue(process + ": expected 2 events, found " + auditEvents.size(),
auditEvents.size()==2);
Iterator i = auditEvents.iterator();
// the first event is required to signal the process creation
Object o = i.next();
Object o2;
if (! (o instanceof WfCreateProcessAuditEvent)) {
o2 = o;
o = i.next();
} else {
o2 = i.next();
}
assertTrue("Expected WfCreateProcessAuditEvent, found " + o,
o instanceof WfCreateProcessAuditEvent);
cpae = (WfCreateProcessAuditEvent)o;
assertTrue(cpae.eventType().equals("processCreated"));
assertTrue(cpae.processName().equals("Audit Tests"));
assertTrue(cpae.activityKey() == null);
assertTrue(cpae.activityName() == null);
assertTrue(cpae.processMgrName().equals("ut-procdef-audit/auditTest"));
assertTrue(cpae.processMgrVersion().equals("1.42"));
assertTrue(cpae.pActivityKey() == null);
assertTrue(cpae.pProcessKey() == null);
assertTrue(cpae.pProcessName() == null);
assertTrue(cpae.pProcessMgrName() == null);
assertTrue(cpae.pProcessMgrVersion() == null);
// the second event is required to signal a process context change
o = o2;
assertTrue(o instanceof WfDataAuditEvent);
dae = (WfDataAuditEvent)o;
assertTrue(dae.eventType().equals("processContextChanged"));
assertTrue(dae.processName().equals("Audit Tests"));
assertTrue(dae.activityKey() == null);
assertTrue(dae.activityName() == null);
assertTrue(dae.processMgrName().equals("ut-procdef-audit/auditTest"));
assertTrue(dae.processMgrVersion().equals("1.42"));
assertTrue(dae.oldData().isEmpty());
ProcessData newData = dae.newData();
assertTrue("Size should be 3, is " + newData.size(),
newData.size()==3);
assertTrue(newData.keySet().contains("status"));
String data = (String)(newData.get("status"));
assertTrue(data == null);
assertTrue(newData.keySet().contains("testData"));
data = (String)(newData.get("testData"));
assertTrue(data.equals("relevante Process Test Daten"));
assertTrue(newData.keySet().contains("emailAddress"));
data = (String)(newData.get("emailAddress"));
assertTrue(data.equals("account@bank.com"));
}
/* ********************************************************************* */
/**
* Changes the activity result
* @throws Exception ...
*/
public void changeActivityResult() throws Exception {
// create the process
createProcessAndProcessContextChanged();
// start the process
// since the first activity declared as "Automatic" it is started
// automatically calling the defined application setting a string
// which may be currently found in the log
process.start();
// wait some time because of asynchronous processing
Thread.sleep(5000);
// get first activity started automatically
WfActivity a = actByName (process, "A21");
// check audit event(s) of first activity
Collection activityEvents = a.history();
//displayAuditEvents(activityEvents);
checkAuditEventsForActivity21(activityEvents);
// get second activity not started automatically
a = actByName (process, "A22");
// check audit event(s) of second activity
activityEvents = a.history();
//displayAuditEvents(activityEvents);
checkAuditEventsForActivityA22(activityEvents);
// check audit event(s) of process
Collection processEvents = process.history();
//displayAuditEvents(processEvents);
checkProcessAuditEventsForChangeActivityResult(processEvents);
}
/**
* Checks the collection of audit events for activty A21.
* @param auditEvents the audit events to display
*/
private void checkAuditEventsForActivity21(Collection auditEvents){
assertTrue(auditEvents.size() == 3);
List sorted = new ArrayList (auditEvents);
Collections.sort (sorted, new Comparator () {
public int compare (Object o1, Object o2) {
if (((WfAuditEvent)o1).timeStamp()
.equals(((WfAuditEvent)o2).timeStamp())) {
return 0;
}
if (((WfAuditEvent)o1).timeStamp()
.before(((WfAuditEvent)o2).timeStamp())) {
return -1;
}
return 1;
}
});
Iterator i = sorted.iterator();
// the first event is required to signal a state change
i.hasNext();
Object o = i.next();
assertTrue(o instanceof WfStateAuditEvent);
sae = (WfStateAuditEvent)o;
assertTrue(sae.eventType().equals("activityStateChanged"));
assertTrue(sae.processName().equals("Audit Tests"));
assertTrue(sae.activityKey() != null);
assertTrue(sae.activityName().equals("A21"));
assertTrue(sae.processMgrName().equals("ut-procdef-audit/auditTest"));
assertTrue(sae.processMgrVersion().equals("1.42"));
assertTrue(sae.oldState().startsWith("open.not_running.not_started"));
assertTrue(sae.newState().startsWith("open.running.running"));
// the second event is required to signal an activity result change,
// timestamps aren't precise enough, though
Object dataEvent = i.next();
Object stateEvent = i.next();
if (stateEvent instanceof WfDataAuditEvent) {
assertTrue (((WfAuditEvent)stateEvent).timeStamp()
.equals(((WfAuditEvent)dataEvent).timeStamp()));
Object h = dataEvent;
dataEvent = stateEvent;
stateEvent = h;
}
o = dataEvent;
assertTrue(o instanceof WfDataAuditEvent);
dae = (WfDataAuditEvent)o;
assertTrue(dae.eventType().equals("activityResultChanged"));
assertTrue(dae.processName().equals("Audit Tests"));
assertTrue(dae.activityKey() != null);
assertTrue(dae.activityName().equals("A21"));
assertTrue(dae.processMgrName().equals("ut-procdef-audit/auditTest"));
assertTrue(dae.processMgrVersion().equals("1.42"));
assertTrue(dae.oldData().isEmpty());
ProcessData newData = dae.newData();
assertTrue(newData.size()==1);
Iterator j = newData.keySet().iterator();
j.hasNext();
String key = (String)j.next();
assertTrue(key.equals("statusOut"));
String data = (String)(newData.get(key));
assertTrue(data.equals("Sent to: account@bank.com"));
// the third event is required to signal a state change
o = stateEvent;
assertTrue(o instanceof WfStateAuditEvent);
sae = (WfStateAuditEvent)o;
assertTrue(sae.eventType().equals("activityStateChanged"));
assertTrue(sae.processName().equals("Audit Tests"));
assertTrue(sae.activityKey() != null);
assertTrue(sae.activityName().equals("A21"));
assertTrue(sae.processMgrName().equals("ut-procdef-audit/auditTest"));
assertTrue(sae.processMgrVersion().equals("1.42"));
assertTrue(sae.oldState().equals("open.running.running"));
assertTrue(sae.newState().startsWith("closed.completed"));
}
/**
* Checks the collection of audit events for activty A21.
* @param auditEvents the audit events to display
*/
private void checkAuditEventsForActivityA22(Collection auditEvents){
assertTrue(auditEvents.size() == 2);
List sorted = new ArrayList (auditEvents);
Collections.sort (sorted, new Comparator () {
public int compare (Object o1, Object o2) {
if (((WfAuditEvent)o1).timeStamp()
.equals(((WfAuditEvent)o2).timeStamp())) {
return 0;
}
if (((WfAuditEvent)o1).timeStamp()
.before(((WfAuditEvent)o2).timeStamp())) {
return -1;
}
return 1;
}
});
Iterator i = sorted.iterator();
// the first event is required to signal a state change
i.hasNext();
Object o = i.next();
assertTrue(o instanceof WfStateAuditEvent);
sae = (WfStateAuditEvent)o;
assertTrue(sae.eventType().equals("activityStateChanged"));
assertTrue(sae.processName().equals("Audit Tests"));
assertTrue(sae.activityKey() != null);
assertTrue(sae.activityName().equals("A22"));
assertTrue(sae.processMgrName().equals("ut-procdef-audit/auditTest"));
assertTrue(sae.processMgrVersion().equals("1.42"));
assertTrue(sae.oldState().startsWith("open.not_running.not_started"));
assertTrue(sae.newState().startsWith("open.running.running"));
//assertTrue(sae.newState().equals("open.running.started"));
// the second event is required to signal a state change
i.hasNext();
o = i.next();
assertTrue(o instanceof WfStateAuditEvent);
sae = (WfStateAuditEvent)o;
assertTrue(sae.eventType().equals("activityStateChanged"));
assertTrue(sae.processName().equals("Audit Tests"));
assertTrue(sae.activityKey() != null);
assertTrue(sae.activityName().equals("A22"));
assertTrue(sae.processMgrName().equals("ut-procdef-audit/auditTest"));
assertTrue(sae.processMgrVersion().equals("1.42"));
assertTrue(sae.oldState().startsWith("open.running.running"));
assertTrue(sae.newState().startsWith("open.not_running.suspended"));
}
/**
* Checks the collection of audit events for test case "createProcess"
* @param auditEvents the audit events to display
*/
private void checkProcessAuditEventsForChangeActivityResult
(Collection auditEvents){
assertTrue(auditEvents.size()==4);
SortedMap sorted = new TreeMap ();
for (Iterator i = auditEvents.iterator(); i.hasNext();) {
WfAuditEvent ae = (WfAuditEvent)i.next ();
sorted.put (ae.timeStamp(), ae);
}
for (Iterator i = sorted.values().iterator(); i.hasNext();) {
Object o = i.next();
if (o instanceof WfCreateProcessAuditEvent) {
cpae = (WfCreateProcessAuditEvent)o;
} else if ((o instanceof WfDataAuditEvent) && dae == null) {
dae = (WfDataAuditEvent)o;
} else if (o instanceof WfStateAuditEvent) {
sae = (WfStateAuditEvent)o;
} else if (o instanceof WfDataAuditEvent) {
dae2 = (WfDataAuditEvent)o;
}
}
assertTrue (cpae != null);
assertTrue (dae != null);
assertTrue (sae != null);
assertTrue (dae2 != null);
assertTrue("This may fail with MySQL because it does not keep ms time.",
sae.eventType().equals("processStateChanged"));
assertTrue(sae.processName().equals("Audit Tests"));
assertTrue(sae.activityKey() == null);
assertTrue(sae.activityName() == null);
assertTrue(sae.processMgrName().equals("ut-procdef-audit/auditTest"));
assertTrue(sae.processMgrVersion().equals("1.42"));
assertTrue(sae.oldState().equals("open.not_running.not_started"));
assertTrue(sae.newState().equals("open.running.running"));
assertTrue(dae2.eventType().equals("processContextChanged"));
assertTrue(dae2.processName().equals("Audit Tests"));
assertTrue(dae2.activityKey() == null);
assertTrue(dae2.activityName() == null);
assertTrue(dae2.processMgrName().equals("ut-procdef-audit/auditTest"));
assertTrue(dae2.processMgrVersion().equals("1.42"));
ProcessData oldData = dae2.oldData();
assertTrue(oldData.size()==1);
Iterator j = oldData.keySet().iterator();
j.hasNext();
String key = (String)j.next();
assertTrue(key.equals("status"));
String data = (String)(oldData.get(key));
assertTrue(data == null);
ProcessData newData = dae2.newData();
assertTrue(newData.size()==1);
Iterator k = newData.keySet().iterator();
k.hasNext();
key = (String)k.next();
assertTrue(key.equals("status"));
data = (String)(newData.get(key));
assertTrue(data.equals("Sent to: account@bank.com"));
}
public void waitForCompletion () throws Exception {
// Obtain subscriber
EventSubscriber subs = workflowService().createEventSubscriber ();
// create the required process
WfRequester req = new DefaultRequester (workflowService());
process = createProcess("ut-procdef-audit", "auditTest2", req);
String procKey = process.key();
assertTrue(process!=null);
process.start ();
WfAuditEvent e = null;
while (true) {
e = subs.receive(5000);
assertTrue ("Timeout receiving event", e != null);
if (e.eventType().equals (WfAuditEvent.PROCESS_STATE_CHANGED)
&& e.processKey().equals (procKey)
&& ((WfStateAuditEvent)e).newState().startsWith ("closed")) {
break;
}
}
assertTrue (e instanceof ProcessClosedAuditEvent);
ProcessData res = ((ProcessClosedAuditEvent)e).result();
assertTrue (res.keySet().size() == 2);
assertTrue (res.keySet().contains("outVal1"));
assertTrue (res.keySet().contains("inOutVal1"));
assertTrue (subs.receive(2500) == null);
workflowService().release (subs);
}
public void testFilters () throws Exception {
// Obtain subscribers
EventSubscriber subs = workflowService().createEventSubscriber ();
// create the required process
WfRequester req = new DefaultRequester (workflowService());
process = createProcess("ut-procdef-audit", "auditTest2", req);
String procKey = process.key();
assertTrue(process != null);
// additional subscribers
final int[] counters = new int[5];
EventSubscriber subsAll = workflowService().createEventSubscriber ();
subsAll.setEventHandler(new WfAuditHandler () {
public void receiveEvent (WfAuditEvent e) {
counters[0] += 1;
}
});
EventSubscriber subsProc = workflowService()
.createEventSubscriber (procKey, null);
subsProc.setEventHandler(new WfAuditHandler () {
public void receiveEvent (WfAuditEvent e) {
counters[1] += 1;
}
});
EventSubscriber subsPSC = workflowService().createEventSubscriber
(procKey, WfAuditEvent.PROCESS_STATE_CHANGED);
subsPSC.setEventHandler(new WfAuditHandler () {
public void receiveEvent (WfAuditEvent e) {
assertTrue (e.eventType().equals
(WfAuditEvent.PROCESS_STATE_CHANGED));
counters[2] += 1;
}
});
EventSubscriber subsASC = workflowService().createEventSubscriber
(procKey, WfAuditEvent.ACTIVITY_STATE_CHANGED);
subsASC.setEventHandler(new WfAuditHandler () {
public void receiveEvent (WfAuditEvent e) {
assertTrue (e.eventType().equals
(WfAuditEvent.ACTIVITY_STATE_CHANGED));
counters[3] += 1;
}
});
EventSubscriber subsPASC = workflowService().createEventSubscriber
(procKey, WfAuditEvent.PROCESS_STATE_CHANGED
+ ", " + WfAuditEvent.ACTIVITY_STATE_CHANGED);
subsPASC.setEventHandler(new WfAuditHandler () {
public void receiveEvent (WfAuditEvent e) {
assertTrue (e.eventType().equals
(WfAuditEvent.PROCESS_STATE_CHANGED)
|| e.eventType().equals
(WfAuditEvent.ACTIVITY_STATE_CHANGED));
counters[4] += 1;
}
});
process.start ();
while (true) {
WfAuditEvent e = subs.receive(5000);
assertTrue ("Timeout receiving event", e != null);
if (e.eventType().equals (WfAuditEvent.PROCESS_STATE_CHANGED)
&& e.processKey().equals (procKey)
&& ((WfStateAuditEvent)e).newState().startsWith ("closed")) {
break;
}
}
// allow delivery of events
Thread.sleep(2500);
assertTrue ("All events: " + counters[0] + " (should be >= 14)",
counters[0] >= 14);
assertTrue ("Process events: " + counters[1]
+ " (should be 14 or 15)",
14 <= counters[1] && counters[1] <= 16);
assertTrue ("Process state changes: " + counters[2] + " (should be 2)",
counters[2] == 2);
assertTrue ("Activity state changes: " + counters[3] + " (should be 8)",
counters[3] == 8);
assertTrue ("All state changes: " + counters[4] + " (should be 10)",
counters[4] == 10);
workflowService().release (subs);
workflowService().release (subsAll);
workflowService().release (subsProc);
workflowService().release (subsPSC);
workflowService().release (subsASC);
workflowService().release (subsPASC);
}
public void testStateFilter () throws Exception {
// Obtain subscribers
// create the required process
WfRequester req = new DefaultRequester (workflowService());
process = createProcess("ut-procdef-audit", "auditStateOnly", req);
assertTrue(process != null);
process.start ();
assertTrue (stateReached (process, "closed"));
int hs = process.history().size ();
for (Iterator i = process.steps().iterator(); i.hasNext ();) {
WfActivity act = (WfActivity)i.next();
hs += act.history().size();
}
assertTrue ("History size should be 4, is " + hs, hs == 4);
}
public void testClosedFilter () throws Exception {
// Obtain subscribers
// create the required process
WfRequester req = new DefaultRequester (workflowService());
process = createProcess("ut-procdef-audit", "auditProcClosedOnly", req);
assertTrue(process != null);
process.start ();
assertTrue (stateReached (process, "closed"));
int hs = process.history().size ();
for (Iterator i = process.steps().iterator(); i.hasNext ();) {
WfActivity act = (WfActivity)i.next();
hs += act.history().size();
}
assertTrue (hs == 1);
}
/* ********************************************************************* */
/* HELPER methods */
/* ********************************************************************* */
private WfActivity actByName(WfProcess proc, String name) throws Exception {
WfActivity a = null;
for (Iterator it = proc.steps().iterator(); it.hasNext(); ) {
WfActivity ai = (WfActivity)it.next();
if (ai.name().equals (name)) {
a = ai;
break;
}
}
return a;
}
/**
* Import the process definitions from a XPDL file
* unsing the ProcessDefinitionDirectory.
*/
public void importProcessDefinitions() throws Exception {
ProcessDefinitionDirectory pdd = null;
try {
pdd = workflowService().processDefinitionDirectory();
InputStream is = getClass()
.getResourceAsStream("/process/auditing.xml");
assertTrue (is != null);
BufferedReader br = new BufferedReader
(new InputStreamReader(is, "ISO-8859-1"));
StringBuffer sb = new StringBuffer();
String st;
while ((st = br.readLine()) != null) {
sb.append(st + "\n");
}
pdd.importProcessDefinitions(sb.toString());
Collection processDefinitions = pdd.processDefinitions();
assertTrue (processDefinitions.size() > 1);
} finally {
workflowService().release (pdd);
}
}
/**
* Creates the process
* using the ProcessDefinitionDirectory bean.
*/
private WfProcess createProcess
(String pkgId, String prcId, WfRequester req)
throws Exception {
ProcessDefinitionDirectory procDir = null;
try {
procDir = workflowService().processDefinitionDirectory ();
ProcessMgr pmgr = procDir.processMgr(pkgId, prcId);
return pmgr.createProcess (req);
} finally {
workflowService().release (procDir);
}
}
private boolean stateReached(WfProcess proc, String procState)
throws Exception {
int maxRetries = 30;
while (true){
if (proc.state().startsWith(procState)) {
return true;
}
if (maxRetries-- <= 0) {
return false;
}
Thread.sleep(1000);
}
}
/**
* Displays the collection of process data
* @param processData the process data to display
*/
private void displayProcessData(ProcessData processData){
for (Iterator i = processData.keySet().iterator(); i.hasNext();) {
String key = (String)i.next();
Object o = processData.get(key);
System.err.println(key + " = " + o);
}
}
/**
* Displays the collection of audit events
* @param auditEvents the audit events to display
*/
private void displayAuditEvents(Collection auditEvents){
for (Iterator i = auditEvents.iterator(); i.hasNext();) {
Object o = i.next();
WfAuditEvent ae = (WfAuditEvent)o;
System.err.println(" --------------------- ");
System.err.println(" event type = " + ae.eventType());
System.err.println(" time stamp = " + ae.timeStamp());
System.err.println(" activity key = " + ae.activityKey());
System.err.println(" activity name = " + ae.activityName());
System.err.println(" process key = " + ae.processKey());
System.err.println(" process name = " + ae.processName());
System.err.println(" process manager name = "
+ ae.processMgrName());
System.err.println(" process manager version = "
+ ae.processMgrVersion());
if (o instanceof WfAssignmentAuditEvent){
WfAssignmentAuditEvent aae =(WfAssignmentAuditEvent)o;
System.err.println(" old resource key = "
+ aae.oldResourceKey());
System.err.println(" new resource key = "
+ aae.newResourceKey());
System.err.println(" old resource name = "
+ aae.oldResourceName());
System.err.println(" new resource name = "
+ aae.newResourceName());
} else if (o instanceof WfCreateProcessAuditEvent){
WfCreateProcessAuditEvent cpae = (WfCreateProcessAuditEvent)o;
System.err.println(" parent activity key = "
+ cpae.pActivityKey());
System.err.println(" parent process key = "
+ cpae.pProcessKey());
System.err.println(" parent process name = "
+ cpae.pProcessName());
System.err.println(" parent process manager name = "
+ cpae.pProcessMgrName());
System.err.println(" parent process manager version = "
+ cpae.pProcessMgrVersion());
} else if (o instanceof WfDataAuditEvent){
WfDataAuditEvent dae =(WfDataAuditEvent)o;
System.err.println(" old data = " + dae.oldData());
System.err.println(" new data = " + dae.newData());
} else if (o instanceof WfStateAuditEvent){
WfStateAuditEvent sae =(WfStateAuditEvent)o;
System.err.println(" old state = " + sae.oldState());
System.err.println(" new state = " + sae.newState());
}
}
}
}