Package org.camunda.bpm.engine.test.concurrency

Source Code of org.camunda.bpm.engine.test.concurrency.ConcurrentDeploymentTest$ControllableDeployCommand

/* 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.concurrency;

import org.camunda.bpm.engine.impl.cmd.DeployCmd;
import org.camunda.bpm.engine.impl.interceptor.CommandContext;
import org.camunda.bpm.engine.impl.repository.DeploymentBuilderImpl;
import org.camunda.bpm.engine.repository.Deployment;
import org.camunda.bpm.engine.repository.DeploymentBuilder;
import org.camunda.bpm.engine.repository.DeploymentQuery;
import org.camunda.bpm.model.bpmn.Bpmn;
import org.camunda.bpm.model.bpmn.BpmnModelInstance;

import java.io.ByteArrayOutputStream;

/**
*
* @author Daniel Meyer
*
*/
public class ConcurrentDeploymentTest extends ConcurrencyTestCase {

  private static String processResource;

  static {
    BpmnModelInstance modelInstance = Bpmn.createExecutableProcess().startEvent().done();
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    Bpmn.writeModelToStream(outputStream, modelInstance);
    processResource = new String(outputStream.toByteArray());
  }

  /**
   * Create deployment from two threads simultaneously -> make sure that
   * duplicate filtering works as expected.
   *  See: https://app.camunda.com/jira/browse/CAM-2128
   */
  public void testDuplicateFiltering() throws InterruptedException {

    // do not execute on H2
    if("h2".equals(processEngineConfiguration.getDbSqlSessionFactory().getDatabaseType())) {
      return;
    }

    // STEP 1: bring two threads to a point where they have
    // 1) started a new transaction
    // 2) are ready to deploy
    ThreadControl thread1 = executeControllableCommand(new ControllableDeployCommand());
    thread1.waitForSync();

    ThreadControl thread2 = executeControllableCommand(new ControllableDeployCommand());
    thread2.waitForSync();

    // STEP 2: make Thread 1 proceed and wait until it has deployed but not yet committed
    // -> will still hold the exclusive lock
    thread1.makeContinue();
    thread1.waitForSync();

    // STEP 3: make Thread 2 continue
    // -> it will attempt to acquire the exclusive lock and block on the lock
    thread2.makeContinue();

    // wait for 2 seconds (Thread 2 is blocked on the lock)
    Thread.sleep(2000);

    // STEP 4: allow Thread 1 to terminate
    // -> Thread 1 will commit and release the lock
    thread1.waitUntilDone();

    // STEP 5: wait for Thread 2 to terminate
    thread2.waitForSync();
    thread2.waitUntilDone();

    // ensure that although both transactions were run concurrently, only one deployment was constructed.
    DeploymentQuery deploymentQuery = repositoryService.createDeploymentQuery();
    assertEquals(1, deploymentQuery.count());

    // cleanup
    Deployment deployment = deploymentQuery.singleResult();
    repositoryService.deleteDeployment(deployment.getId(), true);
  }

  protected static class ControllableDeployCommand extends ControllableCommand<Void> {

    public Void execute(CommandContext commandContext) {

      DeploymentBuilder deploymentBuilder = new DeploymentBuilderImpl(null)
        .name("some-deployment-name")
        .enableDuplicateFiltering(false)
        .addString("foo.bpmn", processResource);

      monitor.sync()// thread will block here until makeContinue() is called form main thread

      new DeployCmd<Deployment>((DeploymentBuilderImpl) deploymentBuilder).execute(commandContext);

      monitor.sync()// thread will block here until waitUntilDone() is called form main thread

      return null;
    }

  }

}
TOP

Related Classes of org.camunda.bpm.engine.test.concurrency.ConcurrentDeploymentTest$ControllableDeployCommand

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.