CAYENNE-BPMS-流程引擎使用指南


1.   嵌入到业务系统中

流程引擎作为业务系统中的一个组件存在。

1.1. 添加引擎依赖

在开始集成引擎前,需要将Cayenne流程引擎的包以及其所依赖的包引入当前项目中。以Maven项目为例,仅需要在项目的pom.xml中加入如下依赖即可:

<dependency>
    <groupId>com.cayenne.bpm</groupId>
    <artifactId>cayenne_bpm_engine</artifactId>
    <version>${cayenne.bpm.engine.version}</version>
</dependency>

Tip :当前的引擎版本号为4.1.0-SNAPSHOT;

l  在使用时将占位符${cayenne.bpm.engine.version}替换为该版本号即可。

l  Maven私服的配置请参考maven-settings.xml

1.2. 始化引擎构造器及构建引擎实例

Cayenne流程引擎配置器用于配置流程引擎启动和运行所需的资源和环境,流程引擎在运行过程中也会通过它动态获取所需要的配置数据。

引擎配置器可通过Spring bean配置文件或API接口调用方式进行构造。如下面章节所述。

1.2.1.    Spring bean配置文件(cayenne-bpm-engine.cfg.xml

在业务系统工程目录下,添加cayenne-bpm-engine.cfg.xml 文件,具体配置如下所述:

备注:其中背景标识的部分是业务系统需要根据自身情况所需灵活配置的。

1)    数据库配置。若系统中已配置了数据库,此步骤可省略。
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
    <property name="driverClass" value="org.h2.Driver" />
    <property name="url" value="jdbc:h2:mem:cayenne_bpm;DB_CLOSE_DELAY=1000" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean>
 
2)    引擎配置器
<!-- 事务管理控制器,若系统中已配置,此处可以省略 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource" />
</bean> 
<bean id="bpEngineConfiguration" class="com.cayenne.bpm.engine.kernel.activiti.cfg.ActivitiProcessEngineConfiguration">
    <constructor-arg>
        <!-- 由于Activiti为集成Spring提供了单独的Configuration,故在与Spring集成时,需按照内核提供的方案写 -->
        <bean class="org.activiti.spring.SpringProcessEngineConfiguration">
            <property name="transactionManager" ref="transactionManager" />
            <!-- 禁用内核自身的流程图绘制功能 -->
            <property name="createDiagramOnDeploy" value="false" />
        </bean>
    </constructor-arg>
    <property name="engineName" value="activitiEngineWithSpring" />
    <property name="dataSource" ref="dataSource" />
    <!-- 数据库更新策略:update - 仅更新/升级;check - 仅做检查;create - 直接创建;create-drop - 先创建,再删除;drop-create - 先删除,再创建 -->
    <property name="dbSchemaUpdateMode" value="update" />
    <property name="mailServerHost" value="localhost" />
    <property name="mailServerPort" value="5025" />
<!-- 引入组织机构桥接器配置,组织机构桥接器的配置见1.3.3 -->
<property name="orgBridgeBuilder" ref="orgBridgeBuilder" />
</bean>
3)    构建引擎实例
<bean id="bpEngine" factory-bean="bpEngineConfiguration" factory-method="buildProcessEngine" />
4)    获取引擎服务对象
<!-- 流程定义以及相关资源的管理服务。提供流程定义的部署、挂起、激活、废弃、删除等功能  -->
<bean id="repositoryService" factory-bean="bpEngine" factory-method="getRepositoryService" />
<!-- 流程运行时服务。提供流程的启动、挂起、激活、终止等功能,包括对运行中的节点的干预  -->
<bean id="runtimeService" factory-bean="bpEngine" factory-method="getRuntimeService" />
<!-- 任务处理服务。提供针对运行中的任务节点的处理操作,如指派、完成、加签、转派、退回等  -->
<bean id="taskService" factory-bean="bpEngine" factory-method="getTaskService" />
<!-- 流程历史数据管理服务。提供对流程历史数据的删除、查询功能  -->
<bean id="historyService" factory-bean="bpEngine" factory-method="getHistoryService" />
<!-- 流程数据报表分析服务。提供针对流程的实时报表和历史数据的统计分析功能 */
<bean id="reportService" factory-bean="bpEngine" factory-method="getReportService" />
<!-- 流程引擎内置的人员组织机构管理。负责用户/组的数据和关系维护  -->
<bean id="identityService" factory-bean="bpEngine" factory-method="getIdentityService" />

