Package org.camunda.bpm.engine.test.bpmn.async

Source Code of org.camunda.bpm.engine.test.bpmn.async.AsyncAfterTest

/* 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.camunda.bpm.engine.test.bpmn.async;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.camunda.bpm.engine.ProcessEngineException;
import org.camunda.bpm.engine.impl.test.PluggableProcessEngineTestCase;
import org.camunda.bpm.engine.runtime.Execution;
import org.camunda.bpm.engine.runtime.Job;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.task.Task;
import org.camunda.bpm.engine.task.TaskQuery;
import org.camunda.bpm.engine.test.Deployment;

/**
* @author Daniel Meyer
* @author Stefan Hentschel
*
*/
public class AsyncAfterTest extends PluggableProcessEngineTestCase {

  public void testTransitionIdRequired() {

    // if an outgoing sequence flow has no id, we cannot use it in asyncAfter
    try {
      repositoryService.createDeployment()
        .addClasspathResource("org/camunda/bpm/engine/test/bpmn/async/AsyncAfterTest.testTransitionIdRequired.bpmn20.xml")
        .deploy();
      fail("Exception expected");
    } catch ( ProcessEngineException e) {
      assertTextPresent("Sequence flow with sourceRef='service' must have an id, activity with id 'service' uses 'asyncAfter'.", e.getMessage());
    }

  }

  @Deployment
  public void testAsyncAfterServiceTask() {
    // start process instance
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testProcess");

    // listeners should be fired by now
    assertListenerStartInvoked(pi);
    assertListenerEndInvoked(pi);

    // the process should wait *after* the catch event
    Job job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    // if the waiting job is executed, the process instance should end
    managementService.executeJob(job.getId());
    assertProcessEnded(pi.getId());
  }

  @Deployment
  public void testAsyncAfterAndBeforeServiceTask() {
    // start process instance
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testProcess");

    // the service task is not yet invoked
    assertNotListenerStartInvoked(pi);
    assertNotBehaviorInvoked(pi);
    assertNotListenerEndInvoked(pi);

    Job job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    // if the job is executed
    managementService.executeJob(job.getId());

    // the manual task is invoked
    assertListenerStartInvoked(pi);
    assertListenerEndInvoked(pi);

    // and now the process is waiting *after* the manual task
    job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    // after executing the waiting job, the process instance will end
    managementService.executeJob(job.getId());
    assertProcessEnded(pi.getId());
  }

  @Deployment
  public void testAsyncAfterServiceTaskMultipleTransitions() {

    // start process instance
    Map<String, Object> varMap = new HashMap<String, Object>();
    varMap.put("flowToTake", "flow2");
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testProcess", varMap);

    // the service task is completely invoked
    assertListenerStartInvoked(pi);
    assertBehaviorInvoked(pi);
    assertListenerEndInvoked(pi);

    // and the execution is waiting *after* the service task
    Job continuationJob = managementService.createJobQuery().singleResult();
    assertNotNull(continuationJob);

    // if we execute the job, the process instance continues along the selected path
    managementService.executeJob(continuationJob.getId());

    assertNotNull(runtimeService.createExecutionQuery().activityId("taskAfterFlow2").singleResult());
    assertNull(runtimeService.createExecutionQuery().activityId("taskAfterFlow3").singleResult());

    // end the process
    runtimeService.signal(pi.getId());

    //////////////////////////////////////////////////////////////

    // start process instance
    varMap = new HashMap<String, Object>();
    varMap.put("flowToTake", "flow3");
    pi = runtimeService.startProcessInstanceByKey("testProcess", varMap);

    // the service task is completely invoked
    assertListenerStartInvoked(pi);
    assertBehaviorInvoked(pi);
    assertListenerEndInvoked(pi);

    // and the execution is waiting *after* the service task
    continuationJob = managementService.createJobQuery().singleResult();
    assertNotNull(continuationJob);

    // if we execute the job, the process instance continues along the selected path
    managementService.executeJob(continuationJob.getId());

    assertNull(runtimeService.createExecutionQuery().activityId("taskAfterFlow2").singleResult());
    assertNotNull(runtimeService.createExecutionQuery().activityId("taskAfterFlow3").singleResult());

  }

  @Deployment
  public void testAsyncAfterServiceTaskMultipleTransitionsConcurrent() {

    // start process instance
    Map<String, Object> varMap = new HashMap<String, Object>();
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testProcess", varMap);

    // the service task is completely invoked
    assertListenerStartInvoked(pi);
    assertBehaviorInvoked(pi);
    assertListenerEndInvoked(pi);

    // there are two async jobs
    List<Job> jobs = managementService.createJobQuery().list();
    assertEquals(2, jobs.size());
    managementService.executeJob(jobs.get(0).getId());
    managementService.executeJob(jobs.get(1).getId());

    // both subsequent tasks are activated
    assertNotNull(runtimeService.createExecutionQuery().activityId("taskAfterFlow2").singleResult());
    assertNotNull(runtimeService.createExecutionQuery().activityId("taskAfterFlow3").singleResult());

  }

