Part II. jBPM Core
5.1。概述
本章介绍了API需要加载过程和执行它们。更多的细节如何定义过程本身,看看在BPMN 2.0章。
与流程引擎交互(例如,开始一个过程),你需要建立一个会话。此会话将被用来与流程引擎进行通信。会话需要引用一个知识库,其中包含所有相关的过程定义的引用。这个知识库用于查找过程定义时必要的。要创建一个会话,您首先需要创建一个知识库,加载所有必要的流程定义(这可以从各种来源,从类路径中,文件系统或流程库),然后实例化一个会话。
一旦你建立了一个会话,你可以使用它来开始执行流程。每当开始一个过程,创建一个新的流程实例(这一过程定义),维护流程的特定实例的状态。
例如,假设您正在编写一个应用程序来处理销售订单。然后您可以定义一个或多个过程定义,定义应该如何处理订单。在启动应用程序时,您首先需要创建一个包含这些过程定义的知识库。然后,您可以创建一个会话基于此知识库,这样,每当一个新的销售订单时,将启动一个新的流程实例的销售订单。这一过程实例包含的状态过程,具体的销售要求。
知识库可以跨会话和共享通常只创建一次,开始的时候应用程序(如创建知识库可以而重量级它包括解析和编译过程定义)。知识库可以动态地改变(所以你可以添加或删除进程在运行时)。
会话可以创建基于知识库和用于执行流程和与引擎交互。您可以创建尽可能多的独立会话需要和创建一个会话被认为是相对较轻。有多少会话创建是取决于你。一般来说,最简单的情况下开始创建一个会话,然后在应用程序中从不同的地方。你可以决定创建多个会话如果例如你想拥有多个独立处理单元(例如,如果你想要所有流程从一个客户是完全独立于流程为另一个客户,您可以创建一个独立的会话为每个客户)或如果你需要多个会话原因可伸缩性。如果你不知道该做什么,只是开始通过一个知识库包含所有您的流程定义和创建一个会话,然后使用它来执行所有的流程。
jBPM项目有一个清晰的分离API用户应该之间的相互作用和实际实现类。公共API公开了大部分的功能我们认为“正常”的用户可以安全地使用和应该保持相当稳定版本。专家用户仍然可以访问内部类但应该意识到,他们应该知道他们在做什么,内部API在未来仍可能会改变。
如上所述,因此jBPM API应该被用来(1)创建一个知识库,其中包含您的流程定义,和(2)创建一个会话开始新流程实例,现有的信号,注册侦听器等。
5.2. KieBase
jBPM API允许您首先创建一个知识库。这个知识库应该包括所有您的流程定义,可能需要执行该会话。创建一个知识库,用KieHelper从各种资源加载过程(例如从类路径或文件系统),然后创建一个新的知识库的帮手。下面的代码片段显示了如何创建一个知识库组成的只有一个流程定义(使用在这种情况下,资源从类路径)。
KieHelper kieHelper = new KieHelper();
KieBase kieBase = kieHelper
.addResource(ResourceFactory.newClassPathResource("MyProcess.bpmn"))
.build(); ResourceFactory也有类似的方法来从文件系统加载文件,从URL,InputStream、读者,等等。
这被认为是手动创建知识库,虽然它很简单,不建议真正的应用程序开发但更多的尝试。后你会发现推荐和更强大的方式构建知识库,会话和更多——RuntimeManager知识。
5.3. KieSession
一旦你加载的知识库,您应该创建一个会话与引擎交互。这个会话可以用于启动新的流程,信号事件,等。下面的代码片段显示了是多么容易创建一个会话基于之前创建的知识库,并开始一个过程(通过id)。
KieSession ksession = kbase.newKieSession();
ProcessInstance processInstance = ksession.startProcess("com.sample.MyProcess");
5.3.1. ProcessRuntime
ProcessRuntime接口定义的所有会话交互的方法与流程,如下所示。
/**
* 启动一个新的流程实例的过程(定义)
* 使用引用给定的进程id。
*
* @param processId 进程的id,应该开始了
* @return ProcessInstance表示实例的过程就开始了
*/
ProcessInstance startProcess(String processId); /**
* 启动一个新的流程实例的过程(定义)
* 被给定的进程id引用使用。可以传递参数
* 同行审判(as),这些将考试和测验科as of the process变量。
*
*
* @param processId the id of the process that should be started
* @param parameters the process variables that should be set when starting the process instance
* @return the ProcessInstance that represents the instance of the process that was started
*/
ProcessInstance startProcess(String processId,
Map<String, Object> parameters); /**
* 信号的引擎类型参数定义一个事件发生
* 哪种类型的事件和事件参数可以包含额外的信息吗
* 相关事件。听这种类型的所有流程实例
* (外部)事件将通知。由于性能的原因,这种类型的事件
*信号时才应该使用一个流程实例应该能够通知
*其他流程实例。内部事件一个流程实例,使用
* processInstanceId signalEvent方法,还包括的流程实例
* in question.
*
* @param type the type of event
* @param event the data associated with this event
*/
void signalEvent(String type,
Object event); /**
* Signals the process instance that an event has occurred. The type parameter defines
* which type of event and the event parameter can contain additional information
* related to the event. All node instances inside the given process instance that
* are listening to this type of (internal) event will be notified. Note that the event
* will only be processed inside the given process instance. All other process instances
* waiting for this type of event will not be notified.
*
* @param type the type of event
* @param event the data associated with this event
* @param processInstanceId the id of the process instance that should be signaled
*/
void signalEvent(String type,
Object event,
long processInstanceId); /**
* Returns a collection of currently active process instances. Note that only process
* instances that are currently loaded and active inside the engine will be returned.
* When using persistence, it is likely not all running process instances will be loaded
* as their state will be stored persistently. It is recommended not to use this
* method to collect information about the state of your process instances but to use
* a history log for that purpose.
*
* @return a collection of process instances currently active in the session
*/
Collection<ProcessInstance> getProcessInstances(); /**
* Returns the process instance with the given id. Note that only active process instances
* will be returned. If a process instance has been completed already, this method will return
* null.
*
* @param id the id of the process instance
* @return the process instance with the given id or null if it cannot be found
*/
ProcessInstance getProcessInstance(long processInstanceId); /**
* Aborts the process instance with the given id. If the process instance has been completed
* (or aborted), or the process instance cannot be found, this method will throw an
* IllegalArgumentException.
*
* @param id the id of the process instance
*/
void abortProcessInstance(long processInstanceId); /**
* Returns the WorkItemManager related to this session. This can be used to
* register new WorkItemHandlers or to complete (or abort) WorkItems.
*
* @return the WorkItemManager related to this session
*/
WorkItemManager getWorkItemManager();
5.3.2. Event Listeners
会话提供了注册和删除侦听器方法。可以使用ProcessEventListener听流程相关事件,如开始或完成一个过程,进入和离开一个节点,等等。下面,ProcessEventListener类显示的不同的方法。一个事件对象提供相关信息,如流程实例和节点实例与事件有关。你可以使用这个API来登记自己的事件监听器。
public interface ProcessEventListener { void beforeProcessStarted( ProcessStartedEvent event );
void afterProcessStarted( ProcessStartedEvent event );
void beforeProcessCompleted( ProcessCompletedEvent event );
void afterProcessCompleted( ProcessCompletedEvent event );
void beforeNodeTriggered( ProcessNodeTriggeredEvent event );
void afterNodeTriggered( ProcessNodeTriggeredEvent event );
void beforeNodeLeft( ProcessNodeLeftEvent event );
void afterNodeLeft( ProcessNodeLeftEvent event );
void beforeVariableChanged(ProcessVariableChangedEvent event);
void afterVariableChanged(ProcessVariableChangedEvent event); } 一个关于事件前后的注意事项:这些事件通常像一堆,这意味着任何事件发生之前事件的直接结果,之间会发生之前和之后的事件。例如,如果一个后续节点触发的结果离开一个节点,该节点触发事件将发生afterNodeLeftEvent beforeNodeLeftEvent和中间的节点的左(第二个节点的触发是离开第一个节点)的直接结果。这样做可以让我们获得更容易导致事件之间的关系。同样,所有节点和节点离开事件触发启动过程的直接结果之间会发生beforeProcessStarted和afterProcessStarted事件。一般来说,如果你只是希望得到通知当一个特定事件发生时,你应该看着事件前只(发生时立即在事件实际发生之前)。时只查看事件之后,一个会觉得被解雇事件错误的订单,但由于事件触发后一堆(事件只会火当所有事件后,由于这个事件触发已经解雇了)。事件后只能使用如果你想确保所有与此有关的处理已经结束(例如,当您希望得到通知在开始的一个特定的流程实例已经结束。
还请注意,并不是所有的节点总是生成节点和/或节点离开事件触发。根据节点的类型,某些节点可能只剩下生成节点事件,别人可能只产生节点触发事件。抓住中间事件例如不产生触发事件(它们只剩下生成事件,因为它们不是真的引发了另一个节点,而激活以外)。同样,把中间事件不是生成左事件(他们只产生触发事件,因为它们不是真的离开,因为他们没有传出连接)。 jBPM开箱即用的提供了一个侦听器,可以用来创建一个审计日志(输出到控制台或文件系统)上的一个文件。该审核日志包含所有在运行时发生的不同事件所以很容易找出发生了什么事。注意,这些伐木工只能用于调试目的。以下日志实现默认支持: 控制台记录器:这到控制台记录器写出所有的事件。
文件日志:这个日志程序写出所有的事件到一个文件使用XML表示。此日志文件可能会被用在IDE生成树可视化执行期间发生的事件。
螺纹文件日志:因为一个文件日志记录器将事件写入磁盘只有当关闭日志记录器或当事件记录器的数量达到一个预定义的水平,它不能在运行时调试过程时使用。螺纹文件记录器将事件写入一个文件指定的时间间隔后,使它可以使用日志记录器来可视化实时进展,而调试过程。 KieServices让你KieRuntimeLogger添加到会话,如下所示。当创建一个控制台记录器,知识需要创建日志记录器的会话必须作为参数传递。文件日志还需要创建日志文件的名称,和螺纹文件日志需要间隔(以毫秒为单位),在此之后的事件应该被保存。你应该关闭日志记录器在您的应用程序。
import org.kie.api.KieServices;
import org.kie.api.logger.KieRuntimeLogger;
...
KieRuntimeLogger logger = KieServices.Factory.get().getLoggers().newFileLogger(ksession, "test");
// add invocations to the process engine here,
// e.g. ksession.startProcess(processId);
...
logger.close(); 创建的日志文件的文件的伐木工包含一个基于xml的概述在运行时发生的所有事件。它可以打开在Eclipse中,在Drools Eclipse插件使用审计视图,事件被可视化为树的地方。事件发生前后之间的事件显示为孩子的事件。下面的屏幕截图显示了一个简单的例子,开始一个过程的激活导致开始节点,一个动作节点和结束节点,之后完成的过程。 5.3.3。相关的钥匙 常见的一种需求在处理过程能力分配给流程实例的业务标识符,可以稍后引用不知道实际的流程实例的id(生成)。jBPM提供这些功能,允许使用CorrelationKey CorrelationProperties组成的。CorrelationKey可以有单独的属性描述它(在大多数情况下),但它可以作为多值属性集。
相关功能提供接口的一部 CorrelationAwareProcessRuntime 这暴露了以下方法:
/**
* Start a new process instance. The process (definition) that should
* be used is referenced by the given process id. Parameters can be passed
* to the process instance (as name-value pairs), and these will be set
* as variables of the process instance.
*
* @param processId the id of the process that should be started
* @param correlationKey custom correlation key that can be used to identify process instance
* @param parameters the process variables that should be set when starting the process instance
* @return the ProcessInstance that represents the instance of the process that was started
*/
ProcessInstance startProcess(String processId, CorrelationKey correlationKey, Map<String, Object> parameters); /**
* Creates a new process instance (but does not yet start it). The process
* (definition) that should be used is referenced by the given process id.
* Parameters can be passed to the process instance (as name-value pairs),
* and these will be set as variables of the process instance. You should only
* use this method if you need a reference to the process instance before actually
* starting it. Otherwise, use startProcess.
*
* @param processId the id of the process that should be started
* @param correlationKey custom correlation key that can be used to identify process instance
* @param parameters the process variables that should be set when creating the process instance
* @return the ProcessInstance that represents the instance of the process that was created (but not yet started)
*/
ProcessInstance createProcessInstance(String processId, CorrelationKey correlationKey, Map<String, Object> parameters); /**
* Returns the process instance with the given correlationKey. Note that only active process instances
* will be returned. If a process instance has been completed already, this method will return
* null. *
* @param correlationKey the custom correlation key assigned when process instance was created
* @return the process instance with the given id or null if it cannot be found
*/
ProcessInstance getProcessInstance(CorrelationKey correlationKey);
相关性通常使用长时间运行的流程,因此需要启用能够永久持久性存储相关信息。 5.3.4线程。 在以下文本,我们会参考两种类型的“多线程”:逻辑与技术。多线程技术是当多个线程或进程开始在电脑上,例如Java或C程序。逻辑多线程是我们所看到在BPM流程过程达到并行网关为例。从功能的角度来看,最初的过程将分为两个过程,以并行方式执行。
当然,jBPM引擎支持逻辑多线程:例如,流程,包括并行网关。我们选择使用一个线程来实现逻辑多线程:jBPM流程,包括逻辑多线程将只在一个技术线程执行。这样做的主要原因是,多个(技术)线程需要能够彼此交流状态信息,如果他们正在相同的过程。这个需求带来了一系列的并发症。虽然看起来似乎多线程将带来性能优势,确保所需的额外的逻辑不同的线程一起工作也意味着这是没有保证的。也有额外的开销,因为我们需要避免竞态条件和死锁。 一般来说,jBPM引擎在串行执行行动。例如,当发动机任务过程中遇到一个脚本,它将同步执行的脚本,等待它完成在继续之前执行。类似地,如果一个过程遇到一个并行网关,它将依次触发每个即将离任的分支,一个接一个。这是可能的因为几乎总是即时执行,这意味着它非常快,生产几乎没有开销。因此,用户通常会不会注意到这一点。同样,动作脚本过程中也同步执行,和引擎将等待他们在继续之前完成这一过程。例如,做一个thread . sleep(…)作为脚本的一部分,不会让引擎继续执行其他地方但会阻塞引擎线程在此期间。
同样的原则也适用于服务任务。当一个服务任务是达到在一个过程中,发动机也将同步调用此服务的处理程序。引擎将等待completeWorkItem(…)方法返回之前继续执行。重要的是,你的服务处理程序执行如果没有即时执行异步服务。 一个例子,这将是一个服务调用外部服务的任务。因为远程调用此服务的延迟和等待太久,结果将会如何可能是一个好主意异步调用这个服务。这意味着处理程序只会调用服务并将通知引擎后,结果是可用的。同时,流程引擎然后继续执行过程。
人工任务服务的一个典型的例子,需要异步调用,因为我们不想让引擎等到人类演员来回应请求。人工任务处理程序只会创建一个新的任务(任务列表的分配演员)人工任务节点时触发。引擎将能够继续执行过程的其余部分(如果有必要)和异步处理程序将通知引擎当用户已经完成了任务。 5.4 . RuntimeManager. RuntimeManager引入了简化和授权使用API的知识特别是在上下文的过程。它提供了可配置的策略,控制实际运行时执行(KieSessions如何提供),默认情况下提供了以下: 单——运行时经理维护单一KieSession无论可用的进程数量
每个请求运行时经理提供新的KieSession为每个请求
每个流程实例,运行时经理之间保持映射流程实例和KieSession总是提供相同KieSession每当处理流程实例
运行时经理主要负责管理和交付RuntimeEngine给调用者的实例。反过来,RuntimeEngine jBPM引擎封装了两个最重要的元素:
KieSession
TaskService
这两个组件已经配置为彼此工作顺利从最终用户没有额外的配置。不再需要注册处理程序或人工任务跟踪是否连接到服务。
public interface RuntimeManager { /**
* Returns <code>RuntimeEngine</code> instance that is fully initialized:
* <ul>
* <li>KiseSession is created or loaded depending on the strategy</li>
* <li>TaskService is initialized and attached to ksession (via listener)</li>
* <li>WorkItemHandlers are initialized and registered on ksession</li>
* <li>EventListeners (process, agenda, working memory) are initialized and added to ksession</li>
* </ul>
* @param context the concrete implementation of the context that is supported by given <code>RuntimeManager</code>
* @return instance of the <code>RuntimeEngine</code>
*/
RuntimeEngine getRuntimeEngine(Context<?> context);
/**
* Unique identifier of the <code>RuntimeManager</code>
* @return
*/
String getIdentifier();
/**
* Disposes <code>RuntimeEngine</code> and notifies all listeners about that fact.
* This method should always be used to dispose <code>RuntimeEngine</code> that is not needed
* anymore. <br/>
* ksession.dispose() shall never be used with RuntimeManager as it will break the internal
* mechanisms of the manager responsible for clear and efficient disposal.<br/>
* Dispose is not needed if <code>RuntimeEngine</code> was obtained within active JTA transaction,
* this means that when getRuntimeEngine method was invoked during active JTA transaction then dispose of
* the runtime engine will happen automatically on transaction completion.
* @param runtime
*/
void disposeRuntimeEngine(RuntimeEngine runtime);
/**
* Closes <code>RuntimeManager</code> and releases its resources. Shall always be called when
* runtime manager is not needed any more. Otherwise it will still be active and operational.
*/
void close();
} RuntimeEngine接口提供了最重要的方法来获得引擎组件:
public interface RuntimeEngine { /**
* Returns <code>KieSession</code> configured for this <code>RuntimeEngine</code>
* @return
*/
KieSession getKieSession();
/**
* Returns <code>TaskService</code> configured for this <code>RuntimeEngine</code>
* @return
*/
TaskService getTaskService();
} RuntimeManager将确保无论战略,它将提供相同功能的时候RuntimeEngine的初始化和配置。这意味着:
KieSession将含有相同的工厂(在内存或基于JPA)
WorkItemHandlers将注册在每个KieSession(从数据库加载或新创建的)
事件监听器(流程、议程WorkingMemory)将注册在每个KieSession(从数据库加载或新创建的)
TaskService将配置:
JTA事务管理器
至于KieSession相同的实体管理器工厂
UserGroupCallback从环境
另一方面,RuntimeManager维护引擎处理以及通过提供专用的方法处理RuntimeEngine不再需要的时候它会释放任何资源。 5.4.2. Strategies 单策略——指示RuntimeManager保持单一实例RuntimeEngine(以及反过来单一实例KieSession TaskService)。访问RuntimeEngine同步,线程安全虽然它带有一个性能损失由于同步。这种策略类似于默认可用在jBPM版本5。x,它被认为是最简单的策略和建议。
它有以下特征重要的评估,同时考虑了给定的场景: 小内存占用,单一实例的运行时引擎和任务服务
简单和紧凑的设计和使用
适合低到中等负载流程引擎由于同步访问
由于单一KieSession实例所有状态对象(如事实)是直接可见的所有流程实例,反之亦然
没有上下文,这意味着当检索实例的RuntimeEngine singleton RuntimeManager上下文实例并不重要,通常EmptyContext.get()虽然使用null参数是可以接受的
跟踪KieSession RuntimeManager重启之间使用id,以确保它将使用相同的会话——这个id作为序列化文件磁盘上的临时存储位置,取决于环境可以以下之一:
jbpm.data价值。dir系统属性
jboss.server.data价值。dir系统属性
. io .给出的值tmpdir系统属性
每个请求策略——指示RuntimeManager为每个请求提供RuntimeEngine的新实例。当请求RuntimeManager将考虑在单一事务中一个或多个调用。它必须返回相同的实例RuntimeEngine在单一事务以确保正确性国家另有操作在一个调用不可见。这是一种“无状态”策略,只提供了请求范围状态,一旦请求完成RuntimeEngine将永久破坏——KieSession信息从数据库中删除,以防使用持久性。
它有以下特点:
完全隔离流程引擎和任务为每个请求服务操作
完全无状态,存储事实只有请求的持续时间是有意义的
适合高负载、无状态流程(不涉及事实或计时器之间应当保存请求)
KieSession只有生活期间的要求和最终被摧毁
没有上下文,这意味着当从每个请求检索实例RuntimeEngine RuntimeManager上下文实例并不重要,通常EmptyContext.get()虽然使用null参数是可以接受的
每个流程实例策略——指示RuntimeManager保持严格的KieSession和ProcessInstance之间的关系。这意味着KieSession可以只要ProcessInstance属于活跃。这个策略提供最灵活的方法,利用先进的功能引擎像规则评估的隔离(仅给流程实例),最大的性能和减少潜在的瓶颈intriduced同步,同时减少数量的KieSessions流程实例,而不是实际数量的请求数(与每个请求策略)。
它有以下特点:
最先进的战略提供隔离只给流程实例
严格KieSession和ProcessInstance之间的关系以确保它总是带来同样KieSession ProcessInstance
合并生命周期的KieSession ProcessInstance使两个处理流程实例完成(完成或中止)
允许维护数据(如事实,计时器)在流程实例的范围,只有流程实例将可以访问这些数据
介绍了一些开销由于需要查找和加载KieSession流程实例
验证使用KieSession所以不能用于其他流程实例(ab),在这种情况下抛出异常
上下文——接受以下上下文实例:
EmptyContext或null -启动流程实例时没有可用的流程实例id
ProcessInstanceIdContext——在流程实例被创建后使用
CorrelationKeyContext——作为替代ProcessInstanceIdContext使用自定义(业务)的关键,而不是流程实例id 第5.4.3使用。 定期使用场景RuntimeManager是:
在应用程序启动时
构建RuntimeManager并保持应用程序的整个生命时间,它是线程安全的,可以(或者应该)并发访问
在请求
使用适当的上下文实例得到RuntimeEngine RuntimeManager致力于RuntimeManager的策略
从RuntimeEngine得到KieSession和/或TaskService
上执行操作KieSession和/或TaskService如startProcess completeTask等等
一旦完成处理处置使用RuntimeManager RuntimeEngine。disposeRuntimeEngine方法
在应用程序关闭
关闭RuntimeManager 5.4.3.1。例如
这里是如何构建RuntimeManager并获得RuntimeEngine(封装KieSession和TaskService):
// first configure environment that will be used by RuntimeManager
RuntimeEnvironment environment = RuntimeEnvironmentBuilder.Factory.get()
.newDefaultInMemoryBuilder()
.addAsset(ResourceFactory.newClassPathResource("BPMN2-ScriptTask.bpmn2"), ResourceType.BPMN2)
.get(); // next create RuntimeManager - in this case singleton strategy is chosen
RuntimeManager manager = RuntimeManagerFactory.Factory.get().newSingletonRuntimeManager(environment); // then get RuntimeEngine out of manager - using empty context as singleton does not keep track
// of runtime engine as there is only one
RuntimeEngine runtime = manager.getRuntimeEngine(EmptyContext.get()); // get KieSession from runtime runtimeEngine - already initialized with all handlers, listeners, etc that were configured
// on the environment
KieSession ksession = runtimeEngine.getKieSession(); // add invocations to the process engine here,
// e.g. ksession.startProcess(processId); // and last dispose the runtime engine
manager.disposeRuntimeEngine(runtimeEngine);
这个示例提供了简单的(最小)的方式使用RuntimeManager RuntimeEngine虽然它提供了一些很有价值的信息:
KieSession将通过使用newDefaultInMemoryBuilder仅在内存中
会有单一可执行过程——通过增加它作为一种资产
TaskService配置,并通过LocalHTWorkItemHandler KieSession支持过程中用户任务能力
5.4.4配置。
知道什么时候创建的复杂性,处理,注册处理程序等的终端用户和移动到运行时经理知道何时/如何执行这些操作但仍然允许细粒度控制这个过程通过提供全面RuntimeEnvironment的配置。
public interface RuntimeEnvironment { /**
* Returns <code>KieBase</code> that shall be used by the manager
* @return
*/
KieBase getKieBase();
/**
* KieSession environment that shall be used to create instances of <code>KieSession</code>
* @return
*/
Environment getEnvironment();
/**
* KieSession configuration that shall be used to create instances of <code>KieSession</code>
* @return
*/
KieSessionConfiguration getConfiguration();
/**
* Indicates if persistence shall be used for the KieSession instances
* @return
*/
boolean usePersistence();
/**
* Delivers concrete implementation of <code>RegisterableItemsFactory</code> to obtain handlers and listeners
* that shall be registered on instances of <code>KieSession</code>
* @return
*/
RegisterableItemsFactory getRegisterableItemsFactory();
/**
* Delivers concrete implementation of <code>UserGroupCallback</code> that shall be registered on instances
* of <code>TaskService</code> for managing users and groups.
* @return
*/
UserGroupCallback getUserGroupCallback();
/**
* Delivers custom class loader that shall be used by the process engine and task service instances
* @return
*/
ClassLoader getClassLoader();
/**
* Closes the environment allowing to close all depending components such as ksession factories, etc
*/
void close(); 5.4.4.1。建筑RuntimeEnvironment 尽管大多数RuntimeEnvironment接口提供了对数据的访问作为环境的一部分,将使用RuntimeManager,用户应该利用建筑样式类提供API来配置RuntimeEnvironment流利使用预定义的设置。
public interface RuntimeEnvironmentBuilder { public RuntimeEnvironmentBuilder persistence(boolean persistenceEnabled); public RuntimeEnvironmentBuilder entityManagerFactory(Object emf); public RuntimeEnvironmentBuilder addAsset(Resource asset, ResourceType type); public RuntimeEnvironmentBuilder addEnvironmentEntry(String name, Object value); public RuntimeEnvironmentBuilder addConfiguration(String name, String value); public RuntimeEnvironmentBuilder knowledgeBase(KieBase kbase); public RuntimeEnvironmentBuilder userGroupCallback(UserGroupCallback callback); public RuntimeEnvironmentBuilder registerableItemsFactory(RegisterableItemsFactory factory); public RuntimeEnvironment get(); public RuntimeEnvironmentBuilder classLoader(ClassLoader cl);
public RuntimeEnvironmentBuilder schedulerService(Object globalScheduler);
RuntimeEnvironmentBuilder的实例可以通过RuntimeEnvironmentBuilderFactory提供预配置的构建器简化和RuntimeManager帮助用户构建环境。
public interface RuntimeEnvironmentBuilderFactory { /**
* Provides completely empty <code>RuntimeEnvironmentBuilder</code> instance that allows to manually
* set all required components instead of relying on any defaults.
* @return new instance of <code>RuntimeEnvironmentBuilder</code>
*/
public RuntimeEnvironmentBuilder newEmptyBuilder();
/**
* Provides default configuration of <code>RuntimeEnvironmentBuilder</code> that is based on:
* <ul>
* <li>DefaultRuntimeEnvironment</li>
* </ul>
* @return new instance of <code>RuntimeEnvironmentBuilder</code> that is already preconfigured with defaults
*
* @see DefaultRuntimeEnvironment
*/
public RuntimeEnvironmentBuilder newDefaultBuilder();
/**
* Provides default configuration of <code>RuntimeEnvironmentBuilder</code> that is based on:
* <ul>
* <li>DefaultRuntimeEnvironment</li>
* </ul>
* but it does not have persistence for process engine configured so it will only store process instances in memory
* @return new instance of <code>RuntimeEnvironmentBuilder</code> that is already preconfigured with defaults
*
* @see DefaultRuntimeEnvironment
*/
public RuntimeEnvironmentBuilder newDefaultInMemoryBuilder();
/**
* Provides default configuration of <code>RuntimeEnvironmentBuilder</code> that is based on:
* <ul>
* <li>DefaultRuntimeEnvironment</li>
* </ul>
* This one is tailored to works smoothly with kjars as the notion of kbase and ksessions
* @param groupId group id of kjar
* @param artifactId artifact id of kjar
* @param version version number of kjar
* @return new instance of <code>RuntimeEnvironmentBuilder</code> that is already preconfigured with defaults
*
* @see DefaultRuntimeEnvironment
*/
public RuntimeEnvironmentBuilder newDefaultBuilder(String groupId, String artifactId, String version);
/**
* Provides default configuration of <code>RuntimeEnvironmentBuilder</code> that is based on:
* <ul>
* <li>DefaultRuntimeEnvironment</li>
* </ul>
* This one is tailored to works smoothly with kjars as the notion of kbase and ksessions
* @param groupId group id of kjar
* @param artifactId artifact id of kjar
* @param version version number of kjar
* @param kbaseName name of the kbase defined in kmodule.xml stored in kjar
* @param ksessionName name of the ksession define in kmodule.xml stored in kjar
* @return new instance of <code>RuntimeEnvironmentBuilder</code> that is already preconfigured with defaults
*
* @see DefaultRuntimeEnvironment
*/
public RuntimeEnvironmentBuilder newDefaultBuilder(String groupId, String artifactId, String version, String kbaseName, String ksessionName);
/**
* Provides default configuration of <code>RuntimeEnvironmentBuilder</code> that is based on:
* <ul>
* <li>DefaultRuntimeEnvironment</li>
* </ul>
* This one is tailored to works smoothly with kjars as the notion of kbase and ksessions
* @param releaseId <code>ReleaseId</code> that described the kjar
* @return new instance of <code>RuntimeEnvironmentBuilder</code> that is already preconfigured with defaults
*
* @see DefaultRuntimeEnvironment
*/
public RuntimeEnvironmentBuilder newDefaultBuilder(ReleaseId releaseId);
/**
* Provides default configuration of <code>RuntimeEnvironmentBuilder</code> that is based on:
* <ul>
* <li>DefaultRuntimeEnvironment</li>
* </ul>
* This one is tailored to works smoothly with kjars as the notion of kbase and ksessions
* @param releaseId <code>ReleaseId</code> that described the kjar
* @param kbaseName name of the kbase defined in kmodule.xml stored in kjar
* @param ksessionName name of the ksession define in kmodule.xml stored in kjar
* @return new instance of <code>RuntimeEnvironmentBuilder</code> that is already preconfigured with defaults
*
* @see DefaultRuntimeEnvironment
*/
public RuntimeEnvironmentBuilder newDefaultBuilder(ReleaseId releaseId, String kbaseName, String ksessionName);
/**
* Provides default configuration of <code>RuntimeEnvironmentBuilder</code> that is based on:
* <ul>
* <li>DefaultRuntimeEnvironment</li>
* </ul>
* It relies on KieClasspathContainer that requires to have kmodule.xml present in META-INF folder which
* defines the kjar itself.
* Expects to use default kbase and ksession from kmodule.
* @return new instance of <code>RuntimeEnvironmentBuilder</code> that is already preconfigured with defaults
*
* @see DefaultRuntimeEnvironment
*/
public RuntimeEnvironmentBuilder newClasspathKmoduleDefaultBuilder();
/**
* Provides default configuration of <code>RuntimeEnvironmentBuilder</code> that is based on:
* <ul>
* <li>DefaultRuntimeEnvironment</li>
* </ul>
* It relies on KieClasspathContainer that requires to have kmodule.xml present in META-INF folder which
* defines the kjar itself.
* @param kbaseName name of the kbase defined in kmodule.xml
* @param ksessionName name of the ksession define in kmodule.xml
* @return new instance of <code>RuntimeEnvironmentBuilder</code> that is already preconfigured with defaults
*
* @see DefaultRuntimeEnvironment
*/
public RuntimeEnvironmentBuilder newClasspathKmoduleDefaultBuilder(String kbaseName, String ksessionName); 除了KieSession运行时经理提供TaskService也为集成组件的RuntimeEngine总是会配置和准备流程引擎和任务之间的通信服务。
因为默认构建器使用,它将已经有组预定义的元素,包括:
org.jbpm.persistence持久性单元名称将被设置。jpa(流程引擎和任务服务)
KieSession人工任务处理程序将自动注册
基于JPA的历史日志KieSession事件侦听器将自动注册
事件监听器触发规则任务评价KieSession(fireAllRules)将自动注册 5.4.4.2。注册处理程序和听众
延长了自己的处理程序或听众专用机制提供之际,RegisterableItemsFactory的实现
/**
* Returns new instances of <code>WorkItemHandler</code> that will be registered on <code>RuntimeEngine</code>
* @param runtime provides <code>RuntimeEngine</code> in case handler need to make use of it internally
* @return map of handlers to be registered - in case of no handlers empty map shall be returned.
*/
Map<String, WorkItemHandler> getWorkItemHandlers(RuntimeEngine runtime);
/**
* Returns new instances of <code>ProcessEventListener</code> that will be registered on <code>RuntimeEngine</code>
* @param runtime provides <code>RuntimeEngine</code> in case listeners need to make use of it internally
* @return list of listeners to be registered - in case of no listeners empty list shall be returned.
*/
List<ProcessEventListener> getProcessEventListeners(RuntimeEngine runtime);
/**
* Returns new instances of <code>AgendaEventListener</code> that will be registered on <code>RuntimeEngine</code>
* @param runtime provides <code>RuntimeEngine</code> in case listeners need to make use of it internally
* @return list of listeners to be registered - in case of no listeners empty list shall be returned.
*/
List<AgendaEventListener> getAgendaEventListeners(RuntimeEngine runtime);
/**
* Returns new instances of <code>WorkingMemoryEventListener</code> that will be registered on <code>RuntimeEngine</code>
* @param runtime provides <code>RuntimeEngine</code> in case listeners need to make use of it internally
* @return list of listeners to be registered - in case of no listeners empty list shall be returned.
*/
List<WorkingMemoryEventListener> getWorkingMemoryEventListeners(RuntimeEngine runtime); 一个最佳实践是扩展出来的箱子就添加你自己的。并不总是需要扩展作为默认的实现自定义处理程序和听众RegisterableItemsFactory提供了可能性。下面是一个列表的实现可能是有用的(它们下令在继承层次结构): org.jbpm.runtime.manager.impl。SimpleRegisterableItemsFactory——简单的实现空和基于反射产生的实例处理程序基于给定的类名称和听众
org.jbpm.runtime.manager.impl。DefaultRegisterableItemsFactory -扩展的简单实现,介绍了上述违约,仍然提供了相同的功能简单的实现
org.jbpm.runtime.manager.impl。KModuleRegisterableItemsFactory——扩展提供特定功能的默认实现kmodule还提供了相同的功能简单的实现
org.jbpm.runtime.manager.impl.cdi。InjectableRegisterableItemsFactory——扩展为CDI的默认实现环境和提供CDI风格方法找到处理程序通过生产商和听众 或者,简单的工作项(无状态或只需要KieSession)注册处理程序可能是众所周知的方式——定义为CustomWorkItem的一部分。conf文件,应当放在类路径。用这种方法做以下:
“drools.session创建文件。conf”里面meta - inf的类路径的根,为web应用程序将web - inf / classes / meta - inf
添加以下行drools.session。配置文件“drools。workItemHandlers = CustomWorkItemHandlers.conf”
“CustomWorkItemHandlers创建文件。conf”里面meta - inf的类路径的根,为web应用程序将web - inf / classes / meta - inf
自定义工作项处理程序在CustomWorkItemHandlers.conf MVEL风格
[
"Log": new org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler(),
"WebService": new org.jbpm.process.workitem.webservice.WebServiceWorkItemHandler(ksession),
"Rest": new org.jbpm.process.workitem.rest.RESTWorkItemHandler(),
"Service Task" : new org.jbpm.process.workitem.bpmn2.ServiceTaskHandler(ksession)
] 就是这样,现在所有这些工作项处理程序将注册为该应用程序创建的任何KieSession,不管是否使用RuntimeManager。
5.4.4.2.1。在CDI环境中注册处理程序和听众
当使用RuntimeManager CDI环境中有专门的接口,可用于提供定制WorkItemHandlers和eventlistener RuntimeEngine。
public interface WorkItemHandlerProducer { /**
* Returns map of (key = work item name, value work item handler instance) of work items
* to be registered on KieSession
* <br/>
* Parameters that might be given are as follows:
* <ul>
* <li>ksession</li>
* <li>taskService</li>
* <li>runtimeManager</li>
* </ul>
*
* @param identifier - identifier of the owner - usually RuntimeManager that allows the producer to filter out
* and provide valid instances for given owner
* @param params - owner might provide some parameters, usually KieSession, TaskService, RuntimeManager instances
* @return map of work item handler instances (recommendation is to always return new instances when this method is invoked)
*/
Map<String, WorkItemHandler> getWorkItemHandlers(String identifier, Map<String, Object> params);
} 事件监听器生产商应当标注与适当的限定符来表示他们提供什么类型的听众,所以选择一个来表示他们的类型:
@Process——ProcessEventListener
@Agenda——AgendaEventListener
@WorkingMemory——WorkingMemoryEventListener
public interface EventListenerProducer<T> { /**
* Returns list of instances for given (T) type of listeners
* <br/>
* Parameters that might be given are as follows:
* <ul>
* <li>ksession</li>
* <li>taskService</li>
* <li>runtimeManager</li>
* </ul>
* @param identifier - identifier of the owner - usually RuntimeManager that allows the producer to filter out
* and provide valid instances for given owner
* @param params - owner might provide some parameters, usually KieSession, TaskService, RuntimeManager instances
* @return list of listener instances (recommendation is to always return new instances when this method is invoked)
*/
List<T> getEventListeners(String identifier, Map<String, Object> params);
} 这些接口的实现应打包为bean档案(包括bean。xml在meta - inf)和放置在应用程序类路径(例如web应用程序的web - inf / lib)。足够的CDI RuntimeManager发现他们并注册基于每个KieSession创建或加载的数据存储。
一些参数提供给生产商允许处理程序/听众更有状态并能够做更高级的事情与发动机的引擎——就像信号或流程实例的一个错误。因此所有组件提供:
KieSession
TaskService
RuntimeManager 此外,一些过滤可以基于应用标识符(即方法)作为参数来决定如果RuntimeManager应当接收处理程序/听众。 5.5。服务 上RuntimeManager API提供了一套高水平服务从jBPM 6.2版。这些服务是最简单的方法(j)BPM功能嵌入到自定义应用程序。一套完整的模块交付这些服务的一部分。他们划分为几个模块来缓解他们收养在各种环境。
jbpm-services-api
只包含api类和接口
jbpm-kie-services
重写服务api——纯java的代码实现,没有框架的依赖
jbpm-services-cdi
CDI包装器的核心服务的实现
jbpm-services-ejb-api
扩展为ejb服务api的需要
jbpm-services-ejb-impl
EJB封装器的核心服务的实现
jbpm-services-ejb-timer
支持基于时间调度程序服务基于EJB TimerService操作例如计时器事件、期限等
jbpm-services-ejb-client
——目前只对JBoss EJB远程客户端实现
服务模块组合框架的依赖关系,因此开发人员可以*选择哪一个是适合他们,只使用。 5.5.1。部署服务
正如它的名字显示,其主要责任是部署(取消)单位。部署单元是kjar带来业务资产(如流程、规则、形式、数据模型)来执行。部署服务允许查询它的可用的部署单元,甚至他们RuntimeManager实例。 所以这个服务的典型用例是为您的系统提供动态行为,可以活跃同时和多个kjars同时执行。
// create deployment unit by giving GAV
DeploymentUnit deploymentUnit = new KModuleDeploymentUnit(GROUP_ID, ARTIFACT_ID, VERSION);
// deploy
deploymentService.deploy(deploymentUnit);
// retrieve deployed unit
DeployedUnit deployed = deploymentService.getDeployedUnit(deploymentUnit.getIdentifier());
// get runtime manager
RuntimeManager manager = deployed.getRuntimeManager(); 完整的DeploymentService接口如下:
public interface DeploymentService { void deploy(DeploymentUnit unit); void undeploy(DeploymentUnit unit); RuntimeManager getRuntimeManager(String deploymentUnitId); DeployedUnit getDeployedUnit(String deploymentUnitId); Collection<DeployedUnit> getDeployedUnits(); void activate(String deploymentId); void deactivate(String deploymentId); boolean isDeployed(String deploymentUnitId);
} 5.5.2。定义服务 部署时,每一个流程定义扫描使用定义服务,解析过程,提取有价值的信息。这些信息可以提供有价值的输入到系统通知用户有关什么是预期。定义服务提供信息:
流程定义- id、名称、描述
流程变量名称和类型
可重用的过程中使用的子流程(如果有的话)
服务任务(领域特定的活动)
用户任务包括分配信息
任务数据输入和输出信息
所以定义服务可以被视为一种支持服务,提供了相当多的信息从BPMN2中直接提取的流程定义。
String processId = "org.jbpm.writedocument"; Collection<UserTaskDefinition> processTasks =
bpmn2Service.getTasksDefinitions(deploymentUnit.getIdentifier(), processId); Map<String, String> processData =
bpmn2Service.getProcessVariables(deploymentUnit.getIdentifier(), processId); Map<String, String> taskInputMappings =
bpmn2Service.getTaskInputMappings(deploymentUnit.getIdentifier(), processId, "Write a Document" ); 虽然它通常是使用其他服务的组合(如部署服务),它也可以独立使用的细节流程定义,不来自kjar。这可以通过使用buildProcessDefinition定义服务的方法。
public interface DefinitionService { ProcessDefinition buildProcessDefinition(String deploymentId, String bpmn2Content,
ClassLoader classLoader, boolean cache) throws IllegalArgumentException; ProcessDefinition getProcessDefinition(String deploymentId, String processId); Collection<String> getReusableSubProcesses(String deploymentId, String processId); Map<String, String> getProcessVariables(String deploymentId, String processId); Map<String, String> getServiceTasks(String deploymentId, String processId); Map<String, Collection<String>> getAssociatedEntities(String deploymentId, String processId); Collection<UserTaskDefinition> getTasksDefinitions(String deploymentId, String processId); Map<String, String> getTaskInputMappings(String deploymentId, String processId, String taskName); Map<String, String> getTaskOutputMappings(String deploymentId, String processId, String taskName); } 5.5.3。流程服务
服务是一个过程,通常是最感兴趣的。一旦部署和定义服务已经用于饲料系统可以执行的东西。流程服务提供执行环境,允许:
启动新的流程实例
工作与现有的一个信号,它的细节,让变量等
使用工作项
同时服务过程是一个命令执行者,它允许执行命令(基本上ksession)来扩展它的功能。
要注意的是,过程服务侧重于运行时操作所以需要改变的时候,使用它(信号,改变变量等)等读操作的流程实例,而不是由循环虽然给列表显示可用的流程实例和调用getProcessInstance方法。,有专门的运行时数据服务,描述如下。
一个例子如何部署和运行过程可以完成如下:
KModuleDeploymentUnit deploymentUnit = new KModuleDeploymentUnit(GROUP_ID, ARTIFACT_ID, VERSION); deploymentService.deploy(deploymentUnit); long processInstanceId = processService.startProcess(deploymentUnit.getIdentifier(), "customtask"); ProcessInstance pi = processService.getProcessInstance(processInstanceId); 正如你所看到的开始过程预计deploymentId作为第一个参数。这是非常强大的,使服务轻松地与不同的部署工作,即使有相同的过程但是来自不同版本——kjar版本。
public interface ProcessService { Long startProcess(String deploymentId, String processId); Long startProcess(String deploymentId, String processId, Map<String, Object> params); void abortProcessInstance(Long processInstanceId); void abortProcessInstances(List<Long> processInstanceIds); void signalProcessInstance(Long processInstanceId, String signalName, Object event); void signalProcessInstances(List<Long> processInstanceIds, String signalName, Object event); ProcessInstance getProcessInstance(Long processInstanceId); void setProcessVariable(Long processInstanceId, String variableId, Object value); void setProcessVariables(Long processInstanceId, Map<String, Object> variables); Object getProcessInstanceVariable(Long processInstanceId, String variableName); Map<String, Object> getProcessInstanceVariables(Long processInstanceId); Collection<String> getAvailableSignals(Long processInstanceId); void completeWorkItem(Long id, Map<String, Object> results); void abortWorkItem(Long id); WorkItem getWorkItem(Long id); List<WorkItem> getWorkItemByProcessInstance(Long processInstanceId); public <T> T execute(String deploymentId, Command<T> command); public <T> T execute(String deploymentId, Context<?> context, Command<T> command); } 5.5.4。运行时数据服务
运行时数据服务正如名字所暗示的那样,处理所有的指的是运行时信息:
启动流程实例
执行节点实例
执行节点实例
和更多的
使用这项服务作为主要的信息来源只要构建基于列表界面,显示过程定义、过程实例,对给定用户的任务,等。该服务被设计成尽可能有效,仍然提供所有必需的信息。
一些例子: 得到所有过程定义:
Collection definitions = runtimeDataService.getProcesses(new QueryContext()); 让活动流程实例:
Collection<processinstancedesc> instances = runtimeDataService.getProcessInstances(new QueryContext()); 获得给定流程实例的活跃节点:
Collection<nodeinstancedesc> instances = runtimeDataService.getProcessInstanceHistoryActive(processInstanceId, new QueryContext()); 把任务分配给john
List<tasksummary> taskSummaries = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter(0, 10)); 有两个重要的参数,运行时数据服务操作支持:
QueryContext
QueryFilter——QueryContext的延伸
这些提供的功能有效管理结果集分页、排序和排序(QueryContext)。而且可以应用于任务额外的过滤查询来搜索用户任务时提供更高级的功能。
public interface RuntimeDataService { // Process instance information Collection<ProcessInstanceDesc> getProcessInstances(QueryContext queryContext); Collection<ProcessInstanceDesc> getProcessInstances(List<Integer> states, String initiator, QueryContext queryContext); Collection<ProcessInstanceDesc> getProcessInstancesByProcessId(List<Integer> states, String processId, String initiator, QueryContext queryContext); Collection<ProcessInstanceDesc> getProcessInstancesByProcessName(List<Integer> states, String processName, String initiator, QueryContext queryContext); Collection<ProcessInstanceDesc> getProcessInstancesByDeploymentId(String deploymentId, List<Integer> states, QueryContext queryContext); ProcessInstanceDesc getProcessInstanceById(long processInstanceId); Collection<ProcessInstanceDesc> getProcessInstancesByProcessDefinition(String processDefId, QueryContext queryContext); Collection<ProcessInstanceDesc> getProcessInstancesByProcessDefinition(String processDefId, List<Integer> states, QueryContext queryContext); // Node and Variable instance information NodeInstanceDesc getNodeInstanceForWorkItem(Long workItemId); Collection<NodeInstanceDesc> getProcessInstanceHistoryActive(long processInstanceId, QueryContext queryContext); Collection<NodeInstanceDesc> getProcessInstanceHistoryCompleted(long processInstanceId, QueryContext queryContext); Collection<NodeInstanceDesc> getProcessInstanceFullHistory(long processInstanceId, QueryContext queryContext); Collection<NodeInstanceDesc> getProcessInstanceFullHistoryByType(long processInstanceId, EntryType type, QueryContext queryContext); Collection<VariableDesc> getVariablesCurrentState(long processInstanceId); Collection<VariableDesc> getVariableHistory(long processInstanceId, String variableId, QueryContext queryContext); // Process information Collection<ProcessDefinition> getProcessesByDeploymentId(String deploymentId, QueryContext queryContext); Collection<ProcessDefinition> getProcessesByFilter(String filter, QueryContext queryContext); Collection<ProcessDefinition> getProcesses(QueryContext queryContext); Collection<String> getProcessIds(String deploymentId, QueryContext queryContext); ProcessDefinition getProcessById(String processId); ProcessDefinition getProcessesByDeploymentIdProcessId(String deploymentId, String processId); // user task query operations UserTaskInstanceDesc getTaskByWorkItemId(Long workItemId); UserTaskInstanceDesc getTaskById(Long taskId); List<TaskSummary> getTasksAssignedAsBusinessAdministrator(String userId, QueryFilter filter); List<TaskSummary> getTasksAssignedAsBusinessAdministratorByStatus(String userId, List<Status> statuses, QueryFilter filter); List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId, QueryFilter filter); List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId, List<String> groupIds, QueryFilter filter); List<TaskSummary> getTasksAssignedAsPotentialOwnerByStatus(String userId, List<Status> status, QueryFilter filter); List<TaskSummary> getTasksAssignedAsPotentialOwner(String userId, List<String> groupIds, List<Status> status, QueryFilter filter); List<TaskSummary> getTasksAssignedAsPotentialOwnerByExpirationDateOptional(String userId, List<Status> status, Date from, QueryFilter filter); List<TaskSummary> getTasksOwnedByExpirationDateOptional(String userId, List<Status> strStatuses, Date from, QueryFilter filter); List<TaskSummary> getTasksOwned(String userId, QueryFilter filter); List<TaskSummary> getTasksOwnedByStatus(String userId, List<Status> status, QueryFilter filter); List<Long> getTasksByProcessInstanceId(Long processInstanceId); List<TaskSummary> getTasksByStatusByProcessInstanceId(Long processInstanceId, List<Status> status, QueryFilter filter); List<AuditTask> getAllAuditTask(String userId, QueryFilter filter); } 5.5.5。用户任务服务
用户任务服务涵盖了完整的生命周期的各个任务,因此它可以管理从开始到结束。它显式地从它消除了查询提供范围内的所有查询操作执行和移动到运行时数据服务。除了生命周期操作用户任务服务允许:
修改选中的属性
对任务变量的访问
访问任务附件
访问任务的评论
最重要的是用户任务服务也是一个命令执行程序,允许执行自定义任务命令。
完整的示例过程开始和完成用户任务完成的服务:
long processInstanceId =
processService.startProcess(deployUnit.getIdentifier(), "org.jbpm.writedocument"); List<Long> taskIds =
runtimeDataService.getTasksByProcessInstanceId(processInstanceId); Long taskId = taskIds.get(0); userTaskService.start(taskId, "john");
UserTaskInstanceDesc task = runtimeDataService.getTaskById(taskId); Map<String, Object> results = new HashMap<String, Object>();
results.put("Result", "some document data");
userTaskService.complete(taskId, "john", results); 5.5.6。与部署工作
部署服务提供了方便的方式将业务资产执行环境,但在某些情况下,需要一些额外的管理,使他们可以在正确的上下文中。
激活和失活的部署
想象情况有已经运行的进程数量给定的部署,然后新版本的这些流程的运行时环境。与管理员可以决定给定流程定义的新实例应该只使用新版本,同时已经活动实例应该继续之前的版本。
协助部署服务已经配备了以下方法:
激活
允许激活特定部署可以用于交互的意义将显示其流程定义,允许启动新的流程实例项目的流程
禁用
可以禁用部署将禁用选项看到或启动新的流程实例项目的流程,但将允许继续使用已经活动流程实例,如信号,与用户任务等工作
这个特性允许平稳过渡项目版本之间没有需要流程实例迁移。 部署同步
jBPM 6.2之前,jBPM服务没有部署存储在默认情况下。当嵌入jbpm-console / kie-wb他们利用sistem。git VFS库保存在服务器重启部署单位。虽然这工作很好,它有一些缺点:
不能用于自定义系统,使用服务
需要复杂的设置集群——饲养员和螺旋
与6.2版本jbpm服务来部署同步器,商店可以部署到数据库,包括它的部署描述符。同时不断地监控表来保持同步与其他设施可能使用相同的数据源。运行时,这是特别重要的在集群或jbpm运行控制台旁边自定义应用程序,应该能够工作在相同的工件。
必须配置默认同步(运行时核心服务虽然是ejb和自动启用cdi扩展)。配置同步需要配置如下:
TransactionalCommandService commandService = new TransactionalCommandService(emf); DeploymentStore store = new DeploymentStore();
store.setCommandService(commandService); DeploymentSynchronizer sync = new DeploymentSynchronizer();
sync.setDeploymentService(deploymentService);
sync.setDeploymentStore(store); DeploymentSyncInvoker invoker = new DeploymentSyncInvoker(sync, 2L, 3L, TimeUnit.SECONDS);
invoker.start();
....
invoker.stop(); 每3秒,部署将同步的初始延迟2秒。
调用最新版本的项目的过程
以防需要总是使用最新版本的项目的过程中,服务允许与各种操作交互使用部署id与最新的关键词。我们去了一个例子来更好地理解功能。
最初部署单元org.jbpm:人力资源:1.0招聘过程的第一个版本。几周之后,新版本开发和部署执行服务器- org.jbpm:HR.2.0版本2的招聘过程。
允许调用者的服务交互不担心如果他们使用最新版本,他们可以使用以下部署id:
org.jbpm.HR:latest 这将alwyas发现最新版本的项目所确定的:
groupId:org.jbpm
artifactId:人力资源
版本comparizon基于Maven版本号和依赖于基于Maen算法找到最新的一个。 这是一个完整的示例部署多个版本和交互总是最新的:
KModuleDeploymentUnit deploymentUnitV1 = new KModuleDeploymentUnit("org.jbpm", "HR", "1.0");
deploymentService.deploy(deploymentUnitV1); long processInstanceId = processService.startProcess("org.jbpm:HR:LATEST", "customtask");
ProcessInstanceDesc piDesc = runtimeDataService.getProcessInstanceById(processInstanceId); // we have started process with project's version 1
assertEquals(deploymentUnitV1.getIdentifier(), piDesc.getDeploymentId()); // next we deploy version 1
KModuleDeploymentUnit deploymentUnitV2 = new KModuleDeploymentUnit("org.jbpm", "HR", "2.0");
deploymentService.deploy(deploymentUnitV2); processInstanceId = processService.startProcess("org.jbpm:HR:LATEST", "customtask");
piDesc = runtimeDataService.getProcessInstanceById(processInstanceId); // this time we have started process with project's version 2
assertEquals(deploymentUnitV2.getIdentifier(), piDesc.getDeploymentId()); 如这提供了非常强大的特性与经常陈环境交互时,可以随时更新时使用过程定义。 5.6 .配置
有几个控制参数可以改变发动机的默认行为。这允许微调的执行环境需求和实际需求。所有这些参数都设置为JVM系统属性,通常用d当起动程序如应用服务器。
Table 5.1. Control parameters
Name | Possible values | Default value | Description | |
---|---|---|---|---|
jbpm.ut.jndi.lookup | String | 替代JNDI名称没有访问时使用默认一个UserTransaction)(java:comp / | ||
jbpm.enable.multi.con | true|false | false | 使多个流入/流出序列流对活动的支持 | |
jbpm.business.calendar.properties | String | /jbpm.business.calendar.properties | 可以提供替代路径业务日历配置文件的位置 | |
jbpm.overdue.timer.delay | Long | 2000 | 为逾期指定延迟计时器允许适当的初始化,以毫秒为单位 | |
jbpm.process.name.comparator | String | 可以提供替代comparator类名称特征为开始的过程,如果不设置NumberVersionComparator使用 | ||
jbpm.loop.level.disabled | true|false | true | 可以启用或禁用循环迭代跟踪,让先进的循环支持当使用XOR网关 | |
org.kie.mail.session | String | mail/jbpmMailSession | 可以提供替代使用的邮件会话的JNDI名称任务的最后期限 | |
jbpm.usergroup.callback.properties | String | /jbpm.usergroup.callback.properties | 允许为用户组提供替代路径位置回调实现(LDAP、DB) | |
jbpm.user.group.mapping | String | ${jboss.server.config.dir}/roles.properties | 可以提供替代位置的角色。属性JBossUserGroupCallbackImpl | |
jbpm.user.info.properties | String | /jbpm.user.info.properties | 可以提供替代路径的位置用户信息配置(LDAPUserInfoImpl使用) | |
org.jbpm.ht.user.separator | String | , | 允许为用户提供替代分离器演员和组织任务,默认是逗号(,) | |
org.quartz.properties | String | 可以提供石英配置文件的位置来激活基于石英计时器服务 | ||
jbpm.data.dir | String | ${jboss.server.data.dir} is available otherwise ${java.io.tmpdir} | 允许提供位置数据文件由jbpm应该存储 | |
org.kie.executor.pool.size | Integer | 1 | 允许为jbpm执行者提供线程池的大小 | |
org.kie.executor.retry.count | Integer | 3 | 允许重试次数提供尝试在出错的情况下由jbpm执行人 | |
org.kie.executor.interval | Integer | 3 | 允许提供频率用于检查由jbpm等待工作的执行者,在几秒钟内 | |
org.kie.executor.disabled | true|false | true | 启用或禁用jbpm遗嘱执行人 |
随机推荐
-
针对特定浏览器起作用的CSS: IE Chrome Firefox CSS Hack
Firefox的CSSHack 只在Firefox上应用的CSS Hack,虽然这种情况非常少,但有时也会碰到: @-moz-document url-prefix() { .cssSelector ...
-
【BZOJ】【3163】【HEOI2013】Eden的新背包问题
多重背包/思路题 多次询问,每次从所有物品中忽略一件,问最大收益…… 这题我用的zyf的一个“暴力”做法,就是先预处理出来g1[i][j]表示1~i号物品花了j块钱的最大价值,g2[i][j]表示i~ ...
-
JAVA多线程学习--生产者消费者问题
一.问题描述 生产者消费者问题是一个典型的线程同步问题.生产者生产商品放到容器中,容器有一定的容量(只能顺序放,先放后拿),消费者消费商品,当容器满了后,生产者等待,当容器为空时,消费者等待.当生产者 ...
-
Bencode编码解析的C++实现
Ben编码的基本规则 B编码中有4种类型:字符串.整型.列表.字典. 字符串 字符串的编码格式为:<字符串的长度>:<字符串>,其中<>括号中的内容为必需.例如,有 ...
-
(简单)华为荣耀4A SCL-TL00的usb调试模式在哪里打开的方法
就在我们使用PC通过数据线连接上安卓手机的时候,如果手机没有开启Usb调试模式,PC则没办法成功检测到我们的手机,有时候,我们使用的一些功能强大的App好比之前我们使用的一个App引号精灵,老版本就需 ...
-
Combat 战斗任务
发售年份 1977 平台 VCS 开发商 雅达利(Atari) 类型 射击 https://www.youtube.com/watch?v=2LxPEdUZOkE
-
使用requests进行模拟登陆
import re import requests header = { 'User-Agent': "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWe ...
-
Mysql5.7出现this is incompatible with sql_mode=only_full_group_by
vi /etc/my.cnf #编辑mysql配置文件 在 [mysqld]和[mysql]下添加 sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZE ...
-
PICE(6):集群环境里多异类端点gRPC Streaming - Heterogeneous multi-endpoints gRPC streaming
gRPC Streaming的操作对象由服务端和客户端组成.在一个包含了多个不同服务的集群环境中可能需要从一个服务里调用另一个服务端提供的服务.这时调用服务端又成为了提供服务端的客户端了(服务消费端) ...
-
使用 Navicate 连接 Oracle9i 数据库
Navicat Premium 是一个可多重连接的数据库管理工具,它可让你以单一程序同時连接到 MySQL.SQLite.Oracle 及 PostgreSQL 数据库,让管理不同类型的数据库更加方便 ...