1.2.2.    API接口调用示例

1)   引擎配置器
BusinessProcessEngineConfiguration engineConfig = new ActivitiProcessEngineConfiguration(new StandaloneProcessEngineConfiguration());
2)    引擎参数配置
engineConfig.setEngineName("standaloneBpmEngine")
            .setJdbcDriver("org.h2.Driver")
            .setJdbcUrl("jdbc:h2:mem:cayenne_bpm;DB_CLOSE_DELAY=1000")
            .setJdbcUsername("sa")
            .setJdbcPassword("")
            .setDbSchemaUpdateMode("update");
3)    构建引擎实例
BusinessProcessEngine processEngine =engineConfig.buildProcessEngine();
4)    获取引擎服务对象
/** 流程定义以及相关资源的管理服务。提供流程定义的部署、挂起、激活、废弃、删除等功能 */
BpRepositoryService   repositoryService = processEngine .getRepositoryService();
/** 流程运行时服务。提供流程的启动、挂起、激活、终止等功能,包括对运行中的节点的干预 */
BpRuntimeService  runtimeService = processEngine .getRuntimeService();
/** 任务处理服务。提供针对运行中的任务节点的处理操作,如指派、完成、加签、转派、退回等 */
BpTaskService taskServ = processEngine .getTaskService();
/** 流程历史数据管理服务。提供对流程历史数据的删除、查询功能 */
BpHistoryService historyService = processEngine .getHistoryService();
/** 流程数据报表分析服务。提供针对流程的实时报表和历史数据的统计分析功能 */
BpReportService reportService = processEngine .getReportService();
/** 流程引擎内置的人员组织机构管理。负责用户/组的数据和关系维护 */
BpIdentityService identityService = processEngine .getIdentityService();
 
 

1.2.3.    总结

上述两种构建方式并没有本质的差异,以Activiti内核为例,Cayenne流程引擎为其提供了封装对象com.cayenne.bpm.engine.kernel.activiti.cfg.ActivitiProcessEngineConfiguration,该对象在实例化时,可接受Activiti的引擎配置器(org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl),或是Activiti的引擎配置器配置文件(activiti.cfg.xml)。在Cayenne流程引擎配置器实例化完成后,可通过其set接口修改或增加配置数据,从而为引擎提供必要的运行数据。

需要注意的是,Cayenne流程引擎具有自动更新或升级数据库的功能,在构建引擎时,其会根据数据库更新策略对数据库进行相应的更新操作。该更新策略由配置项dbSchemaUpdateMode指定,其可选值如下:

l  update 仅更新或升级数据库,其将检测当前数据库所对应的引擎版本与当前所使用引擎版本的差异,从而决定是更新还是升级数据库;

l  check 仅检查数据库所对应的引擎版本是否与当前所使用的引擎版本一致,不一致,则抛出异常。此外,其还会检查必要的表是否完整;

l  create 直接创建数据库,其会直接在数据库中创建引擎数据表,而不会检查是否存在引擎数据表;

l  create-drop先创建数据库,再删除。即在引擎启动时创建数据库,关闭后,删除数据库。可用于测试和仿真等临时使用的场景下;

l  drop-create 先删除数据库,再创建。即在引擎启动时删除所有的引擎数据表,再创建空的引擎数据表,其和create-drop类似,只是先后顺序不同;

Tip: Spring框架环境下,Activiti引擎配置器需使用org.activiti.spring.SpringProcessEngineConfiguration