  @Deployment
  public void testAsyncAfterWithoutTransition() {

    // start process instance
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testProcess");

    // the service task is completely invoked
    assertListenerStartInvoked(pi);
    assertBehaviorInvoked(pi);
    assertListenerEndInvoked(pi);

    // and the execution is waiting *after* the service task
    Job continuationJob = managementService.createJobQuery().singleResult();
    assertNotNull(continuationJob);

    // but the process end listeners have not been invoked yet
    assertNull(runtimeService.getVariable(pi.getId(), "process-listenerEndInvoked"));

    // if we execute the job, the process instance ends.
    managementService.executeJob(continuationJob.getId());
    assertProcessEnded(pi.getId());

  }

  @Deployment
  public void testAsyncAfterInNestedWithoutTransition() {

    // start process instance
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testProcess");

    // the service task is completely invoked
    assertListenerStartInvoked(pi);
    assertBehaviorInvoked(pi);
    assertListenerEndInvoked(pi);

    // and the execution is waiting *after* the service task
    Job continuationJob = managementService.createJobQuery().singleResult();
    assertNotNull(continuationJob);

    // but the subprocess end listeners have not been invoked yet
    assertNull(runtimeService.getVariable(pi.getId(), "subprocess-listenerEndInvoked"));

    // if we execute the job, the listeners are invoked;
    managementService.executeJob(continuationJob.getId());
    assertTrue((Boolean)runtimeService.getVariable(pi.getId(), "subprocess-listenerEndInvoked"));

  }

  @Deployment
  public void testAsyncAfterManualTask() {
    // start process instance
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testManualTask");

    // listeners should be fired by now
    assertListenerStartInvoked(pi);
    assertListenerEndInvoked(pi);

    // the process should wait *after* the catch event
    Job job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    // if the waiting job is executed, the process instance should end
    managementService.executeJob(job.getId());
    assertProcessEnded(pi.getId());
  }

  @Deployment
  public void testAsyncAfterAndBeforeManualTask() {
    // start process instance
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testManualTask");

    // the service task is not yet invoked
    assertNotListenerStartInvoked(pi);
    assertNotListenerEndInvoked(pi);

    Job job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    // if the job is executed
    managementService.executeJob(job.getId());

    // the manual task is invoked
    assertListenerStartInvoked(pi);
    assertListenerEndInvoked(pi);

    // and now the process is waiting *after* the manual task
    job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    // after executing the waiting job, the process instance will end
    managementService.executeJob(job.getId());
    assertProcessEnded(pi.getId());
  }

  @Deployment
  public void testAsyncAfterIntermediateCatchEvent() {
    // start process instance
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testIntermediateCatchEvent");

    // the intermediate catch event is waiting for its message
    runtimeService.correlateMessage("testMessage1");

    // listeners should be fired by now
    assertListenerStartInvoked(pi);
    assertListenerEndInvoked(pi);

    // the process should wait *after* the catch event
    Job job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    // if the waiting job is executed, the process instance should end
    managementService.executeJob(job.getId());
    assertProcessEnded(pi.getId());
  }

  @Deployment
  public void testAsyncAfterAndBeforeIntermediateCatchEvent() {

    // start process instance
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testIntermediateCatchEvent");

    // check that no listener is invoked by now
    assertNotListenerStartInvoked(pi);
    assertNotListenerEndInvoked(pi);

    // the process is waiting before the message event
    Job job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    // execute job to get to the message event
    executeAvailableJobs();

    // now we need to trigger the message to proceed
    runtimeService.correlateMessage("testMessage1");

    // now the listener should be invoked
    assertListenerStartInvoked(pi);
    assertListenerEndInvoked(pi);

    // and now the process is waiting *after* the intermediate catch event
    job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    // after executing the waiting job, the process instance will end
    managementService.executeJob(job.getId());
    assertProcessEnded(pi.getId());
  }

  @Deployment
  public void testAsyncAfterIntermediateThrowEvent() {
    // start process instance
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testIntermediateThrowEvent");

    // listeners should be fired by now
    assertListenerStartInvoked(pi);
    assertListenerEndInvoked(pi);

    // the process should wait *after* the throw event
    Job job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    // if the waiting job is executed, the process instance should end
    managementService.executeJob(job.getId());
    assertProcessEnded(pi.getId());
  }

  @Deployment
  public void testAsyncAfterAndBeforeIntermediateThrowEvent() {
    // start process instance
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testIntermediateThrowEvent");

    // the throw event is not yet invoked
    assertNotListenerStartInvoked(pi);
    assertNotListenerEndInvoked(pi);

    Job job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    // if the job is executed
    managementService.executeJob(job.getId());

    // the listeners are invoked
    assertListenerStartInvoked(pi);
    assertListenerEndInvoked(pi);

    // and now the process is waiting *after* the throw event
    job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    // after executing the waiting job, the process instance will end
    managementService.executeJob(job.getId());
    assertProcessEnded(pi.getId());
  }

