Activiti User Guide -- Activit 用户指南 Part04

 

Chapter 5. API

第五章 API

Table of Contents

Engine API

Exception strategy

Unit testing

The activiti-webapp-init.war

Process Virtual Machine API

Engine API

引擎API

The engine API is the most common way of interacting with Activiti. You need a configuration file to get started. Then you can create aConfiguration and feed in the file as a resource or as an input stream. Then you build a ProcessEngine from the configuration. From the ProcessEngine, you can obtain the various XxxxServices that contain the workflow/BPM methods. ProcessEngine and the services objects are thread safe. So you can keep a reference to 1 of those for a whole server.

引擎API是与Activiti进行交互的最常用方式。你需要一个配置文件才能够启动引擎。你可以以资源配置文件的方式创建一个配置,也可以以输入流的方式创建一个配置,那么你就可以使用该配置文件来构建一个ProcessEngine。通过ProcessEngine你可以获取一系列包含工作流/BPM方法的XxxxServicesProcessEngine和服务对象都是线程安全的,因此你可以在整个服务器中保留对它们任何一个的引用。


Activiti User Guide -- Activit 用户指南 Part04

ProcessEngine processEngine = new ProcessEngineBuilder()
  .configureFromPropertiesResource(configurationResource)
  .buildProcessEngine();

RuntimeService runtimeService = processEngine.getRuntimeService();
RepositoryService repositoryService = processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService();
ManagementService managementService = processEngine.getManagementService();
IdentityService identityService = processEngine.getIdentityService();
HistoryService historyService = processEngine.getHistoryService();
  We've also added a couple of classes that can provide convenience for unit testing processes in package   org.activiti.engine.test .

我们在 org.activiti.engine.test包中添加了几个类以方便对流程进行单元测试。

 

For more docs on the engine API, see the javadocs.

关于流程引擎API更多的信息可以参考javadocs

Exception strategy

异常策略

The base exception in Activiti is the ActivitiException, an unchecked exception. This exception can be thrown at all times by the API, but 'expected' exceptions that happen in specific methods are documented in the the javadocs. For example, an extract from TaskService:

ActivitiExceptionActiviti最基本的异常,它是一个unchecked异常。该异常可以在API的任何地方被抛出,在javadocs中会描述了一些方法的异常需要被‘expected’。例如,TaskService

/**
        * Called when the task is successfully executed.
        * @param taskId the id of the task to complete, cannot be null.
        * @throws ActivitiException when no task exists with the given id.
        */
        void complete(String taskId);
  In the example above, when an id is passed for which no task exists, an exception will be thrown. Also, since the javadoc explicitly states that taskId cannot be null, an ActivitiException will be thrown when null is passed.

该方法中,如果不存在所传入id的任务,那么就会抛出一个异常。同时,javadoc中也明确的指出taskId参数不可以为空,如果为空则会抛出一个ActivitiException异常。

 

Even though we want to avoid a big exception hierarchy, the following subclasses were added which are thrown in specific cases:

尽管我们极力避免一个庞大的异常体系,但是下面两个子类还是被加入进来,它们会在一些特殊用例中被抛出:

  • ActivitiWrongDbException: Thrown when the Activiti engine discovers a mismatch between the database schema version and the engine version.
  • ActivitiWrongDbException: Activiti引擎发现数据库的版本和引擎版本不一致时被抛出。
  • ActivitiOptimisticLockingException: Thrown when an optimistic locking occurs in the datastore caused by concurrent access of the same data entry.
  • ActivitiOptimisticLockingException: 由于同时访问同一条数据造成乐观锁产生时就会抛出该异常。

Unit testing

单元测试

Business processes are an integral part of software projects and they should be tested in the same way normal application logic is tested: with unit tests. Since Activiti is an embeddable Java engine, writing unit test for business processes is as simple as writing regular unit tests.

业务流程是软件项目中一个重要的部分,因此它们也应该像我们使用单元测试测试应用逻辑一样可以被测试。因为Activiti是一个嵌入式流程引擎,所以编写业务流程的单元测试就和我们编写普通单元测试一样易于编写。

 

Activiti supports both Junit versions 3 and 4 style of unit testing. In the Junit 3 style, the org.activiti.engine.test.ActivitiTestCase must be extended. This will make the processEngine and the services available through protected member fields. In the setup() of the test, the processEngine will be initialized by default with the activiti.properties resource on the classpath. To specify a different configuration file, override the getConfigurationResource() method. Process engines are be cached statically over multiple unit tests when the configuration resource is the same.

Activiti的单位测试支持Junit的版本3和版本4两种风格。使用版本3Junit时,必须使用org.activiti.engine.test.ActivitiTestCase 作为基类。这样可以使用保护字段来构建processEngineservices。在setup() 方法中,缺省流程引擎将根据classpath中的 activiti.properties 资源文件进行初始化。你可以通过复写 getConfigurationResource() 方法来使用不同的配置文件。当多个单元测试使用同一个配置资源文件时,process engines将被静态缓存。

 

By extending ActivitiTestCase, you can annotate test methods with org.activiti.engine.test.Deployment. Before the test is run, a resource file of the form testClassName.testMethod.bpmn20.xml in the same package as the test class, will be deployed. At the end of the test, the deployment will be deleted, including all related process instances, tasks, etc. The Deployment annotation also supports setting the resource location explicitly. See the Javadoc for more details.

