SAP JCO 连接 SAP 系统
Message Broker 介绍
IBM WebSphere Message Broker 做为高级企业服务总线的实现平台,在 IBM SOA (Service Oriented Architecture)架构应用中扮演着非常重要的角色。在企业应用整合中,WMB 具有高性能,高可靠性的特点,为基于标准和非标准的应用程序及服务提供了连通性和通用的数据转换能力。Message Broker 支持不同的数据格式之间的转化和处理,并可以将消息根据业务逻辑路由到不同的目标应用系统中;Message Broker 支持业界中常用的消息协议和消息传输方式,从而非常容易地允许企业现有的各种应用系统接入到企业服务总线。
连接 SAP 的几种方式
SAP 是业内领先的 ERP 软件,在企业内被作为核心应用系统广泛使用。随着业务需求的变化和跨系统的业务流程的需要,将 SAP 系统接入到 SOA 应用架构中,成为了常见的应用场景。Message Broker 提供了多种对 SAP 系统的接入方式,在 Message Broker 中常见的有以下两种:
使用 WBI SAP Adapter:WBI SAP Adapter 作为 SAP 系统和 Message Broker 的桥梁,支持两者之间双向、多线程和实时的交互。SAP Adapter 使用 WBI Adapter Framework 作为运行时环境,MQ 作为底层传输基础,JMS 作为传输协议。在使用 SAP Adapter 与 SAP 系统进行通讯时,Message Broker将符合业务对象 Schema 的 JMS 请求消息放到 Adapter 的请求队列中,Adapter 接收到请求消息后将消息取出并调用 SAP 系统提供的函数;随后,Adapter 将 SAP 系统返回的结果构造成符合业务对象 Schema 的 JMS 响应消息放到 Adapte r响应队列由 Message Broker 做进一步处理。除了支持常见的请求响应模式外。SAP Adapter 也可以主动侦听 SAP 系统发送的通知消息,将消息放到指定队列由 Message Broker 取出并处理。
使用 SAP JCO(Java Connector):SAP JCO 是 SAP 公司提供的基于 JNI 的符合 SAP RFC 规范的一组 API 接口,允许您在 JAVA 应用程序中使用该 API 来调用 SAP 系统的 RFC 函数,如下图 1 所示。JCO 支持两种对 SAP 系统的连接方式:直接连接和使用连接池。直接连接需要开发人员自己控制创建和断开 SAP 连接;使用连接池,可以重用池内已有的连接实例,从而获得更高的效率。
实质上,WBI SAP Adapter 的内部实现机制就是使用 SAP JCO 来连接 SAP,在 Message Broker 与 SAP Adapter 的交互过程中,SAP Adapter 接收到 Message Broker 发送的请求消息后,会通过 SAP JCO 类库来调用 SAP 应用系统提供的 RFC 函数,从而实现与 SAP 应用的交互。SAP Adapter 是符合 WBI Adapter Framework 的统一的连接 SAP 的适配器,有很多的设计、开发和测试工具作支持,它屏蔽了调用 SAP 应用系统 RFC 函数的技术细节,对与 SAP 系统的双向交互做了较好的封装,并使用 JMS 标准协议作为交互方式。但相对于直接使用 JCO 来说,WBI SAP Adapter 需要专门的开发环境和运行环境,其配置步骤和开发过程较为复杂,对开发人员的要求较高。如何在 Message Broker 中使用WBI SAP Adapter, 请参考附录相关文章;本文以下部分将详细介绍如何在 Message Broker 中直接使用 SAP JCO 来集成 SAP 应用,给开发者提供一个简单快速的解决方案。
本示例场景是从某企业业务场景中摘取出来的,在该场景中,Message Broker 作为企业整合平台的实现工具,将现有一些系统的业务功能根据需要包装成 Web 服务接入到企业服务总线中。其中,SAP HR 系统是该企业核心系统之一,维护着 HR 相关的数据和功能。由于企业新上 OA 系统作为员工日常工作的平台,员工在请假时候需要到 OA 系统登记并提交,在 OA 提交的请假信息按照企业要求需要在 SAP HR 中实现记账,根据现有系统的实现状况,针对员工请假登记这个业务需求我们做了如下图 2 的集成方案。
为实现员工请假登记这个功能,SAP 开发人员在 SAP HR 系统中开发了名字为 ZRFC_LEAVE 的 RFC 函数,ESB开发人员在 Message Broker 开发消息流,使用 SAP JCO 调用该 RFC 函数,最后将消息流发布为 Web 服务并由 OA 系统调用。
下面我们将根据这个简单的业务场景讲述具体的配置和开发过程,示例中用到的主要工具和类库以及对应的版本是:
Message Broker toolkit 6.02
Message Broker 6.003
SAP JCO 2.18
在该例中使用的Message Broker版本是6.0,但本文解决方案可适用于Message Broker V6.0、V6.1及以上版本。
配置 JCO
首先在开发前,需要配置 JCO。用户首先使用 SAP 提供的服务账号登陆http://service.sap.com/connectors,根据操作系统的类别下载 JCO 类库。在该示例中,我们下载的是 Windowns 操作系统对应的 sapjco-ntintel-2.1.8.zip,解压缩之后,
?将 librfc32.dll 和 sapjcorfc.dll 拷贝到“C:\WINDOWS\system32”中,这两个 dll 为调用 RFC 的运行时环境提供支持。
?将 sapjco.jar 拷贝到“C:\Documents and Settings\All Users\Application Data\IBM\MQSI\shared-classes”中,为 Message Broker 的运行时使用 JCO API 提供支持。
如果是在 AIX 环境下,则需要下载 sapjco-rs6000-xxx 的 tgz 包,解压缩后,将解压缩的目录路径加入到 LIBPATH 环境变量中,同时将 sapjco.jar 路径加入到 CLASSPATH 环境变量中。
开发消息流
由于实现员工请假登记的消息流要发布为 Web 服务,首先我们定义该 Web 服务的 WSDL 文件,可以在 RAD(Rational Application Developer)或者 WID (WebSphere Integration Developer)中定义 WSDL,接口定义如图 3。
定义好 WSDL 之后,就可以在 Message Broker Toolkit 中开发实现该 WSDL 的消息流了。首先新建消息流项目 MsgFlowSample 和消息集项目 MsgSetSample,在新建 MsgSetSample 消息集的步骤中,选择基于 WSDL 新建消息定义文件,导入上面创建的 WSDL 后即可生成对应的消息定义文件。
在 MsgFlowSample 项目中实现消息流,其中 HTTP Input 节点接受请求的SOAP 消息,TraceInput 将请求消息记录到文件中。如果执行失败,TryCatch 节点会将异常信息路由到 catch 终端,TraceError 记录异常信息,Throw 节点将异常消息抛出。Call SAP JCO 是一个 Java Compute 节点,我们通过在 Java 代码中使用 SAP JCO 调用 SAP RFC 并将返回结果传递到后面的 Construct Reply 节点来构造返回的 SOAP 响应消息。HTTP Reply 节点返回 SOAP 响应消息给请求者。
在消息流编辑器中,双击 Call SAP JCO 这个 Java Compute 节点就会打开实现该节点的 Java类文件,在下面的步骤中,我们将在这个 Java 类中编写 Java 代码来使用 SAP JCO 类库调用 SAP HR 提供的 RFC 函数 ZRFC_LEAVE。要调用 SAP 的 RFC 函数,首先需要定义连接 SAP 系统的相关参数,例如 IP 地址、登陆用户名和密码等等,为了较好地维护这些参数,我们在一个配置文件 SAPHRLogon.properties 中指定这些参数名值对,在消息流运行时该 Java Compute 节点会读取该配置文件获取这些参数来创建 SAP 系统的连接。清单1是在配置文件SAPHRLogon.properties 中定义的连接 SAP 的参数,例如客户机编号,主机地址、用户名和密码,具体参数可咨询 SAP 管理员。
清单 1. SAP连接配置文件
jco.client.client=300
jco.client.user=sapuser
jco.client.passwd=sappwd
jco.client.ashost=192.168.1.1
jco.client.sysnr=02
jco.client.lang=ZH
在定义完 SAP 连接配置文件后,接下来就需要在 Java 代码中读取该配置信息,使用 JCO API 获得 SAP 系统的连接实例。为了应对 SAP 系统的频繁连接,我们采用 JCO 连接池的方式来管理连接实例,从而获得较好的性能和效率。清单 2 示例了如何使用 JCO 连接池得到 SAP 连接实例的代码,JCO API 允许开发人员非常容易地传入连接参数、控制连接池大小等。
清单 2. 使用JCO API获得连接实例
private static final String SAPHR_POOL_NAME = "SAP_HR_Pool";
public static JCO.Client getSAPHRPoolConnection() throws IOException {
PoolManager clientPoolManager = JCO.getClientPoolManager();
JCO.Pool pool = clientPoolManager.getPool(SAPHR_POOL_NAME);
if (pool == null) {
Properties props = new Properties();
InputStream is = SAPConnectionPool.class.
getResourceAsStream("SAPHRLogon.properties");
props.load(is);
JCO.addClientPool(SAPHR_POOL_NAME, // pool name
10, // maximum number of connections
props); // properties
}
JCO.Client mConnection = JCO.getClient(SAPHR_POOL_NAME);
return mConnection;
}
在获得 SAP 连接的实例后,就可以通过调用 SAP 提供的 RFC 函数以实现业务逻辑,过程非常简单,根据 RFC 函数名字获得函数实例,传入请求参数调用 RFC 函数,然后从返回结果中获得响应参数,具体步骤请参考清单 3 的代码。
清单 3. 使用JCO API调用SAP RFC函数
// Get connection instance from pool
JCO.Client client = SAPConnectionPool.getSAPHRPoolConnection();
IRepository mRepository = JCO.createRepository("MYRepository", client);
// get RFC function template by RFC name
IFunctionTemplate ftemplate = mRepository.getFunctionTemplate("RFC_ZRFC_LEAVE");
// get RFC function
JCO.Function function = ftemplate.getFunction();
// set values for RFC parameters
function.getImportParameterList().setValue(serialNumber, "PERNR");
function.getImportParameterList().setValue(absentType, "AWART");
function.getImportParameterList().setValue(absentBeginTime, "BEGDA");
function.getImportParameterList().setValue(absentEndTime, "ENDDA");
// invoke RFC
client.execute(function);
// get output parameter values of RFC
String resultCode = function.getExportParameterList().getString("RTCODE");
String resultMsg = function.getExportParameterList().getString("RTMSG");
部署和测试消息流
消息流开发完毕后就可以发布为 Web 服务了,在消息流的 HTTP Input 节点属性中指定 Web 服务的端点地址是:http://localhost:9088/DWService。在部署消息流之前,需要将 Message Broker 的 HTTP 侦听端口改为 9088,命令如下:
mqsichangebroker MB_BROKER1 -P 9088
将上面开发的工程导成 BAR 包 DWSample.bar 并部署在代理 MB_BROKER1 上,命令如下所示,参数根据实际加以调整。
mqsideploy -i localhost -p 1419 -q MB_CFGMGR_QM -b MB_BROKER1 -e default -a C:\DWSample.bar -m
部署完成后开始测试,在 RAD 中选择接口的 WSDL 文件使用 RAD 提供的 Test With Web Service Explorer 功能测试部署的消息流,输入请求参数调用消息流实现的 Web 服务,测试完成后查看返回结果是否和预期一致,如图 5 所示,也可以查看日志文件或者登陆到 SAP 系统查看 RFC 函数是否被正确地调用。
图 5. 测试消息流实现的Web服务