  @Deployment
  public void testAsyncAfterInclusiveGateway() {
    // start process instance
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testInclusiveGateway");

    // listeners should be fired
    assertListenerStartInvoked(pi);
    assertListenerEndInvoked(pi);

    // the process should wait *after* the gateway
    assertEquals(2, managementService.createJobQuery().active().count());

    executeAvailableJobs();

    // if the waiting job is executed there should be 2 user tasks
    TaskQuery taskQuery = taskService.createTaskQuery();
    assertEquals(2, taskQuery.active().count());

    // finish tasks
    List<Task> tasks = taskQuery.active().list();
    for(Task task : tasks) {
      taskService.complete(task.getId());
    }

    assertProcessEnded(pi.getProcessInstanceId());

  }

  @Deployment
  public void testAsyncAfterAndBeforeInclusiveGateway() {
    // start process instance
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testInclusiveGateway");

    // no listeners are fired:
    assertNotListenerStartInvoked(pi);
    assertNotListenerEndInvoked(pi);

    // we should wait *before* the gateway:
    Job job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    // after executing the gateway:
    managementService.executeJob(job.getId());

    // the listeners are fired:
    assertListenerStartInvoked(pi);
    assertListenerEndInvoked(pi);

    // and we will wait *after* the gateway:
    List<Job> jobs = managementService.createJobQuery().active().list();
    assertEquals(2, jobs.size());
  }

  @Deployment
  public void testAsyncAfterExclusiveGateway() {
    // start process instance with variables
    Map<String, Object> variables = new HashMap<String, Object>();
    variables.put("flow", false);

    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testExclusiveGateway", variables);

    // listeners should be fired
    assertListenerStartInvoked(pi);
    assertListenerEndInvoked(pi);

    // the process should wait *after* the gateway
    assertEquals(1, managementService.createJobQuery().active().count());

    executeAvailableJobs();

    // if the waiting job is executed there should be 2 user tasks
    TaskQuery taskQuery = taskService.createTaskQuery();
    assertEquals(1, taskQuery.active().count());

    // finish tasks
    List<Task> tasks = taskQuery.active().list();
    for(Task task : tasks) {
      taskService.complete(task.getId());
    }

    assertProcessEnded(pi.getProcessInstanceId());
  }

  @Deployment
  public void testAsyncAfterAndBeforeExclusiveGateway() {
    // start process instance with variables
    Map<String, Object> variables = new HashMap<String, Object>();
    variables.put("flow", false);

    ProcessInstance pi = runtimeService.startProcessInstanceByKey("testExclusiveGateway", variables);

    // no listeners are fired:
    assertNotListenerStartInvoked(pi);
    assertNotListenerEndInvoked(pi);

    // we should wait *before* the gateway:
    Job job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    // after executing the gateway:
    managementService.executeJob(job.getId());

    // the listeners are fired:
    assertListenerStartInvoked(pi);
    assertListenerEndInvoked(pi);

    // and we will wait *after* the gateway:
    assertEquals(1, managementService.createJobQuery().active().count());
  }
  /**
   * Test for CAM-2518: Fixes an issue that creates an infinite loop when using
   * asyncAfter together with an execution listener on sequence flow event "take".
   * So the only required assertion here is that the process executes successfully.
   */
  @Deployment
  public void testAsyncAfterWithExecutionListener() {
    // given an async after job and an execution listener on that task
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("testProcess");

    Job job = managementService.createJobQuery().singleResult();
    assertNotNull(job);

    assertNotListenerTakeInvoked(processInstance);

    // when the job is executed
    managementService.executeJob(job.getId());

    // then the process should advance and not recreate the job
    job = managementService.createJobQuery().singleResult();
    assertNull(job);

    Task task = taskService.createTaskQuery().singleResult();
    assertNotNull(task);

    assertListenerTakeInvoked(processInstance);
  }


  protected void assertListenerStartInvoked(Execution e) {
    assertTrue((Boolean) runtimeService.getVariable(e.getId(), "listenerStartInvoked"));
  }

  protected void assertListenerTakeInvoked(Execution e) {
    assertTrue((Boolean) runtimeService.getVariable(e.getId(), "listenerTakeInvoked"));
  }

  protected void assertListenerEndInvoked(Execution e) {
    assertTrue((Boolean) runtimeService.getVariable(e.getId(), "listenerEndInvoked"));
  }

  protected void assertBehaviorInvoked(Execution e) {
    assertTrue((Boolean) runtimeService.getVariable(e.getId(), "behaviorInvoked"));
  }

  protected void assertNotListenerStartInvoked(Execution e) {
    assertNull(runtimeService.getVariable(e.getId(), "listenerStartInvoked"));
  }

  protected void assertNotListenerTakeInvoked(Execution e) {
    assertNull(runtimeService.getVariable(e.getId(), "listenerTakeInvoked"));
  }

  protected void assertNotListenerEndInvoked(Execution e) {
    assertNull(runtimeService.getVariable(e.getId(), "listenerEndInvoked"));
  }

  protected void assertNotBehaviorInvoked(Execution e) {
    assertNull(runtimeService.getVariable(e.getId(), "behaviorInvoked"));
  }

}
TOP

Related Classes of org.camunda.bpm.engine.test.bpmn.async.AsyncAfterTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.