/* 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.activiti.standalone.event; import java.util.List; import org.activiti.engine.ActivitiClassLoadingException; import org.activiti.engine.ActivitiException; import org.activiti.engine.ActivitiIllegalArgumentException; import org.activiti.engine.delegate.event.ActivitiEntityEvent; import org.activiti.engine.delegate.event.ActivitiEvent; import org.activiti.engine.delegate.event.ActivitiEventType; import org.activiti.engine.impl.test.ResourceActivitiTestCase; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import org.activiti.engine.test.Deployment; import org.activiti.engine.test.api.event.StaticTestActivitiEventListener; import org.activiti.engine.test.api.event.TestActivitiEventListener; /** * Test for event-listeners that are registered on a process-definition scope, * rather than on the global engine-wide scope, declared in the BPMN XML. * * @author Frederik Heremans */ public class ProcessDefinitionScopedEventListenerDefinitionTest extends ResourceActivitiTestCase { public ProcessDefinitionScopedEventListenerDefinitionTest() { super("org/activiti/standalone/event/activiti-eventlistener.cfg.xml"); } protected TestActivitiEventListener testListenerBean; /** * Test to verify listeners defined in the BPMN xml are added to the process * definition and are active. */ @Deployment public void testProcessDefinitionListenerDefinition() throws Exception { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testEventListeners"); assertNotNull(testListenerBean); Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); taskService.complete(task.getId()); // Check if the listener (defined as bean) received events (only creation, not other events) assertFalse(testListenerBean.getEventsReceived().isEmpty()); for(ActivitiEvent event : testListenerBean.getEventsReceived()) { assertEquals(ActivitiEventType.ENTITY_CREATED, event.getType()); } // First event received should be creation of Process-definition assertTrue(testListenerBean.getEventsReceived().get(0) instanceof ActivitiEntityEvent); ActivitiEntityEvent event = (ActivitiEntityEvent) testListenerBean.getEventsReceived().get(0); assertTrue(event.getEntity() instanceof ProcessDefinition); assertEquals(processInstance.getProcessDefinitionId(), ((ProcessDefinition) event.getEntity()).getId()); // First event received should be creation of Process-instance assertTrue(testListenerBean.getEventsReceived().get(1) instanceof ActivitiEntityEvent); event = (ActivitiEntityEvent) testListenerBean.getEventsReceived().get(1); assertTrue(event.getEntity() instanceof ProcessInstance); assertEquals(processInstance.getId(), ((ProcessInstance) event.getEntity()).getId()); // Check if listener, defined by classname, received all events List<ActivitiEvent> events = StaticTestActivitiEventListener.getEventsReceived(); assertFalse(events.isEmpty()); boolean insertFound = false; boolean deleteFound = false; for(ActivitiEvent e : events) { if(ActivitiEventType.ENTITY_CREATED == e.getType() ) { insertFound = true; } else if(ActivitiEventType.ENTITY_DELETED == e.getType()) { deleteFound = true; } } assertTrue(insertFound); assertTrue(deleteFound); } /** * Test to verify listeners defined in the BPMN xml with invalid class/delegateExpression * values cause an exception when process is started. */ public void testProcessDefinitionListenerDefinitionError() throws Exception { // Deploy process with expression which references an unexisting bean try { repositoryService.createDeployment().addClasspathResource("org/activiti/standalone/event/invalidEventListenerExpression.bpmn20.xml") .deploy(); fail("Exception expected"); } catch(ActivitiException ae) { assertEquals("Exception while executing event-listener", ae.getMessage()); assertTrue(ae.getCause() instanceof ActivitiException); assertEquals("Unknown property used in expression: ${unexistingBean}", ae.getCause().getMessage()); } // Deploy process with listener which references an unexisting class try { repositoryService.createDeployment().addClasspathResource("org/activiti/standalone/event/invalidEventListenerClass.bpmn20.xml") .deploy(); fail("Exception expected"); } catch(ActivitiException ae) { assertEquals("Exception while executing event-listener", ae.getMessage()); assertTrue(ae.getCause() instanceof ActivitiException); assertEquals("couldn't instantiate class org.activiti.engine.test.api.event.UnexistingClass", ae.getCause().getMessage()); assertTrue(ae.getCause().getCause() instanceof ActivitiClassLoadingException); assertTrue(ae.getCause().getCause().getCause() instanceof ClassNotFoundException); } } /** * Test to verify if event listeners defined in the BPMN XML which have illegal event-types * cause an exception on deploy. */ public void testProcessDefinitionListenerDefinitionIllegalType() throws Exception { // In case deployment doesn't fail, we delete the deployment in the finally block to // ensure clean DB for subsequent tests org.activiti.engine.repository.Deployment deployment = null; try { deployment = repositoryService.createDeployment() .addClasspathResource("org/activiti/standalone/event/invalidEventListenerType.bpmn20.xml") .deploy(); fail("Exception expected"); } catch(ActivitiException ae) { assertTrue(ae instanceof ActivitiIllegalArgumentException); assertEquals("Invalid event-type: invalid", ae.getMessage()); } finally { if(deployment != null) { repositoryService.deleteDeployment(deployment.getId(), true); } } } /** * Test to verify listeners defined in the BPMN xml are added to the process * definition and are active, for all entity types */ @Deployment public void testProcessDefinitionListenerDefinitionEntities() throws Exception { ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testEventListeners"); assertNotNull(processInstance); Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult(); assertNotNull(task); // Attachment entity TestActivitiEventListener theListener = (TestActivitiEventListener) processEngineConfiguration.getBeans().get("testAttachmentEventListener"); assertNotNull(theListener); assertEquals(0, theListener.getEventsReceived().size()); taskService.createAttachment("test", task.getId(), processInstance.getId(), "test", "test", "url"); assertEquals(2, theListener.getEventsReceived().size()); assertEquals(ActivitiEventType.ENTITY_CREATED, theListener.getEventsReceived().get(0).getType()); assertEquals(ActivitiEventType.ENTITY_INITIALIZED, theListener.getEventsReceived().get(1).getType()); } @Override protected void setUp() throws Exception { super.setUp(); testListenerBean = (TestActivitiEventListener) processEngineConfiguration.getBeans().get("testEventListener"); } }