WebSphere JCA Adapter 开发入门

来源:互联网 发布:如何做好一个淘宝客 编辑:程序博客网 时间:2024/05/16 18:38
IBM WebSphere JCA Adapter 是沟通 WebSphere Process Server 和 EIS 之间的桥梁,本文通过一个简单实例介绍了开发 WebSphere JCA Adapter 的基本步骤。

JCA (Java 2 Enterprise Edition (J2EE) Connector Architecture)是J2EE规范中重要的一环,为J2EE应用程序和其它企业信息系统(EIS)之间的交互制定了标准。IBM WebSphere Process Server(WPS)是构筑在J2EE之上的企业应用集成服务器,IBM WebSphere JCA Adapter就是配合WPS使用的,既符合JCA规范又支持WPS优秀集成特性的产品家族。目前最新的是6.0.2版,主要包括如下Adapter:

  • IBM WebSphere Adapter for JDBC
  • IBM WebSphere Adapter for Flat Files
  • IBM WebSphere Adapter for PeopleSoft Enterprise
  • IBM WebSphere Adapter for SAP Software
  • IBM WebSphere Adapter for Siebel Business Applications
  • IBM WebSphere Adapter for Email
  • IBM WebSphere Adapter for FTP
  • IBM WebSphere Adapter for JD Edwards EnterpriseOne
  • IBM WebSphere Adapter for Oracle E-Business Suite

IBM WebSphere JCA Adapter 架构

所需知识背景

本文假定读者熟悉J2EE,并对JCA规范有所了解。如果不熟悉JCA,最好先读一下JCA 1.5规范的以下章节:概述,包括1,2,3章;Outbound 相关,包括6,15章。

WebSphere Adapter使用Service Data Object(SDO)规范来表示数据,如果读者有SDO相关知识,将有助于理解相关内容。

IBM WebSphere JCA Adapter完全符合JCA 1.5规范。JCA Adapter规范规定了连接和操作EIS的协议,但是对所交换的数据规范没有指定。在WPS中,核心的数据规范是Business Object,简称BO。BO从技术实现的角度讲是Service Data Object(SDO),一种标准化的数据接口。WebSphere JCA Adapter使用SDO与WPS来交换数据。

连接不同的EIS的Adapters有很多共性,对每个Adapter都完全从实现JCA接口开始白手起家显然是没有必要的。因此,IBM开发了Adapter Foundation Classes作为WebSphere JCA Adapter的开发框架。它提供了JCA 接口的抽象实现,以及在Adapter之间可以重用的基本功能,并提供了Assured Event Delivery等QoS服务,而将与EIS密切相关的功能留给具体的Adapter来实现,从而大大简化了Adapter的开发工作。

下图表明WebSphere Adapter的基本架构:


图 1. Adapter的基本架构
Adapter的基本架构

从上图可以看出,Adapter Foundation Classes提供了JCA 1.5规范的框架实现,Adapter特有部分扩展并细化这一框架,实现对EIS的操作,并通过SDO规范与WPS交换数据。有了Adapter Foundation Classes,开发Adapter的工作量大为减少,只要实现上图中的蓝色部分,开发主要关注点为对不同EIS的操作。

古人云:绝知此事要躬行,以下本文将以一个连接虚拟的EIS(Mock EIS)的MockAdapter为例简要描述了如何基于WebSphere Adapter Foundation Classes 6.0.2 版,一步步开始开发符合WebSphere 框架的JCA Adapter。以此来更好的了解Adapter的工作原理。MockAdapter将只支持由J2EE应用程序发起的对EIS的操作(在JCA规范中称为Outbound操作)。

开发工具和Adapter Foundation Classes库文件

和WPS配套的开发工具是WebSphere Integration Developer(WID),它是基于Eclipse技术的企业应用集成开发环境。我们需要使用WID这个工具来开发WebSphere JCA Adapter。在WID 6.0.2的安装目录下,可以找到Resource Adapters目录,其中包括了所有可用的JCA Adapter。将某个Adapter,如FlatFile的RAR文件导入WID中,你会在connectModule目录下发现CWYBS_AdapterFoundation.jar,这就是Adapter Foundation Classes。





回页首

Mock EIS

为了简化,本文不使用任何现实的EIS,而是用一个Mock EIS 类来模拟一个EIS,这样的好处是你无需了解任何EIS API的调用,通常那是很复杂的。Mock EIS是一个二元计算服务,可以计算加减乘除。

使用Mock EIS的程序,首先要用setOperation()设置运算符,然后调用calculate()计算得出结果。


