IBM BPM提供了一组基于REST协议的API,作为查询和访问流程实例,任务和业务应用程序数据的工具。 REST API为外部客户端和内部流程提供对与业务流程定义(BPD),业务流程执行语言(BPEL)模块和联合资源相关的数据的访问。 可以通过IBM BPM随附的REST API Tester门户查看提供的REST API列表。
您可能会发现从BPD或服务组件体系结构(SCA)应用程序(例如BPEL流或中介)中以编程方式启动REST API会受益的情况。 例如,异常治理流程可能需要访问已停止流程实例的业务和流程数据,以便它可以重新启动或恢复流程实例。 REST API可以直接从IBM BPM数据库检索流程变量,输入/输出参数,业务对象,交易状态和其他详细信息。 这些API是轻量级的,可以通过编程方式从各种设备(例如台式机,平板电脑和移动设备)启动。
本教程展示了一种使用IBM BPM REST API通过Java™通过BPD以编程方式访问流程实例数据的方法。 示例实现显示了流程管理员如何通过使用基于REST API的流程应用程序的教练来管理已停止的流程。 本教程中包含的示例是在IBM BPM V8.5.5上实现的,但是它应该在所有IBM BPM V8.x版本中都没有任何更改地工作。
为了充分利用本教程,您应该熟悉IBM BPM的基本功能。 此外,了解REST,JavaScript,JSON,Java和一般编程知识也是有帮助的。
设计解决方案
在主要使用无头IBM BPM流程模式的环境中,获得对由于异常而停止(失败或挂起)的流程的可见性至关重要,以便您可以恢复或停止该流程。 例如,在IBM BPM工作流的无头模式中,整个过程通过一系列步骤作为自动化工作流完成,而无需人工干预,但是人工界面仅用于异常处理或过程管理。 为了有效地管理这种类型的异常治理流程,对于应用程序的用户和管理员来说,使用门户网站查询已停止的流程并进行批量管理非常有帮助。
例如,假设您需要一个简单的异常治理流程来查询无头IBM BPM流程的已停止流程实例的状态,以便您可以重新启动或恢复它们。 通常,它们是SCA流程,例如长时间运行的BPEL流程。
图1显示了有关如何实现已停止进程状态的查询的示例。
图1.实现示例:使用REST API的查询流程实例状态
此示例实现由一个称为Process Query的BPD组成,该BPD包含一个简单的Coach(用户界面),应用程序的用户可以在其中基于进程类型(IBM BPM或SCA)和已停止状态(失败或失败)来查询处于异常状态的进程。暂停)。 为了简化设计,假设用户要重新启动或结束已停止的流程实例。
使用IBM BPM Integration Service组件处理搜索失败或挂起的流程实例,该组件使用名为RESTQuery.jar
的自定义Java存档文件来运行IBM BPM REST API查询。 所述RESTQuery Java类,其中包含在RESTQuery.jar
,返回检索过程实例数据作为JSON(JavaScript对象符号)对象到集成服务的列表。 为了解析返回的JSON对象,该示例使用json2.js
实用程序库提取已停止的流程实例ID,然后将其显示在教练中。 如前所述,IBM BPM REST API支持在HTTP Accept标头中设置的JSON,JSONP和XML返回格式。 (JSONP返回格式仅在IBM BPM Standard中受支持,并且默认情况下不启用。有关详细信息,请参阅IBM知识中心上的IBM BPM 8.5.5文档中IBM BPM REST API支持的内容类型 )。
然后,基于返回的列表,用户可以选择重新启动或终止一个或多个流程实例。 选定的流程ID传递到另一个Integration Service组件,该组件通过RESTQuery Java类启动REST API,以重新启动或终止选定的流程实例。
此示例实现的范围是受REST API支持的简单用户界面,但是此设计方法也可以用于构建更自动化的治理流程。
现在,详细检查每个组件。
实施解决方案
图2显示了ProcessQuery_BPD ,其中包含一个称为Process Query HS的人工服务。
图2.流程查询BPD示例
如图3所示,该人工服务包含一个称为“ 查询流程HT”的指导,其中应用程序的用户查询已停止的流程实例。 图4显示了教练的布局。
图3. Process Query HS实现示例
图4.查询流程HT教练布局示例
Process Query HS服务包含完成实施的三个服务组件( 检索实例GS , 解析结果GS和对实例GS执行服务)。 当用户在流程或实例上输入搜索条件并单击“ 获取流程ID”时 ,“ 检索流程GS”服务将使用Java Integration组件启动RESTQuery
Java类的getStoppedInstances()
方法。 此类基于传递的参数构建REST服务URL,并针对IBM BPM服务器运行查询。 请求的响应类型在HTTP Accept标头中设置为JSON。 或者,请求的响应类型也可以作为URL查询字符串的一部分发送。
图5示出了Java积分步骤启动该getStoppedInstances()
的方法RESTQuery
Java类,和清单1只显示了的部分getStoppedInstances()
方法。 它根据Coach中用户指定的参数来构建并启动REST API URL。 该方法接受String类型的三个参数:IBM BPM服务器(主机和端口),查询的类型以及进程状态。 IBM BPM服务器值存储为环境变量。
图5.获取流程ID集成服务示例
清单1.构建和调用REST URL的Java代码
/* Map state values */
if (state.equalsIgnoreCase("FAILED"))
iState = "5";
else if (state.equalsIgnoreCase("SUSPENDED"))
iState = "2";
/* Set the URI based on the resource type */
if (processType.equalsIgnoreCase("BPD")) {
restURI = "rest/bpm/wle/v1/";
} else if (processType.equalsIgnoreCase("SCA")) {
restURI = "rest/bpm/bfm/v1/processes/";
/* Set default query parameters: for BPD (process), default is all
* detail; for SCA (service) default is blank (GET) */
parameters = parameters.concat("filter?whereClause=PROCESS_INSTANCE.STATE=").concat(iState);
}
urlStr = buildURL(bpmServer, restURI, parameters);
logger.info("REST URL: " + urlStr);
try {
/* open connection, set method and headers */
conn = createConnection(urlStr, method); logger.info("Connection created...");
/* Invoke REST service over HTTP and get response */
StringBuffer response = readResponse(conn);
result = response.toString();
logger.info("Result: " + result);
} catch (MalformedURLException me) {
String msg = "IOException thrown... " + me.getLocalizedMessage() + "...for: (" + urlStr + "," + method + ")";
logger.severe(msg);
throw new Exception(msg);
} catch (IOException io) {
String msg = "IOException thrown... " + io.getLocalizedMessage() + "...for: (" + urlStr + "," + method + ")";
logger.severe(msg);
throw new Exception(msg);
} catch (Exception e) {
String msg = "Exception thrown... " + e.getLocalizedMessage() + "...for: (" + urlStr + "," + method + ")";
logger.severe(msg);
throw new Exception(msg);
}
return (Object) result;
代码清单1中的Java代码根据进程类型构建REST URL,如表1所示。
表1.由getStoppedInstances()方法构建的REST URL
Craft.io类型 | Java构建的URL | 方法 |
---|---|---|
IBM BPM流程类型-失败的实例 | http:// bpm_server : port /rest/bpm/wle/v1/search/query?condition=instanceStatus %7CFailed&organization=byInstance&run=true &shared=false&filterByCurrentUser=false | 放 |
IBM BPM流程类型-挂起的实例 | http:// bpm_server : port /rest/bpm/wle/v1/search/query?condition=instanceStatus%7CSuspended&organization=byInstance&run= true&shared=false&filterByCurrentUser=false | 放 |
SCA进程类型-失败/挂起的实例 | http:// bpm_server : port /rest/bpm/bfm/v1/processes/filter?whereClause=PROCESS_INSTANCE.STATE= state_integer_code (其中state_integer_code可以是5或11) | 得到 |
RESTQuery.java
打包为Java归档文件,并作为文件资源导入到流程应用程序中(通过单击“库”导航窗格的“ 文件”菜单选项旁边的+符号),以便可以在Java中使用它。集成组件。 从本教程的“下载”部分,下载code_sample.zip并解压缩包含完整代码的示例.jar
文件。
由于需要REST客户端对IBM BPM服务器进行身份验证,因此RESTQuery
类实现了Authenticator接口,以提供用于基本身份验证的用户ID和密码。 这种简单的身份验证机制很简单。 在现实生活中,您可能需要考虑其他更安全的单点登录技术。
RESTQuery
Java类的getStoppedInstances()
方法将JSON结果对象作为Java String对象返回给调用BPD。 然后将该对象传递到Parse Result GS服务(如图6所示),该服务使用服务器端Javascript步骤将字符串结果转换为纯JSON对象,并解析结果元素以提取停止的流程实例ID和其他任何内容。必需的元素。
图6.解析结果GS一般服务实现
清单2显示了Parse Result GS步骤中包含的Javascript。
清单2.解析JSON结果对象的Javascript
if (tw.local.response != null && tw.local.response != '') {
log.info("Result: " + tw.local.response);
var jsonObject = JSON.parse(tw.local.response);
log.info("JSON Object: " + jsonObject);
// Build process id list
tw.local.processIds = new tw.object.listOf.String();
if(tw.local.processType == "BPM") {
for ( var pid=0; pid<jsonObject.data.data.length; pid++) {
tw.local.processIds[pid] = jsonObject.data.data[pid].instanceId.toString();
tw.local.state = jsonObject.data.data[pid].instanceStatus;
}
} else {
for ( var pid=0; pid<jsonObject.items.length; pid++) {
tw.local.processIds[pid] = jsonObject.items[pid].topLevelProcessInstanceName;
tw.local.state = jsonObject.items[pid].executionState;
}
}
} else
log.error("NULL Response returned!");
IBM BPM 8.5.x需要一个实用程序库来处理服务器端Javascript中的JSON对象。 此示例演示使用json2.js
(请参阅参考资料部分),必须将其作为文件资源导入BPD。 图7显示了实现此解决方案所需的文件资源。
图7.文件资源
检索到的流程实例ID将返回给教练,教练将它们显示为多选列表。 然后,用户可以选择一个或多个流程实例ID,并决定单击Restart或Terminate (请参见图8)。 为简单起见,该示例仅列出了已停止进程的实例ID。 在现实生活中,您可能希望列出实例ID的其他详细信息,例如进程名称,开始日期和失败日期,以帮助用户决定如何处理这些进程。
图8.查询流程指导
当用户单击Restart或Terminate时 ,教练将控制权传递给Act on Instance IS服务(请参见图9),该服务循环遍历每个实例ID,并启动RESTQuery.java
类的processAction()
方法。
图9.实例集成服务
此类接受String类型的四个参数: IBM BPM server
, instance ID
, action to perform
以及process type
。 它根据操作和流程类型构建适当的REST URL,然后启动API。
清单3显示了此方法的一部分(在“下载”部分中,请参见code_sample.zip
以获取完整的代码示例)。
清单3. processAction()方法的部分清单
/* Set the URI based on the resource type */
if (processType.equalsIgnoreCase("BPM")) {
restURI = "rest/bpm/wle/v1/process/";
parameters = parameters.concat(instanceId).concat("?action=").concat(action).concat("&parts=all");
} else if (processType.equalsIgnoreCase("SCA")) {
restURI = "rest/bpm/bfm/v1/process/";
if (action.equalsIgnoreCase("restart") || action.equalsIgnoreCase("resume"))
parameters = parameters.concat(instanceId).concat("?action=").concat(action);
else if (action.equalsIgnoreCase("terminate")) {
parameters = parameters.concat(instanceId).concat("?action=forceTerminateamp;invokeCompensation=false");
} else if (action.equalsIgnoreCase("delete")) {
parameters = parameters.concat(instanceId);
method = "DELETE"; // can only delete a failed/suspended process
}
}
urlStr = buildURL(bpmServer, restURI, parameters);
logger.info(urlStr);
try {
/* open connection, set method and headers */
conn = createConnection(urlStr, method);
/* Invoke REST service over HTTP and get response */
String response = readResponse(conn).toString();
object = ((response==null || response.trim().equals(""))? (conn.getResponseCode() + " " + conn.getResponseMessage()):response).toString();
logger.info( "Response object: " + (String)object);
}
}
表2根据流程类型和要采取的措施,显示了该方法生成和调用的URL。
表2.重新启动/终止REST API URL
Craft.io类型 | Java构建的URL | 方法 |
---|---|---|
IBM BPM流程类型- 重新启动程序 | http:/ bpm_server : port /rest/bpm/wle/v1/process/ process_instance_ID ?action=retry&parts=all | 放 |
IBM BPM流程类型- 终止过程 | http:// bpm_server : port /rest/bpm/wle/v1/process/ process_instance_ID ?action=terminate&parts=all | 放 |
SCA流程类型 -重新启动程序 | http:// bpm_server : port /rest/bpm/bfm/v1/process/ process_instance_ID ?action=restart | 放 |
SCA流程类型 -恢复过程 | http:// bpm_server : port /rest/bpm/bfm/v1/process/ process_instance_ID ?action=resume | 放 |
SCA流程类型 -删除过程 | http:// bpm_server : port /rest/bpm/bfm/v1/process/ process_instance_ID | 删除 |
SCA流程类型 -终止过程 | http:// bpm_server : port /rest/bpm/bfm/v1/process/ process_instance_ID ?action=forceTerminate&invokeCompensation=false | 放 |
然后,在“ 结果”部分中,呼叫状态会显示在教练底部的用户处,如图8所示。
测试应用程序
要测试该应用程序,请逐步执行用户将执行的步骤。 首先从您的环境中识别一些失败或停止的实例。 查找IBM BPM和BPEL流程实例–对BPD实例使用Process Designer中的检查器,对于BPEL实例使用Business Process Choreographer Explorer。 记下每个实例的实例ID。 从Process Designer或Process Portal运行ProcessQuery_BPD ,并在Coach屏幕中提供以下参数(参见图8):
流程类型:从列表中选择BPM 。
进程状态:从列表中选择“ 失败 ”。
单击获取进程ID 。
RESTQuery
Java类构造并启动REST服务并返回结果,这些结果显示在“ 进程 ID 列表”字段中。 从先前制作的手册列表中比较显示的实例ID的列表。
从显示的列表中选择一个或多个进程ID,然后单击重新启动 。 如果IBM BPM服务器能够重新启动进程,那么在结果部分的指导者底部会显示一个简短的结果(例如STATE_RUNNING
)。
对SCA进程类型和“挂起”状态重复上述步骤。 然后,WebSphere Application Server中的SystemOut.log
将显示代码中编写的消息。 同样,选择一个或多个检索到的进程ID,然后单击“ 终止”以终止和删除进程。
要比较和验证结果,可以从IBM BPM REST API Tester( http:// Your_IBM_BPM_Server : Your_http_port /bpmrest-ui
)运行RESTQuery
Java类构建的相同查询(可以从SystemOut.log
输出中复制该类编写的URL)。 http:// Your_IBM_BPM_Server : Your_http_port /bpmrest-ui
)。
结论
本教程描述了一种从IBM BPM流程流以编程方式访问IBM BPM REST API的方法。 它介绍了一个简单的用例和示例实现,以演示如何使用IBM BPM REST API快速,轻松地构建需要在运行时访问IBM BPM流程实例数据的定制异常管理流程。
因为REST API为IBM BPM数据库提供了透明层,所以与直接访问表和视图相比,它使对流程,服务和任务数据的访问变得更简单,更可维护。 REST API简化了跨分布在两个数据库中的BPD和SCA层对流程和实例数据的访问。 您可以扩展此方法,以构建更加自动化和可操作的异常流程管理工作流,以管理大量流程实例。
致谢
作者要感谢Bobby Pham对本教程的技术审查。
翻译自: https://www.ibm.com/developerworks/bpm/bpmjournal/1509_gopalan-trs/1509_gopalan.html