package org.jbpm.sim; import java.util.List; import org.jbpm.graph.exe.ExecutionContext; import org.jbpm.graph.exe.ProcessInstance; import org.jbpm.sim.datasource.ProcessDataFilter; import org.jbpm.sim.datasource.ProcessDataSource; import org.jbpm.sim.def.JbpmSimulationExperiment; import org.jbpm.sim.def.JbpmSimulationScenario; import org.jbpm.sim.exe.ExperimentReader; public class VariableSourceAndFilterTest extends AbstractSimTestCase { private static final String testProcessXml = "<process-definition name='test' start-distribution='startDist'>" + " <start-state name='start'>" + " <transition to='change order' />" + " </start-state>" + " <task-node name='change order'>" + " <task name='change order' swimlane='clerk' />" + " <transition to='end' />" + " </task-node>" + " <end-state name='end'/>" + "</process-definition>"; private static final String experimentConfiguration = "<experiment name='MySimulationExperiment'" + " run-time='100'" + " real-start-time='01.01.1970 01:00:00:002'" + " time-unit='minute'>" + " <scenario name ='test'>" + " <distribution name='startDist' sample-type='real' type='constant' value='20' /> " + " <distribution name='taskDist' sample-type='real' type='constant' value='20' /> " + " <resource-pool name='clerk' pool-size='1'/> " + " <data-source name='orders' " + " handler='org.jbpm.sim.VariableSourceAndFilterTest$TestProcessVariableSource' /> " + " <data-filter name='orders' " + " handler='org.jbpm.sim.VariableSourceAndFilterTest$TestProcessVariableFilter' /> " + " <sim-process name='test'>" + " <process-overwrite start-distribution='startDist'> " + " <use-data-source name='orders' /> " + " </process-overwrite> " + " <task-overwrite task-name='change order' time-distribution='taskDist'>" + " <use-data-filter name='orders' /> " + " </task-overwrite> " + " </sim-process>" + " </scenario>" + " <output path='target' />" // currently just used as parameter for DESMO-J + "</experiment>"; static boolean dataSourceIsCalled = false; static boolean dataFilterIsCalled = false; public static class TestProcessVariableSource implements ProcessDataSource { public void addNextData(ExecutionContext ctx) { dataSourceIsCalled = true; ctx.getContextInstance().createVariable("test", "Hello Bernd"); } public boolean hasNext() { return true; } public void reset() { } } public static class TestProcessVariableFilter implements ProcessDataFilter { public void changeProcessData(ExecutionContext ctx) { dataFilterIsCalled = true; String test = (String) ctx.getContextInstance().getVariable("test"); test += ", how are you?"; ctx.getContextInstance().setVariable("test", test); } public void reset() { } } public void testSourceAndFilter() { ExperimentReader reader = new ExperimentReader(experimentConfiguration); // inject process definition reader.addProcessDefinition("test", testProcessXml); JbpmSimulationExperiment experiment = reader.readExperiment(); experiment.setRememberEndedProcessInstances(true); experiment.run(); assertTrue(dataSourceIsCalled); assertTrue(dataFilterIsCalled); JbpmSimulationScenario scenario = experiment.getScenario("test"); ProcessInstance pi = (ProcessInstance) scenario.getEndedProcessInstances().iterator().next(); assertEquals("Hello Bernd, how are you?", pi.getContextInstance().getVariable("test")); // simulation runs till the end assertEquals(100, scenario.getScenarioReport().getSimulationRunTime(), 0.001); } private static final String experimentConfiguration2 = "<experiment name='MySimulationExperiment'" + " run-time='100'" + " real-start-time='01.01.1970 01:00:00:002'" + " time-unit='minute'>" + " <scenario name ='test'>" + " <distribution name='startDist' sample-type='real' type='constant' value='20' /> " + " <distribution name='taskDist' sample-type='real' type='constant' value='20' /> " + " <resource-pool name='clerk' pool-size='1'/> " + " <data-source name='orders' " + " handler='org.jbpm.sim.VariableSourceAndFilterTest$TestProcessVariableSourceExhausting' /> " + " <sim-process name='test'>" + " <process-overwrite start-distribution='startDist'> " + " <use-data-source name='orders' /> " + " </process-overwrite> " + " <task-overwrite task-name='change order' time-distribution='taskDist' />" + " </sim-process>" + " </scenario>" + " <output path='target' />" // currently just used as parameter for DESMO-J + "</experiment>"; static int calledCount = 0; public static class TestProcessVariableSourceExhausting implements ProcessDataSource { public void addNextData(ExecutionContext ctx) { calledCount++; ctx.getContextInstance().createVariable("test", new Integer(calledCount)); } public boolean hasNext() { return (calledCount < 3); } public void reset() { } } /** * use a data source which provides data only three times, the simulation should be ended after * the third query, at this time two processes are ended */ public void testSimulationStopIfSourceIsExhausted() { ExperimentReader reader = new ExperimentReader(experimentConfiguration2); // inject process definition reader.addProcessDefinition("test", testProcessXml); JbpmSimulationExperiment experiment = reader.readExperiment(); experiment.setRememberEndedProcessInstances(true); experiment.run(); JbpmSimulationScenario scenario = experiment.getScenario("test"); List processes = scenario.getEndedProcessInstances(); assertEquals(3, calledCount); assertEquals(2, processes.size()); assertEquals(new Integer(1), ((ProcessInstance) processes.get(0)).getContextInstance() .getVariable("test")); assertEquals(new Integer(2), ((ProcessInstance) processes.get(1)).getContextInstance() .getVariable("test")); // after two processes the simulation should end, this is 60 time units assertEquals(60, scenario.getScenarioReport().getSimulationRunTime(), 0.001); } }