代码清单 1.MockEIS.java
                package com.ibm.eis.mock; public class MockEIS {  String operation = "+";      public MockEIS(){         }  /**   * @param operation The operation to set.   */  public void setOperation(String operation) {    this.operation = operation;  }    /**   * Calculate the result.   * @param x   * @param y   * @return   */  public float calculate(float x, float y){    float result = Float.NaN;    if(operation.equals("+")){      result = x + y;    }else if(operation.equals("-")){      result = x - y;    }else if(operation.equals("*")){      result = x * y;    }else if(operation.equals("/")){      result = x / y;    }    return result;  }}      





回页首

先期准备:创建Business Object定义

由于SDO是一种需要预先定义数据格式的规范,并且使用XML Schema文件来描述数据格式,在WPS/WID中称为Business Object 定义。我们首先要确定EIS所需要处理的数据格式,并将它映射到一个适当的Business Object 定义。在Mock EIS中需要处理的数据包括运算数和结果,可以作为属性封装在一个BO中。

我们是用WID的BO编辑器来创建BO。首先创建一个新Business Object,命名为MockBO,为它添加X,Y,Result三个属性,然后为它生成一个Business Graph(BG),BG是SDO规范中规定的BO的包装器,用来纪录BO的变化和某些附加信息,可以看作是一种特殊的BO。在WebSphere Adapter中,接受和发送的数据对象都是以BG包装的BO。

创建完成的BO如下图所示:


图 2. MockBO 定义
MockBO 定义

BO的定义会保存为XML Schema文件,切换到资源透视图,可以在模块工程目录下找到MockBO.xsd和MockBOBG.xsd两个文件。





回页首

第一步:创建Connector Project

在WID中切换到J2EE perspective,创建一个Connector Project。注意要选择WebSphere Process Server 6.0作为该Project的server,然后,把Foundation Classes的Jar文件CWYBS_AdatperFoundation.jar导入到该project的connectorModule 目录下,并添加到build path中。接下来,将刚才创建的BO定义文件,即MockBO.xsd和MockBOBG.xsd复制到connectorModule,以便将来BO定义随Adapter一同部署。





回页首

第二步:创建Resource Adapter主类

用文本方式打开ra.xml文件,目前只有对MockAdapter的简单描述,将各项描述添全。

      <display-name>IBM Mock Adapter for QA</display-name>      <vendor-name>IBM CSDL AIA</vendor-name>      <eis-type>Mock EIS</eis-type>      <resourceadapter-version>1.0.0</resourceadapter-version>

接着创建Mock Adapter的ResourceAdapter类,类名为com.ibm.j2ca.mock.MockAdapter,将此添加到ra.xml中。

       <resourceadapter>          <resourceadapter-class>com.ibm.j2ca.mock.MockAdapter</resourceadapter-class>          ......       </resourceadapter>

通过继承WBIResourceAdapter类创建MockAdapter类。WBIResourceAdapter类在com.ibm.j2ca.base包中(大部分Adapter需要继承的基类都在这个包中,如不特别指出,以下文中提到的需要继承的类都属于这个包)。唯一必须实现的方法是getResourceAdapterMetadata,返回描述该Adapter的WBIResourceAdapterMetadata实例。注意,该类需要符合Java Bean规范,即必须有public无参数的缺省构造函数。


代码清单 2.MockAdapter.java
                package com.ibm.j2ca.mock;import javax.resource.ResourceException;import com.ibm.j2ca.base.WBIResourceAdapter;import com.ibm.j2ca.base.WBIResourceAdapterMetadata;public class MockAdapter extends WBIResourceAdapter {  public MockAdapter()     super();  }  public WBIResourceAdapterMetadata getResourceAdapterMetadata()      throws ResourceException {    return new WBIResourceAdapterMetadata(            "IBM Mock Adapter", "IBM CSDL ", "1.0.0", false);  }}





回页首

第三步:实现对EIS的连接管理逻辑

WebSphere Adapter要连接EIS,必须实现JCA规范中的Connection管理逻辑。包括四个主要接口:Connection,ManagedConnection,ManagedConnectionFactory,ConnectionFactory

首先要确定的是连接特定的EIS需要的属性值,必需的属性要加在实现ManagedConnectionFactory接口的类里,如hostname,port,username,password之类。Mock EIS唯一需要设置的就是操作符Operation。因此Mock Adapter只需要一个ManagedConnectionFactory属性:Operation

各个接口的实现类以及ManagedConnectionFactory的属性需要在ra.xml里加以描述。在ra.xml <resourceadapter>标签下加上如下信息,来描述Adapter的outbound功能,指明各个接口的实现类名。