1.3. 组织机构桥接器配置

组织机构桥接器用于BPMS集成业务系统中的组织机构数据,以便进行流程中用户任务的分派。对于引擎而言,组织机构只有用户与组两种类型,但实际业务系统中的组织机构往往要复杂的多,不仅包含用户,还包括部门、职位、角色等。为了使引擎支持按业务系统中的组织机构进行流程中任务的分派,即支持将任务分派给组织机构中的角色、职位等,引擎通过一个组织机构桥接器来实现与业务系统组织机构的集成。

1.3.1.    添加组织机构桥接器依赖

在开始使用引擎前,需要将组织机构桥接器依赖包引入当前项目中。以Maven项目为例,需要在项目的pom.xml中加入如下依赖:

<dependency>
    <groupId>com.cayenne.component</groupId>
    <artifactId>cayenne_organization_bridge</artifactId>
    <version>${project.parent.version}</version>
</dependency>

Tip :当前的引擎版本号为4.1.0-SNAPSHOT;

l  在使用时将占位符${project.parent.version}替换为该版本号即可。

 

1.3.2.    组织机构映射规则配置

业务系统在使用引擎时,需先根据自身的组织机构模型,按规范编写相应的组织机构模型映射规则配置文件。组织机构桥接器支持数据库直接访问、Hibernate持久化框架访问等多种访问方式。下面只介绍数据库直接访问的配置。

在业务系统工程目录下,添加cayenne-org-bridge-mapper.xml 文件。其具体内容的配置如下所述:

l  <mappers/>查询结果数据的映射规则配置节点

l  <expressions/>查询/更新数据表达式配置节点

 

1.3.2.1.       查询结果数据映射规则配置

查询结果数据的映射需放置在<bridge/>根节点的<mappers/>子节点下,其下的每个子节点实际上代表一个组织机构中的一个模型。即人员分派所支持的按组织机构分派时的指派方式。其中<user/>子元素用于配置组织机构中的用户/人员模型,在<mappers/>节点下只能有一个<user/>节点。<group/>子元素用于配置组织机构中除用户/人员模型之外的其他模型,在<mappers/>节点下只能有一个<group/>节点。如下图所示。

<bridge class="com.cayenne.organization.bridge.impl.jdbc.JdbcBridge">

<mappers>

        <user id="User" class="org.activiti.engine.impl.persistence.en

                tity.UserEntity" name="用户">

            <id id="id" map="ID" name="ID" />

            <name id="firstName" map="XINGMING" name="姓名" />

        </user>

        <group id="Role" class="org.activiti.engine.impl.persi

                 stence.entity.GroupEntity" name="角色">

            <id id="id" map="ID" name="ID" />

            <name id="name" map="NAME" name="名称" />

            <field id="type" map="TYPE" name="类型" default="Role" />

        </group>

</mappers>

</bridge>

1<user>元素配置说明:

属性:

l  id: 映射对象标识,通常用模型对象的英文名称表示。<mappers>下所有子元素的id属性不允许重复。

l  class:未设置或对应的Class不存在或无法实例化时,均默认以Map集合代表该映射对象,key为对象属性名称。

org.activiti.engine.impl.persistence.entity.UserEntity

l  name:映射对象的描述。

子元素:

l  <id>元素:映射对象的唯一标识字段,必须指定且唯一。id属性:属性名称,map属性:模型对象数据库表中对应的字段名称,name属性:属性字段描述。

l  <name>元素:映射对象的描述字段,必须指定且唯一。id属性:属性名称,map属性:模型对象数据库表中对应的字段名称,name属性:属性字段描述。

(2)<group>元素配置说明:

l  id: 映射对象标识,通常用模型对象的英文名称表示。<mappers>下所有子元素的id属性不允许重复。

l  class:未设置或对应的Class不存在或无法实例化时,均默认以Map集合代表该映射对象,key为对象属性名称。

org.activiti.engine.impl.persistence.entity.GroupEntity

l  name:映射对象的描述。