当基于ActivitiTestCase进行单元测试时,可以使用 org.activiti.engine.test.Deployment注释来指定要进行测试的方法。在测试运行前,流程引擎会先部署测试类所在目录下一个名称为testClassName.testMethod.bpmn20.xml 流程定义文件。当测试运行结束后,该部署将会被删除,同时也会删除相关的流程实例、任务等数据。Deployment 注释也可以明确的指定资源文件所在路径。详细信息可以查看javadoc.

 

Taking all that in account, a Junit 3 style test looks as follows.

综上所述,基于Junit3的测试用例,如下所示:

public class MyBusinessProcessTest extends ActivitiTestCase {
   
  @Deployment
  public void testSimpleProcess() {
    runtimeService.startProcessInstanceByKey("simpleProcess");
    
    Task task = taskService.createTaskQuery().singleResult();
    assertEquals("My Task", task.getName());
    
    taskService.complete(task.getId());
    assertEquals(0, runtimeService.createProcessInstanceQuery().count());
  }
}     
  To get the same functionality when using the Junit 4 style of writing unit tests, the  org.activiti.engine.test.ActivitiRule  Rule must be used. Through this rule, the process engine and services are available through getters. As with the  ActivitiTestCase  (see above), including this Rule will enable the use of the  org.activiti.engine.test.Deployment  annotation (see above for an explanation of its use and configuration). Process engines are statically cached over mutliple unit tests when using the same configuration resource.

使用Junit4风格来编写单元测试也可以获得同样的功能,此时你必须采用org.activiti.engine.test.ActivitiRule 规则。这样你才能够通过ActivitiRule所提供的get方法获取到process engineserivces。和上述的ActivitiTestCase一样,当包含了该规则后就可以使用org.activiti.engine.test.Deployment 注释了。当多个单元测试使用同一个配置资源文件时,process engines将被静态缓存。

 

Following code snippet shows an example of using the Junit 4 style of testing and the usage of the ActivitiRule.

下面的实例展现了使用Junit4风格进行单元测试,以及ActivitiRule的使用方式。

public class MyBusinessProcessTest {
  
  @Rule
  public ActivitiRule activitiRule = new ActivitiRule();
  
  @Test
  @Deployment
  public void ruleUsageExample() {
    RuntimeService runtimeService = activitiRule.getRuntimeService();
    runtimeService.startProcessInstanceByKey("ruleUsage");
    
    TaskService taskService = activitiRule.getTaskService();
    Task task = taskService.createTaskQuery().singleResult();
    assertEquals("My Task", task.getName());
    
    taskService.complete(task.getId());
    assertEquals(0, runtimeService.createProcessInstanceQuery().count());
  }
}

 

The activiti-webapp-init.war

activity-webapp-init.war

The activiti-webapp-init.war can be used to easily manage process engine initialization and proper shutdown. This war is automatically added to tomcat in the setup scripts when deploying activiti to tomcat.

使用activiti-webapp-init.war可以方便管理流程引擎的初始化和proper关闭。当部署activititomcat时,该war将自动的安装到tomcat中。

 

The war contains a single ServletContextListener that has a contextInitialized and a contextDestroyed method. The contextInitialized will delegate to ProcessEngines.init(). That will look for all activiti.properties resource files on the classpath. For each configuration file found, it will create a ProcessEngine.

war中包含里了一个单独的 ServletContextListener ,该listener声明了 contextInitialized  contextDestroyed 方法。 contextInitialized 方法将调用 ProcessEngines.init()方法。在启动时将搜索classpath下所有 activiti.properties 文件。然后为每一个找到的配置文件创建一个ProcessEngine

 

The default process engine name is default.

缺省流程引擎的名称为default

 

If you have multiple such resource files on the classpath, make sure they all have different values for property process.engine.name

如果你在classpath下有多个这样的配置文件,那么请确认它们的process.engine.name是否拥有不同的值。

 

The initialized ProcessEngines can be accessed with ProcessEngines.getProcessEngine(String processEngineName)

通过ProcessEngines.getProcessEngine(String processEngineName)就可以访问到初始后的ProcessEngine

 

The contextDestroyed of the context-listener delegates to ProcessEngines.destroy(). That will properly close all initialized process engines.

context-listener contextDestroyed 方法则调用 ProcessEngines.destroy()方法,用例关闭所有已经加载的流程引擎。

Process Virtual Machine API

流程虚拟机API

The Process Virtual Machine API exposes the POJO core of the Process Virtual Machine. Reading and playing with it is interesting for education purposes to understand the internal workings of Activiti. And the POJO API can also be used to build new process languages.

流程虚拟机API则暴露了流程虚拟机的POJO核心。把玩这些理解Activiti的内部工作机制。使用POJO API你可以构建一个新流程语言。

 

For example:

例如:

PvmProcessDefinition processDefinition = new ProcessDefinitionBuilder()
  .createActivity("a")
    .initial()
    .behavior(new WaitState())
    .transition("b")
  .endActivity()
  .createActivity("b")
    .behavior(new WaitState())
    .transition("c")
  .endActivity()
  .createActivity("c")
    .behavior(new WaitState())
  .endActivity()
  .buildProcessDefinition();

PvmProcessInstance processInstance = processDefinition.createProcessInstance();
processInstance.start();

PvmExecution activityInstance = processInstance.findExecution("a");
assertNotNull(activityInstance);

activityInstance.signal(null, null);

activityInstance = processInstance.findExecution("b");
assertNotNull(activityInstance);

activityInstance.signal(null, null);

activityInstance = processInstance.findExecution("c");
assertNotNull(activityInstance);
 

 

你可能感兴趣的:(tomcat,搜索引擎,单元测试,软件测试,JUnit)