<outbound-resourceadapter>    <connection-definition>        <managedconnectionfactory-class>             com.ibm.j2ca.mock.MockManagedConnectionFactory        </managedconnectionfactory-class>        <config-property>            <config-property-name>Operation</config-property-name>            <config-property-type>java.lang.String</config-property-type>            <config-property-value></config-property-value>        </config-property>        <connectionfactory-interface>            javax.resource.cci.ConnectionFactory        </connectionfactory-interface>        <connectionfactory-impl-class>            com.ibm.j2ca.mock.MockConnectionFactory        </connectionfactory-impl-class>        <connection-interface>javax.resource.cci.Connection</connection-interface>        <connection-impl-class>com.ibm.j2ca.mock.MockConnection</connection-impl-class>    </connection-definition>    <transaction-support>NoTransaction</transaction-support>    <reauthentication-support>false</reauthentication-support></outbound-resourceadapter>

接着分别实现这四个接口:

Connection:Foudation Classes提供了Connection接口的抽象实现WBIConnection,MockConnection继承并该类。唯一必须实现的方法是createInteraction,提供outbound操作需要的Interaction接口的实现MockInteraction(将在下一步中描述)。


代码清单 3.MockConnection.java
                package com.ibm.j2ca.mock; import javax.resource.ResourceException;import javax.resource.cci.Interaction;import com.ibm.j2ca.base.WBIConnection;import com.ibm.j2ca.base.WBIManagedConnection;public class MockConnection extends WBIConnection {  public MockConnection(WBIManagedConnection mc) throws ResourceException {    super(mc);  }  public Interaction createInteraction() throws ResourceException {    return new MockInteraction(this);  }}

ManagedConnection:对EIS真正的连接通过实现ManagedConnection接口完成。Foundation Classe提供了抽象实现WBIManagedConnection。Mock Adapter要继承WBIManagedConnection并完成对EIS连接的操作,如创建和关闭连接。MockManagedConnection所要做的是创建一个MockEIS对象来代表一个连接。需要实现的方法有:

  • getMetaData方法返回关于EIS的一些信息。
  • getWBIConnection方法,进行认证并返回一个对应的JCA Connection对象,这里将是MockConnection。
  • destory方法,释放对EIS的连接。
  • getMockEIS方法,使得Adapter其他部分可以访问EIS。

代码清单 4.MockManagedConnection.java
                package com.ibm.j2ca.mock;import javax.resource.ResourceException;import javax.resource.spi.ManagedConnectionMetaData;import javax.resource.spi.security.PasswordCredential;import javax.security.auth.Subject;import com.ibm.eis.mock.MockEIS;import com.ibm.j2ca.base.WBIConnectionRequestInfo;import com.ibm.j2ca.base.WBIManagedConnection;import com.ibm.j2ca.base.WBIManagedConnectionFactory;import com.ibm.j2ca.base.WBIManagedConnectionMetaData;/** * @author Donny * */public class MockManagedConnection extends WBIManagedConnection {    private MockEIS mockEIS ;  public MockManagedConnection(WBIManagedConnectionFactory factory,        Subject sub, WBIConnectionRequestInfo request,MockEIS eis)        throws ResourceException {    super(factory, sub, request);    mockEIS = eis;  }  public ManagedConnectionMetaData getMetaData() throws ResourceException {    return new WBIManagedConnectionMetaData("Mock EIS",          "1.0.0",10,super.getPasswordCredential().getUserName());  }  public Object getWBIConnection(PasswordCredential arg0, boolean arg1)        throws ResourceException {    return new MockConnection(this);  }  public void destroy() throws ResourceException {  }  public MockEIS getMockEIS() {    return mockEIS;  }  }

ManagedConnectionFactory:J2EE容器通过ManagedConnectionFactory来创建ManagedConnection。AFC提供了ManagedConnectionFactory的抽象实现WBIManangedConnectionFactory。MockManagedConnectionFactory只需要继承这个类,实现特定的属性,在这里就是Operation。同时要实现方法createConnectionFactory供J2EE服务器取得ConnectionFactory的实例,这里将是MockConnectionFactory对象;最重要的是要实现createManagedConnection返回MangedConnection对象。还必须实现在前面确定并在ra.xml文件里制定的属性所对应的get和set方法,这里即getOperation和setOperation。MockManagedConnectionFactory根据Operation属性值构造一个MockEIS实例,并由此实例构造出MockMangedConnection的一个实例。

MockManagedConnectionFactory实现如下,注意必须提供缺省构造函数使其满足Java Bean规范要求:


代码清单 5.MockManagedConnectionFactory.java
                 package com.ibm.j2ca.mock;import javax.resource.ResourceException;import javax.resource.spi.ConnectionManager;import javax.resource.spi.ConnectionRequestInfo;import javax.resource.spi.ManagedConnection;import javax.security.auth.Subject;import com.ibm.j2ca.base.WBIConnectionRequestInfo;import com.ibm.j2ca.base.WBIManagedConnectionFactory;public class MockManagedConnectionFactory extends WBIManagedConnectionFactory {    private String operation = "+";  public MockManagedConnectionFactory() {    super();  }  public ManagedConnection createManagedConnection(Subject sub,      ConnectionRequestInfo info) throws ResourceException {    //“连接” Mock EIS,创建对MockManagedConnection     MockEIS eis = new MockEIS();    eis.setOperation(this.operation);    return new MockManagedConnection(this, sub, (WBIConnectionRequestInfo) info,eis);  }    public Object createConnectionFactory(ConnectionManager arg0)      throws ResourceException {    return new MockConnectionFactory(arg0,this);  }  public String getOperation(){      return operation;  }  public void setOperation(String operation){    this.operation = operation;  }}

MockConnectionFactory:MockConnectionFactory需继承WBIConnectionFactory,该类已经实现了基本逻辑,子类只要实现构造函数即可。


代码清单 6.MockConnectionFactory.java
                package com.ibm.j2ca.mock;import javax.resource.spi.ConnectionManager;import com.ibm.j2ca.base.WBIConnectionFactory;import com.ibm.j2ca.base.WBIManagedConnectionFactory;public class MockConnectionFactory extends WBIConnectionFactory {  public MockConnectionFactory(ConnectionManager cm,       WBIManagedConnectionFactory factory){    super(cm, factory);  }}

到这里,连接管理的逻辑已经全部实现。





回页首

第四步:实现Interaction接口以支持outbound操作

为支持outbound操作,必须实现Interaction接口,如上一步所示,Interaction对象由MockConnection创建。Foundation Classes提供了抽象实现WBIInteraction。继承该类需要实现的唯一方法是execute,在其中根据传入的参数实现对EIS的操作。

为符合Websphere Adapter的标准,Record execute(InteractionSpec ixSpec,Record in) 函数的传入参数有相应的限制,ixSpec应当是 WBIInteractionSpec的实例,in应该是DataObjectRecord的实例。DataObjectRecord包含了一个SDO规范所定义的DataObject,即BO。

MockAdatper非常简单的实现了execute方法,分析输入的BO,取出操作数,交给MockEIS进行计算后返回一份BO副本。

如何操作BO

WPS提供了BO操作的各种服务,比如创建,复制等等。Foundation Classes将这些服务封装在com.ibm.j2ca.base.AdapterBOUtil工具类中以方便调用。


代码清单 7.MockInteraction.java
                package com.ibm.j2ca.mock;import javax.resource.ResourceException;import javax.resource.cci.InteractionSpec;import javax.resource.cci.Record;import com.ibm.eis.mock.MockEIS;import com.ibm.j2ca.base.AdapterBOUtil;import com.ibm.j2ca.base.DataObjectRecord;import com.ibm.j2ca.base.WBIConnection;import com.ibm.j2ca.base.WBIInteraction;import com.ibm.j2ca.base.WBIInteractionSpec;import commonj.sdo.DataObject;public class MockInteraction extends WBIInteraction {  public MockInteraction(WBIConnection arg0) {    super(arg0);  }  public Record execute(InteractionSpec ixSpec, Record record)      throws ResourceException {    if(!(ixSpec instanceof WBIInteractionSpec)){      throw new ResourceException("Unknown InteractionSpec type!");    }    if(!(record instanceof DataObjectRecord)){      throw new ResourceException("Invalid Record type!");    }    //1. 分析输入的BO,得到运算数    DataObject bg = ((DataObjectRecord)record).getDataObject();    DataObject mockBO = bg.getDataObject("MockBO");    float x = mockBO.getFloat("X");    float y = mockBO.getFloat("Y");    //2. 通过相应的连接,得到Mock EIS服务,并计算结果    MockManagedConnection mcon = (MockManagedConnection)(        (WBIConnection)this.getConnection()).getManagedConnection();    MockEIS eis = mcon.getMockEIS();    float result = eis.calculate(x,y);        //3. 创建输出Record    DataObject outputBG = AdapterBOUtil.copyBusinessObject(bg);    outputBG.getDataObject("MockBO").setFloat("Result",result);    DataObjectRecord outputRecord = new DataObjectRecord();    outputRecord.setDataObject(outputBG);    outputRecord.setRecordName(record.getRecordName());    return outputRecord;  }}

到这里,Adapter对Outbound的支持已经完全实现,可以部署运行了。





回页首

测试:CCI 方式调用Adapter

为了在WPS上部署运行Adapter,需要将Adapter打包。首先,用wid的export功能,将Adapter所有类文件打包成为一个jar文件,比如MockAdapter.jar,并将该文件保存在工程的connectorModule目录下,这样可以在WID的集成测试环境中成功部署。

必须要有应用程序来调用Adapter,可以是jsp,ejb等。这里我们创建一个动态Web工程,使用jsp来做测试。根据J2EE的规范,还需要创建EAR工程,将Adapter工程和Web工程都包括进去。

调用Adapter很简单,首先通过JNDI查找获取ConnectionFactory实例以创建连接;然后调用Interaction的execute方法执行操作;最后关闭连接即可。


代码清单 8.MockTest.jsp
                <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><HTML><HEAD><%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%><%@ page import="com.ibm.j2ca.base.*"%> <%@ page import="commonj.sdo.*"%> <%@ page import="javax.resource.cci.*"%><META http-equiv="Content-Type" content="text/html; charset=UTF-8"><META name="GENERATOR" content="IBM Software Development Platform"><TITLE>MockTest.jsp</TITLE></HEAD><BODY><%    try{    //Step 1: 获取连接    //  1.1: 通过JNDI查找ConnetionFactory    javax.naming.InitialContext initCx = new javax.naming.InitialContext();    String jndi = "Mock/Mock_Multi";    ConnectionFactory cxf = (ConnectionFactory) initCx.lookup(jndi);        //  1.2: 创建连接    Connection connection = null ;    connection = cxf.getConnection();    //Step 2: 执行操作    //  2.1: 创建Interaction    Interaction interaction = null;    interaction = connection.createInteraction();        //  2.2: 准备InteractionSpec    WBIInteractionSpec interactionSpec = new WBIInteractionSpec();    //  2.3: 准备BO,必须以BG为包装器    DataObject inputObject = null;    inputObject = AdapterBOUtil        .createDataObject(            "http://MockTest",            "MockBOBG");    DataObject bo = inputObject.createDataObject("MockBO");    bo.set("X", "1.01");    bo.set("Y", "3.21");    //  2.4: 准备Record    DataObjectRecord inputRecord = new DataObjectRecord();    inputRecord.setDataObject(inputObject);    //  2.5: 调用执行方法    Record outputRecord = interaction.execute(interactionSpec,        inputRecord);    //  2.6: 获取返回值并输出    DataObject outputObject = ((DataObjectRecord) outputRecord)        .getDataObject();    out.println(AdapterBOUtil.serializeDataObject(outputObject));    //Step 3: 关闭连接    connection.close();  } catch (Exception e) {    e.printStackTrace();  }%></BODY></HTML>

以上代码中,第一步引用了JNDI名字Mock/Mock_Multi,需要在ear部署后手工创建。首先启动WID的集成测试服务器,将ear工程添加到服务器上。接着通过WPS的管理控制台,找到相应的企业应用程序,为其建立J2C连接工厂,将其JNDI设为Mock/Mock_Multi,并且定制其属性opertaion为“*”(即乘法)。


图 3. 定义J2C连接工厂
定义J2C连接工厂

然后可以通过浏览器来执行index.jsp。如果完全按照如上设置,将得到以下输出:


图 4. 输出结果
输出结果




回页首

总结及展望

以上我们实现了MockAdapter的连接管理和Outbound操作功能。WebSphere JCA Adapter还有很多其它需要考虑的特性,比如事务的管理,Inbound通讯等。Foundation Classes也有很多其他功能,如Command管理框架,统一的日志功能等。这些本文都没有触及。实际可用的Adapter无疑要复杂的多,但是基本的实现步骤是大体相同的。



参考资料

学习
  • Sun的JCA官方网站可以获得JCA 1.5规范

  • IBM WebSphere Adapters 文档中心

  • 参考 SDO规范 学习更多SDO的知识


获得产品和技术
  • 参考 IBM WebSphere Adapter 产品主页

  • 参考 IBM WebSphere Integration Developer 产品主页


关于作者

 

刘冬清是中国软件实验室(CSDL BJ)的工程师,加入IBM以来一直从事Websphere Business Integration相关软件的开发和测试工作。可以通过电子邮件:liudongq@cn.ibm.com来联系他。

 
原创粉丝点击