子元素:

l  <id>元素:映射对象的唯一标识字段,必须指定且唯一。id属性:属性名称,map属性:模型对象数据库表中对应的字段名称,name属性:属性字段描述。

l  <name>元素:映射对象的描述字段,必须指定且唯一。id属性:属性名称,map属性:模型对象数据库表中对应的字段名称,name属性:属性字段描述。

l  <field>元素:组类型配置,用于区分不同的组。id属性:类型属性名称(需指定为type,即引擎groupEntity中的type属性),map属性:数据库表中对应的字段名称(需指定为type,即group数据表中type属性的名称),defalut:组类型值,需唯一。

1.3.2.2.       组织机构数据查询表达式配置

表达式的配置放置在<bridge/>根节点的<expressions/>节点下,其下的每个<query>节点代表一个查询表达式。

 

<bridge class="com.cayenne.organization.bridge.impl.jdbc.JdbcBridge">

    <expressions>

        <query id="selectAllUser" name="查找所有用户" mapper="User">

            SELECT u.ID as ID, u.XINGMING as XINGMING

            FROM ORG_USER u

        </query>

    <expressions>

</bridge>

<query/>配置说明:

属性配置:

id:表达式标识,命名规则如下(query均以select开头):

# selectAll{ModelMapper} ()

     描述: 查询指定映射模型中的所有数据;

     要求: 必须定义,{ModelMapper}<bridge>/<mapper>节点下的某个映射模型的id,首字母需大写;注意:必须针对<mapper/>下的每个子节点,必须编写查询模型中所有数据的表达式。

     参数: ;

     示例: selectAllUser

 # select{ModelMapper}By{Hierarchy} ({FieldValue})

     描述: 根据层级属性值查询指定映射模型中的数据,用于以树形结构展示层级数据;

     要求: 根据情况而定义,其余同上. {Hierarchy}中的首字母也需大写,若其为点分形式,则需去除".",并将每个单词首字母大写;

     参数: {FieldValue}: 层级的属性的值;

     示例: selectDepartmentByParentId(parentId)

  # select{ModelMapper}By{Field} ({FieldValue})

      描述: 根据模型映射的属性查询模型的数据;

      要求: 同上. {Field}为模型映射的属性id;

      参数: {FieldValue}: 属性的值;

      示例: selectDepartmentByName(name)

 # select{ModelMapper}By{ModelMapper}{Field} ({FieldValue})

      描述: 根据被关联模型的属性的值查询关联模型的数据;

      要求: 同上;

      参数: {FieldValue}: 被关联模型的属性的值;

      示例: selectDepartmentByUserId(userId)

name表达式描述信息。

mapper:查询结果数据映射。为<bridge>/<mapper>节点下的某个映射模型的id

内容配置:Sql数据查询语句。

1.3.3.    组织机构桥接器配置

组织机构桥接器支持数据库直接访问、Hibernate持久化框架访问等多种访问方式,当使用数据库直接访问配置时,需在业务系统工程目录下,添加applicationContext-org-bridge.xml 文件。其具体配置如下所述:

备注:背景标识的部分是业务系统需要根据自身情况所需灵活配置的

    <bean id="jdbcBridgeBuilder" class="com.cayenne.organization.bridge.impl.jdbc.JdbcBridgeBuilder">

        <property name="dataSource" ref="dataSource" />

        <property name="mapperLocation" value="classpath:cayenne-org-bridge-mapper.xml" />

</bean>

备注:其中mapperLocationvalue需指定为组织机构映射规则文件(cayenne-org-bridge-mapper.xml)的位置。

1.4. 消息提醒配置

消息提醒功能用于流程引擎针对某些业务动作被触发从而生产相应的消息向外部发送,BPMS系统对消息进行分发,以便于相关人员及时得知流程最新信息,从而更好的完成工作。

对于引擎来说,引擎只负责消息的触发与创建,至于消息发送的目的地,则由BPMS业务系统决定。

