/** * Copyright 2010 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jbpm.process; import static org.jbpm.process.test.NodeCreator.connect; import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.List; import org.drools.core.process.core.Work; import org.drools.core.process.core.datatype.impl.type.ObjectDataType; import org.drools.core.process.core.impl.WorkImpl; import org.jbpm.process.core.context.variable.Variable; import org.jbpm.process.core.event.EventTypeFilter; import org.jbpm.process.instance.impl.Action; import org.jbpm.process.test.NodeCreator; import org.jbpm.process.test.TestProcessEventListener; import org.jbpm.process.test.TestWorkItemHandler; import org.jbpm.ruleflow.core.RuleFlowProcess; import org.jbpm.test.util.AbstractBaseTest; import org.jbpm.workflow.core.DroolsAction; import org.jbpm.workflow.core.impl.DroolsConsequenceAction; import org.jbpm.workflow.core.node.ActionNode; import org.jbpm.workflow.core.node.CompositeNode; import org.jbpm.workflow.core.node.EndNode; import org.jbpm.workflow.core.node.EventSubProcessNode; import org.jbpm.workflow.core.node.StartNode; import org.jbpm.workflow.core.node.WorkItemNode; import org.junit.Test; import org.kie.api.runtime.KieSession; import org.kie.api.runtime.process.ProcessContext; import org.kie.api.runtime.process.ProcessInstance; import org.slf4j.LoggerFactory; public class EventSubProcessTest extends AbstractBaseTest { public void addLogger() { logger = LoggerFactory.getLogger(this.getClass()); } String [] nestedEventOrder = { "bps", "bnt-0", "bnl-0", "bnt-1", "bnt-1:3", "bnl-1:3", "bnt-1:4", "bnt-1:4:5", "bnl-1:4:5", "bnt-1:4:6", "ant-1:4:6", "anl-1:4:5", "ant-1:4:5", "ant-1:4", "anl-1:3", "ant-1:3", "ant-1", "anl-0", "ant-0", "aps", "bnl-1:4:7:8", "bnt-1:4:7:9", "bnl-1:4:7:9", "bnt-1:4:7:10","bnl-1:4:7:10", "bnl-1:4:7", "anl-1:4:7", "anl-1:4:7:10","ant-1:4:7:10", "anl-1:4:7:9", "ant-1:4:7:9", "anl-1:4:7:8", "bnl-1:4:6", "bnt-1:4:11", "bnl-1:4:11", "bnl-1:4", "bnt-1:12", "bnl-1:12", "bnl-1", "bnt-12", "bnl-12", "bpc", "apc", "anl-12", "ant-12", "anl-1", "anl-1:12", "ant-1:12", "anl-1:4", "anl-1:4:11", "ant-1:4:11", "anl-1:4:6" }; @Test public void testNestedEventSubProcess() throws Exception { RuleFlowProcess process = new RuleFlowProcess(); process.setAutoComplete(true); String processId = "org.jbpm.process.event.subprocess"; process.setId(processId); process.setName("Event SubProcess Process"); List<Variable> variables = new ArrayList<Variable>(); Variable variable = new Variable(); variable.setName("event"); ObjectDataType personDataType = new ObjectDataType(); personDataType.setClassName("org.drools.Person"); variable.setType(personDataType); variables.add(variable); process.getVariableScope().setVariables(variables); NodeCreator<StartNode> startNodeCreator = new NodeCreator<StartNode>(process, StartNode.class); NodeCreator<EndNode> endNodeCreator = new NodeCreator<EndNode>(process, EndNode.class); NodeCreator<CompositeNode> compNodeCreator = new NodeCreator<CompositeNode>(process, CompositeNode.class); // outer process StartNode startNode = startNodeCreator.createNode("start0"); CompositeNode compositeNode = compNodeCreator.createNode("comp0"); connect( startNode, compositeNode ); EndNode endNode = endNodeCreator.createNode("end0"); connect( compositeNode, endNode ); // 1rst level nested subprocess startNodeCreator.setNodeContainer(compositeNode); endNodeCreator.setNodeContainer(compositeNode); compNodeCreator.setNodeContainer(compositeNode); startNode = startNodeCreator.createNode("start1"); compositeNode = compNodeCreator.createNode("comp1"); connect( startNode, compositeNode ); endNode = endNodeCreator.createNode("end1"); connect( compositeNode, endNode ); // 2nd level subprocess startNodeCreator.setNodeContainer(compositeNode); endNodeCreator.setNodeContainer(compositeNode); NodeCreator<WorkItemNode> workItemNodeCreator = new NodeCreator<WorkItemNode>(compositeNode, WorkItemNode.class); startNode = startNodeCreator.createNode("start2"); WorkItemNode workItemNode = workItemNodeCreator.createNode("workItem2"); Work work = new WorkImpl(); String workItemName = "play"; work.setName( workItemName ); workItemNode.setWork(work); connect( startNode, workItemNode ); endNode = endNodeCreator.createNode("end2"); connect( workItemNode, endNode ); // (3rd level) event sub process in 2nd level subprocess NodeCreator<EventSubProcessNode> espNodeCreator = new NodeCreator<EventSubProcessNode>(compositeNode, EventSubProcessNode.class); EventSubProcessNode espNode = espNodeCreator.createNode("eventSub2"); EventTypeFilter eventFilter = new EventTypeFilter(); String EVENT_NAME = "subEvent"; eventFilter.setType(EVENT_NAME); espNode.addEvent(eventFilter); startNodeCreator.setNodeContainer(espNode); endNodeCreator.setNodeContainer(espNode); NodeCreator<ActionNode> actionNodeCreator = new NodeCreator<ActionNode>(espNode, ActionNode.class); startNode = startNodeCreator.createNode("start3*"); ActionNode actionNode = actionNodeCreator.createNode("print3*"); actionNode.setName("Print"); final List<String> eventList = new ArrayList<String>(); DroolsAction action = new DroolsConsequenceAction("java", null); action.setMetaData("Action", new Action() { public void execute(ProcessContext context) throws Exception { eventList.add("Executed action"); } }); actionNode.setAction(action); connect( startNode, actionNode ); endNode = endNodeCreator.createNode("end3*"); connect( actionNode, endNode ); // run process KieSession ksession = createKieSession(process); TestProcessEventListener procEventListener = new TestProcessEventListener(); ksession.addEventListener(procEventListener); TestWorkItemHandler workItemHandler = new TestWorkItemHandler(); ksession.getWorkItemManager().registerWorkItemHandler(workItemName, workItemHandler); ProcessInstance processInstance = ksession.startProcess(processId); processInstance.signalEvent(EVENT_NAME, null); assertEquals("Event " + EVENT_NAME + " did not fire!", 1, eventList.size()); ksession.getWorkItemManager().completeWorkItem(workItemHandler.getWorkItems().removeLast().getId(), null); assertEquals(ProcessInstance.STATE_COMPLETED, processInstance.getState()); verifyEventHistory(nestedEventOrder, procEventListener.getEventHistory()); } }