/* * Copyright 2014 Effektif GmbH. * * 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 com.effektif.workflow.test.impl; import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.effektif.workflow.api.activities.EndEvent; import com.effektif.workflow.api.activities.NoneTask; import com.effektif.workflow.api.activities.ParallelGateway; import com.effektif.workflow.api.activities.StartEvent; import com.effektif.workflow.api.workflow.ExecutableWorkflow; import com.effektif.workflow.api.workflowinstance.WorkflowInstance; import com.effektif.workflow.impl.WorkflowEngineImpl; import com.effektif.workflow.impl.WorkflowExecutionListener; import com.effektif.workflow.impl.workflow.TransitionImpl; import com.effektif.workflow.impl.workflowinstance.ActivityInstanceImpl; import com.effektif.workflow.impl.workflowinstance.WorkflowInstanceImpl; import com.effektif.workflow.test.WorkflowTest; /** * @author Tom Baeyens */ public class WorkflowExecutionListenerTest extends WorkflowTest { private class LoggingListener implements WorkflowExecutionListener { private List<String> events = new ArrayList<>(); public List<String> getEvents() { return Collections.unmodifiableList(events); } @Override public boolean starting(ActivityInstanceImpl instance) { events.add("start " + instance.activity.id); return true; } @Override public void ended(ActivityInstanceImpl instance) { events.add("end " + instance.activity.id); } @Override public boolean transitioning(ActivityInstanceImpl activityInstanceFrom, TransitionImpl transition, ActivityInstanceImpl activityInstanceTo) { events.add("take "+transition.from.id+"->"+transition.to.id); return true; } @Override public void flush(WorkflowInstanceImpl workflowInstance) { events.add("flush"); } @Override public void insert(WorkflowInstanceImpl workflowInstance) { events.add("insert"); } @Override public void starting(WorkflowInstanceImpl workflowInstance) { events.add("start workflow instance"); } @Override public void ended(WorkflowInstanceImpl workflowInstance) { events.add("end workflow instance"); } @Override public void unlocked(WorkflowInstanceImpl workflowInstance) { } } LoggingListener listener; @Override @Before public void initializeWorkflowEngine() { super.initializeWorkflowEngine(); listener = new LoggingListener(); ((WorkflowEngineImpl) workflowEngine) .addWorkflowExecutionListener(listener); } @After public void removeListener() { ((WorkflowEngineImpl) workflowEngine) .removeWorkflowExecutionListener(listener); } @Test public void testBasicEvents() { ExecutableWorkflow workflow = new ExecutableWorkflow() .activity("s", new StartEvent() .transitionTo("t")) .activity("t", new NoneTask() .transitionTo("e")) .activity("e", new EndEvent()); deploy(workflow); start(workflow); int i = 0; assertEquals("start workflow instance", listener.getEvents().get(i++)); assertEquals("insert", listener.getEvents().get(i++)); assertEquals("start s", listener.getEvents().get(i++)); assertEquals("end s", listener.getEvents().get(i++)); assertEquals("take s->t", listener.getEvents().get(i++)); assertEquals("start t", listener.getEvents().get(i++)); assertEquals("end t", listener.getEvents().get(i++)); assertEquals("take t->e", listener.getEvents().get(i++)); assertEquals("start e", listener.getEvents().get(i++)); assertEquals("end e", listener.getEvents().get(i++)); assertEquals("end workflow instance", listener.getEvents().get(i++)); } @Test public void testParallelGatewayFullEvents() { // /- a -\ // s - g1 -X X- g2 - e // \- b -/ ExecutableWorkflow workflow = new ExecutableWorkflow() .activity("s", new NoneTask() .transitionTo("g1")) .activity("g1", new ParallelGateway() .transitionTo("a") .transitionTo("b")) .activity("a", new NoneTask() .transitionTo("g2")) .activity("b", new NoneTask() .transitionTo("g2")) .activity("g2", new ParallelGateway() .transitionTo("e")) .activity("e", new EndEvent()); deploy(workflow); start(workflow); // there are no flush events because the activities used have isFlushSkippable==true int i = 0; assertEquals("start workflow instance", listener.getEvents().get(i++)); assertEquals("insert", listener.getEvents().get(i++)); assertEquals("start s", listener.getEvents().get(i++)); assertEquals("end s", listener.getEvents().get(i++)); assertEquals("take s->g1", listener.getEvents().get(i++)); assertEquals("start g1", listener.getEvents().get(i++)); assertEquals("end g1", listener.getEvents().get(i++)); assertEquals("take g1->a", listener.getEvents().get(i++)); assertEquals("take g1->b", listener.getEvents().get(i++)); assertEquals("start a", listener.getEvents().get(i++)); assertEquals("end a", listener.getEvents().get(i++)); assertEquals("take a->g2", listener.getEvents().get(i++)); assertEquals("start b", listener.getEvents().get(i++)); assertEquals("end b", listener.getEvents().get(i++)); assertEquals("take b->g2", listener.getEvents().get(i++)); assertEquals("start g2", listener.getEvents().get(i++)); assertEquals("end g2", listener.getEvents().get(i++)); assertEquals("start g2", listener.getEvents().get(i++)); assertEquals("end g2", listener.getEvents().get(i++)); assertEquals("take g2->e", listener.getEvents().get(i++)); assertEquals("start e", listener.getEvents().get(i++)); assertEquals("end e", listener.getEvents().get(i++)); assertEquals("end workflow instance", listener.getEvents().get(i++)); } @Test public void testParallelGatewayDirectEvents() { // /- - -\ // s - g1 -X X- g2 - e // \- b -/ ExecutableWorkflow workflow = new ExecutableWorkflow() .activity("s", new StartEvent() .transitionTo("g1")) .activity("g1", new ParallelGateway() .transitionTo("g2") .transitionTo("b")) .activity("b", new NoneTask() .transitionTo("g2")) .activity("g2", new ParallelGateway() .transitionTo("e")) .activity("e", new EndEvent()); deploy(workflow); start(workflow); // there are no flush events because the activities used have isFlushSkippable==true int i = 0; assertEquals("start workflow instance", listener.getEvents().get(i++)); assertEquals("insert", listener.getEvents().get(i++)); assertEquals("start s", listener.getEvents().get(i++)); assertEquals("end s", listener.getEvents().get(i++)); assertEquals("take s->g1", listener.getEvents().get(i++)); assertEquals("start g1", listener.getEvents().get(i++)); assertEquals("end g1", listener.getEvents().get(i++)); assertEquals("take g1->g2", listener.getEvents().get(i++)); assertEquals("take g1->b", listener.getEvents().get(i++)); assertEquals("start g2", listener.getEvents().get(i++)); assertEquals("end g2", listener.getEvents().get(i++)); assertEquals("start b", listener.getEvents().get(i++)); assertEquals("end b", listener.getEvents().get(i++)); assertEquals("take b->g2", listener.getEvents().get(i++)); assertEquals("start g2", listener.getEvents().get(i++)); assertEquals("end g2", listener.getEvents().get(i++)); assertEquals("take g2->e", listener.getEvents().get(i++)); assertEquals("start e", listener.getEvents().get(i++)); assertEquals("end e", listener.getEvents().get(i++)); assertEquals("end workflow instance", listener.getEvents().get(i++)); } }