1.4.1.    添加消息引擎Camel依赖

流程引擎需要将消息引擎Camel的依赖包引入项目中。以Maven项目为例,需要在项目的pom.xml中加入如下依赖:

<dependency>
     <groupId>org.apache.camel</groupId>
     <artifactId>camel-core</artifactId>
     <version>${camel.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-spring</artifactId>
    <version>${camel.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-mail</artifactId>
    <version>${camel.version}</version>
</dependency>

l  在使用时将占位符${project.parent.version}替换为该版本号即可。

1.4.2.    消息路由规则配置

若想获取流程引擎的消息并进行发送,首先需配置一个消息路由的配置文件。在业务系统工程目录下,添加message-camel-routes.xml 文件,具体配置如下所述:

<routes xmlns="http://camel.apache.org/schema/spring">

    <!-- 待办消息 -->

    <route id="taskAssignmentRouteJms" description="待办提醒">

        <from uri="cayenne-bpm-engine://task:assignment" />

        <process ref="messageTemplateProcessor" />

        <filter>

            <spel>#{ @bpmEngineMessageRouteFilter.canBeRouted(exchange) == true }</spel>

        <to uri="jms:queue:taskAssignment"/>

        </filter>

    </route>

    <route id="taskAssignmentRouteDestination">

        <from uri="jms:queue:taskAssignment" />

        <recipientList>

            <method ref="taskAssignmentRecipientService" method="getRecipientList" />

        </recipientList>

    </route>

    <!-- 签收消息 -->

    <route id="taskClaimRouteJms" description="签收提醒">

        <from uri="cayenne-bpm-engine://task:claim" />

        <process ref="messageTemplateProcessor" />

        <filter>

            <spel>#{ @bpmEngineMessageRouteFilter.canBeRouted(exchange) == true }</spel>

        <to uri="jms:queue:taskClaim"/>

        </filter>

    </route>

    <route id="taskClaimRouteDestination">

    <from uri="jms:queue:taskClaim" />

        <recipientList>

            <method ref="taskClaimRecipientService" method="getRecipientList" />

        </recipientList>

    </route>

    <!-- 流程进展消息 -->

    <route id="taskCompletionRouteJms" description="执行进展提醒">

        <from uri="cayenne-bpm-engine://task:completion" />

        <process ref="messageTemplateProcessor" />

        <filter>

            <spel>#{ @bpmEngineMessageRouteFilter.canBeRouted(exchange) == true }</spel>

        <to uri="jms:queue:taskCompletion"/>

        </filter>

    </route>

    <route id="taskCompletionRouteDestination">

    <from uri="jms:queue:taskCompletion" />

        <recipientList>

            <method ref="taskCompletionRecipientService" method="getRecipientList" />

        </recipientList>

    </route>

    <!-- 退回消息 -->

    <route id="taskTurnbackRouteJms" description="退回提醒">

        <from uri="cayenne-bpm-engine://task:turnback" />

        <process ref="messageTemplateProcessor" />

        <filter>

            <spel>#{ @bpmEngineMessageRouteFilter.canBeRouted(exchange) == true }</spel>

        <to uri="jms:queue:taskTurnback"/>

        </filter>

    </route>

    <route id="taskTurnbackRouteDestination">

    <from uri="jms:queue:taskTurnback" />

        <recipientList>

            <method ref="taskTurnbackRecipientService" method="getRecipientList" />

        </recipientList>

    </route>

    <!-- 任务抄送消息 -->

    <route id="taskCopyToRouteJms" description="抄送提醒">

        <from uri="cayenne-bpm-engine://task:copyto" />

        <process ref="messageTemplateProcessor" />

        <filter>

            <spel>#{ @bpmEngineMessageRouteFilter.canBeRouted(exchange) == true }</spel>

        <to uri="jms:queue:taskCopyto"/>

        </filter>

    </route>

    <route id="taskCopyToRouteDestination">

    <from uri="jms:queue:taskCopyto" />

        <recipientList>

            <method ref="taskCopyToRecipientService" method="getRecipientList" />

        </recipientList>

    </route>

    <!-- 任务加签消息 -->

    <route id="taskAddSignRouteJms" description="加签提醒">

        <from uri="cayenne-bpm-engine://task:addsign" />

        <process ref="messageTemplateProcessor" />

        <filter>

            <spel>#{ @bpmEngineMessageRouteFilter.canBeRouted(exchange) == true }</spel>

        <to uri="jms:queue:taskAddsign"/>

        </filter>

    </route>

    <route id="taskAddSignRouteDestination">

    <from uri="jms:queue:taskAddsign" />

        <recipientList>

            <method ref="taskAddsignRecipientService" method="getRecipientList" />

        </recipientList>

    </route>

    <!-- 任务协助消息 -->

    <route id="taskAssistRouteJms" description="协助提醒">

        <from uri="cayenne-bpm-engine://task:assist" />

        <process ref="messageTemplateProcessor" />

        <filter>

            <spel>#{ @bpmEngineMessageRouteFilter.canBeRouted(exchange) == true }</spel>

        <to uri="jms:queue:taskAssist"/>

        </filter>

    </route>

    <route id="taskAssistRouteDestination">

    <from uri="jms:queue:taskAssist" />

        <recipientList>

            <method ref="taskAssistRecipientService" method="getRecipientList" />

        </recipientList>

    </route>

</routes>

Ø  <route>元素配置说明:

属性:

l  id: 消息路由标识。<routes>下所有子元素的id属性不允许重复。

l  description:消息路由描述。

       子元素:

l  <from>元素:表示消息发送的起始路由地址(即消息从哪发出)。uri属性:消息发送端起始地址。

l  <process>元素:消息内容及消息头处理器,用于解析消息模板得到消息内容。ref属性:映射的消息处理器类。

l  <filter>元素:消息过滤器,消息必须经过此过滤器并且返回true后才能继续发送,某种停止发送。子元素spel:引用消息过滤器类,并确定执行其中的哪个过滤方法。

l  <recipientList>元素:消息接收端列表(消息路由器)。子元素method:,ref属性:映射的消息路由器类,method属性:调用消息路由器类中的哪个方法。

1.4.3.    消息引擎配置

在流程引擎的Spring配置文件中,需将camelContext加入到bpEngineConfiguration配置中;在业务系统的Spring配置文件中,需要加入“消息处理器、消息过滤器、消息路由器”等接口地址,并配置jms服务地址及参数。此外,业务系统启动时,需要把消息路由的配置更新到系统中:

1)        流程引擎Spring配置中引入camelContext,将其加入到bpEngineConfiguration配置中:

<bean id="bpEngineConfiguration" class="com.cayenne.bpm.engine.kernel.activiti.cfg.ActivitiProcessEngineConfiguration">

        <constructor-arg>

            <bean class="org.activiti.spring.SpringProcessEngineConfiguration">

                <property name="processEngineName" value="activitiEngineWithSpring" />

                <property name="dataSource" ref="dataSource" />

                <property name="transactionManager" ref="transactionManager" />

                <property name="databaseSchemaUpdate" value="true" />

                <property name="mailServerHost" value="localhost" />

                <property name="mailServerPort" value="5025" />

                <property name="jobExecutorActivate" value="false" />

            </bean>

        </constructor-arg>

        <property name="camelContext" ref="camelContext" />

        <property name="orgBridgeBuilder" ref="orgBridgeBuilder" />

</bean>

2)        消息处理器、消息过滤器以及消息路由器:

<!-- 消息处理器 -->

    <bean id="messageTemplateProcessor" class="com.cayenne.bpm.workbench.message.processor.MessageTemplateProcessor">

        <property name="messageTemplateService">

            <bean class="com.cayenne.bpm.workbench.service.impl.FileMessageTemplateServiceImpl" />

        </property>

        <property name="messageRouteService">

            <bean class="com.cayenne.bpm.workbench.service.impl.MessageRouteServiceImpl" />

        </property>

        <property name="identityService" ref="identityService"></property>

    </bean>

    <!-- 消息过滤器 -->

    <bean id="bpmEngineMessageRouteFilter" class="com.cayenne.bpm.workbench.message.route.MessageRouteFilter" />

    <!-- 消息路由器 -->

    <bean id="taskAssignmentRecipientService" class="com.cayenne.bpm.workbench.message.route.TaskAssignmentRecipientService" />

    <bean id="taskCompletionRecipientService" class="com.cayenne.bpm.workbench.message.route.TaskCompletionRecipientService" />

    <bean id="taskClaimRecipientService" class="com.cayenne.bpm.workbench.message.route.TaskClaimRecipientService" />

    <bean id="taskTurnbackRecipientService" class="com.cayenne.bpm.workbench.message.route.TaskTurnbackRecipientService" />

    <bean id="taskCopyToRecipientService" class="com.cayenne.bpm.workbench.message.route.TaskCopyToRecipientService" />

    <bean id="taskAddsignRecipientService" class="com.cayenne.bpm.workbench.message.route.TaskAddSignRecipientService" />

    <bean id="taskAssistRecipientService" class="com.cayenne.bpm.workbench.message.route.TaskAssistRecipientService" />

3)        Jms服务地址及配置参数:

<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">

       <property name="brokerURL" value="vm://localhost?broker.persistent=false&amp;broker.useJmx=false&amp;broker.deleteAllMessagesOnStartup=true&amp;broker.schedulerSupport=true" />

    </bean>

     

    <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory" init-method="start" destroy-method="stop">

       <property name="maxConnections" value="8" />

       <property name="connectionFactory" ref="jmsConnectionFactory" />

    </bean>

     

    <bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">

       <property name="connectionFactory" ref="pooledConnectionFactory"/>

       <property name="concurrentConsumers" value="10"/>

    </bean>

     

    <bean id="jms" class="org.apache.activemq.camel.component.ActiveMQComponent">

        <property name="configuration" ref="jmsConfig"/>

</bean>

4)        业务系统启动时更新消息路由配置:

//获取的地址,读取为InputStream ,通过该输入流得到消息路由定义对象
RoutesDefinition routes = this.camelContext.loadRoutesDefinition(input);
List<RouteDefinition> routeDefinitions = this.camelContext.getRouteDefinitions();
 
if (null != routeDefinitions && routeDefinitions.size() > 0) {
    this.camelContext.removeRouteDefinitions(routeDefinitions);
}
this.camelContext.addRouteDefinitions(routes.getRoutes());

 

1.5. 接口使用样例

详细的接口说明请参见CAYENNE-BPMS-流程引擎API.doc

1.5.1.    部署流程接口

用于将由Cayenne流程设计器所设计的流程定义文件部署到引擎中。引擎通过com.cayenne.bpm.engine.BpRepositoryService服务对外提供部署流程的接口。使用了专门的部署器(com.cayenne.bpm.engine.repository.BpDeploymentBuilder),该部署器可同时将一个或多个流程,以及流程所需的附加文件等一次性部署到引擎中,为流程部署提供灵活且便捷的功能。

BpDeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeploymentBuilder();// 添加流程定义文件,并执行部署
BpDeployment deployment = deploymentBuilder.addClasspathResource("/simple.bpmn20.xml").deploy();

 

流程部署器(BpDeploymentBuilder)还提供了如下接口,用于部署多种形式的资源文件

/**
 * 添加指定的资源输入流到本次部署中
 * <p>
 * 
 * @param resourceName 资源名称,可为null. 可按目录结构方式为资源命名,以表示资源的归属,在统一处理表单的查询时极为有用 :-)
 * @param inputStream 资源输入流,不能为null
 */
BpDeploymentBuilder addInputStream(String resourceName, InputStream inputStream);
 /**
 * classpath路径中指定的资源加入本次部署中
 * <p>
 * 指定的资源不存在时,将抛出运行时异常
 * 
 * @param resource 所要部署的资源文件的classpath路径,不能为null或空
 */
BpDeploymentBuilder addClasspathResource(String resource);
 /**
 * 将文本内容资源加入本次部署中
 * <p>
 * 
 * @param resourceName 资源名称,可为null
 * @param text 资源文本内容,不能为null或空
 */
BpDeploymentBuilder addString(String resourceName, String text);
 /**
 * zip资源输入流加入本次部署中
 * <p>
 * 
 * @param zipInputStream zip资源输入流,不能为null
 */
BpDeploymentBuilder addZipInputStream(ZipInputStream zipInputStream);
 /**
 * 部署所有资源(将所有加入的资源一次性部署到引擎中)
 * <p>
 * 该部署接口可被多次调用.<br>
 * 若所要部署的资源和最新的(通过{@link #name(String) name}查找)已部署资源没有差别时,这些资源将不会被重复部署,并会返回该最新的部署的 {@link BpDeployment}实例;<br>
 * 否则,即使仅有一个文件存在差异也将进行一次完整的部署.
 * <p>
 * <b>: </b>为防止外部class对引擎稳定性造成影响,对与class,jar等资源是不会自动加载到引擎运行环境中的
 */
BpDeployment deploy();

1.5.2.    启动流程接口

用于创建流程实例。引擎通过com.cayenne.bpm.engine.BpRuntimeService服务对外提供启动流程的接口(BpProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceById(processDefinition.getId());)。主要提供了如下启动流程的接口,详细的接口介绍请查阅API文档。

l  根据流程定义key启动流程(最新版本)

BpProcessInstance startProcessInstanceByKey(String processDefinitionKey)

l  根据流程定义key启动流程(最新版本),并携带业务实体的Key(=ID)

BpProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey);

l  根据流程定义key启动流程(最新版本),并设置流程启动变量

BpProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables);

l  根据流程定义key启动流程(最新版本),并携带业务实体的Key(=ID),以及启动变量

BpProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey,Map<String, Object> variables);

1.5.3.    工单列表查询接口

用于查询待办/已办/我提交的工单列表。引擎通过com.cayenne.bpm.engine.BpHistoryService服务对外提供相关列表的查询接口。详细的接口介绍请查阅API文档。

1.5.3.1.       待办

//查询指定流程定义key且分派给我或者待我签收的任务
List<BpHistoricTaskInstance>  hpi = processEngine.getHistoryService().createHistoricTaskInstanceQuery()
.processDefinitionKey(processDefinitionKey)
.taskCandidateOrAssigned(user).unfinished()
.orderByHistoricTaskInstanceStartTime().desc().list();

1.5.3.2.       已办

//首先查询出所有我已处理的任务(任务的查询详见3.4.2节)
List<BpHistoricTaskInstance> htiList = processEngine.getHistoryService().createHistoricTaskInstanceQuery()
.processDefinitionKey(processDefinitionKey).taskAssignee(UserToken.getToken()).finished().list();
//获得所有任务所在的流程实例
Set<String> bpiSet = new HashSet<String>();
for (BpHistoricTaskInstance hti : htiList) {
         bpiSet.add(hti.getProcessInstanceId());
}
//查询指定流程定义key和流程实例,并且由我处理过的流程
List<BpHistoricProcessInstance>  hpi = processEngine.getHistoryService().createHistoricProcessInstanceQuery()
.processDefinitionKey(processDefinitionKey).processInstanceIds(bpiSet)
.orderByProcessInstanceStartTime().desc();

1.5.3.3.       由我创建的

/查询指定流程定义key,并且由我创建的流程
List<BpHistoricProcessInstance>  hpi = processEngine.getHistoryService().createHistoricProcessInstanceQuery()
.processDefinitionKey(processDefinitionKey)
.startedBy(UserToken.getToken())
.orderByProcessInstanceStartTime().desc().list();