SCA集成应用的开发

日期: 2008-03-11 作者:方伟漆池李旭王征 来源:TechTarget中国

  SCA 集成应用的开发


  下面我们通过另外一个示例来说明 SOA Feature Pack 的其他重要功能点,并且简单演示如何利用 SCA 开发企业集成应用。一个银行系统提供给客户的服务可以包括帐户管理,存取款,转账,贷款等服务。这些服务有的是已有系统中存在的,有的是需要开发新系统实现的,在 SOA 应用中往往需要对这些异构系统进行整合。运用 SCA 构架体系为这种类型的业务整合提供了强大的支持和良好的封装性,并使开发简单便利。


  示例概述


  在我们的示例中,提供四个银行账户服务:存款、查询余额、取款、转账。其中存款、查询余额以及取款由 EJB 实现的已有系统提供,转账为新开发的服务,以 Web Service 的形式体现。下面先看 EJB 提供的功能:


  清单 1 AccountEJB 的 Remote 接口


  package ejbs;


 /**
 * Remote interface for Enterprise Bean: AccountEJB
 */
 public interface AccountEJB extends javax.ejb.EJBObject {


 /**
 * @param accountId, ID of the customer’s bank account
  * @return the balance of the customer’s account
  * @throws java.rmi.RemoteException
  */
 public double getBalance(String accountId) throws  java.rmi.RemoteException;


 /**
  * @param accountId, ID of the customer’s bank account
  * @param amount, how much does the customer want to deposit
  * @throws java.rmi.RemoteException
  */
 public void deposit(String accountId, double amount)
   throws java.rmi.RemoteException;


 /**
  * @param accountId, ID of the customer’s bank account
 * @param amount, how much does the customer want to withdraw
  * @throws java.rmi.RemoteException
  */
 public void withdraw(String accountId, double amount)
   throws java.rmi.RemoteException;
}
 
  AccountEJB 提供存款、查询余额以及取款的功能,其 Remote 接口定义如清单 1 所示。getBalance 为查询余额操作,它接受银行受帐户 ID,返回帐户余额;deposit 为存款操作,它接受帐户 ID 以及存款额度;withdraw 为取款操作,它接受帐户 ID 以及取款额度。


  下面定义转账服务的 Web Service,首先为转账操作的接受的参数信息定义 XML Shcema – BankService.xsd,该 Schema 如清单 2 所示 AccountTransfer 为转账操作参数类型,它是一个 Complex Type,包含三个属性,分别为来源帐户,目的帐户,以及转账额度。有了 Schema 后接着定义转账操作的 WSDL – BankService.wsdl,如清单 3 所示(未列出 service 以及 port),该 WSDL 定义了一个名为 BankService 的 portType,包含一个操作 transfer,它接受之前定义的 AccountTransfer 作为参数,返回 boolean 以表示转账是否成功。该 WSDL 以 document-literal-wrapper 方式定义。


  清单 2 转账参数 Schema


 
 http://www.w3.org/2001/XMLSchema“
 http://demo.sca/BankService”>http://demo.sca/BankService”  elementFormDefault=”qualified”
 targetNamespace=”http://demo.sca/BankService“>


  清单 3 转账操作 WSDL


  
 http://schemas.xmlsoap.org/wsdl/“
 http://schemas.xmlsoap.org/wsdl/soap/”>http://schemas.xmlsoap.org/wsdl/soap/“
 http://demo.sca/BankService”>http://demo.sca/BankService“
 http://www.w3.org/2001/XMLSchema”>http://www.w3.org/2001/XMLSchema” name=”BankService”
 targetNamespace=”http://demo.sca/BankService“>
 
  http://demo.sca/BankService“
   http://www.w3.org/2001/XMLSchema”>http://www.w3.org/2001/XMLSchema“>
   
        
              type=”tns:AccountTransfer” />
     

    

  至此,我们已经有了一个 EJB 提供的服务以及一个 Web Service 提供的服务,下面描述如何建立一个 SCA 应用来集成它们。


  Java 生成


  注意到在生成 Web Service 的时候,定义了一个 XSD 的 Complex Type:AccountTransfer 作为 Web Service 操作的参数,在 SCA 实现的时候,需要以 Java 的方式创建并且使用这个类型,因此需要一个由 XSD 到 Java 的转换。如文章上半部分中所述,这个功能是由 SOA Feature Pack 的 XSD2Java 工具提供的。此外在创建 SCA 实现的时候,也需要有一个 Java 接口来表示 WSDL 里定义的 portType,因此需要一个 WSDL 到 Java 的转换,这个功能由 WSDL2Java 工具提供。下面演示怎样在 RSA 中使用这两个工具:


  ·在 Project Explorer 视图中右击 BankService.xsd,选择 Run As -> Run…,弹出运行配置对话框。
  ·在左侧的运行类型树中,右击“Java Application”,选择 New,进入编辑 Java 运行启动项的配置界面。
  ·在“Main”的配置页中(如图 1 所示),在 Main class 中搜索出 org.apache.tuscany.sdo.generate.XSD2JavaGenerator 类,该类是 XSD2Java 工具的入口。注意必须勾选“Include libraries when searching for a main class”的选项。(在工程建立时必须配好 SOA Feature Pack 的 classpath)。


  图 1 XSD2Java 启动项配置




 
  在 Arguments 配置页中,“Program arguments”处填入 XSD2Java 工具的运行参数,如图 2 所示。其中 -targetDirectory 表示生成的 Java 类放在哪个源目录中,${resource_loc} 是 XSD 文件的位置,这里取右击时的目标文件位置。


  图 2 XSD2Java 启动项配置




 
  配置好启动项后,点击“Run”,则会在 src/main/java 目录中生成 Java 类,其中包含:
  
  ·AccountTransfer 接口,它是 JavaBean 形式的 SDO 接口,用来表示 BankService.xsd 中定义的类型。
  ·ServiceFactory 工厂类接口,它是 BankService.xsd 中定义的所有复杂类型的 SDO 创建工厂,其命名由 XSD 中的 namespace 决定。
  ·AccountTransfer 以及 ServiceFactory 的实现类。


  至此,对 BankService.xsd 的 Java 生成工作已经完成。


  对 BankService.wsdl 也需要运行 XSD2Java 工具,因为在对 BankService 采用的是 document-literal-wrapper 方式的定义,其 wsdl 中包含内嵌的 XSD 类型 transfer 以及 transferResponse,需要将它们生成 Java 类。运行参数与处理 BankService.xsd 时类似。
  对 BankService.wsdl 进行 WSDL2Java 的操作以生成 SCA 组件中所需的接口。操作的流程与运行 XSD2Java 类似,不过在“Main”的配置页中,“Main class”处应搜索 org.apache.tuscany.tools.wsdl2java.generate.WSDL2JavaGenerator 类。清单 4 列出了生成出的 Java 接口。


  清单 4 BankService.wsdl 生成的 Java 接口


 /**
 * BankService.java
 *
 * This file was auto-generated from WSDL
 * by the SOA Feature Pack WSDL to Java tool
 */


 package sca.demo.bankservice;


 import org.osoa.sca.annotations.Remotable;


 /*
 * BankService java interface
 */


@Remotable
public interface BankService {


 /**
  * Auto generated method signatures
  */


 public boolean transfer(sca.demo.bank.service.AccountTransfer transfer);


}
 
  至此,Java 生成的工作已经完成,下面可以利用生成的 Java 类进行 SCA 组件的开发。


  SCA 组件接口与实现


  首先为需要建立的 SCA Component 定义接口,该接口集成了 AccountEJB 的功能以及 BankService 服务的功能,清单 5 为该接口的代码,注意需要使用 @Remotable 将接口声明成远程 SCA 接口。


  清单 5 SCA 组件接口


 package sca.demo.banksca;


 @Remotable
 public interface BankClient {
 public double getBalance(String accountId);


 public void deposit(String accountId, double amount);


 public void withdraw(String accountId, double amount);


 public boolean transfer(sca.demo.bank.service.AccountTransfer transfer);
}
 
  接着为此接口创建实现类,该实现类即我们所需要创建的 SCA Component 的实现,实现类的代码如清单 6 所示,此实现类中有以下需要注意的地方:


  ·需要将 AccountEJB 的 Remote 接口导入到此 SCA 应用中,并且在实现类中建立此接口的 Reference
  ·需要为 WSDL2Java 工具生成的接口 BankService 创建 Reference。


  在实现 SCA 组件的业务功能时,分别调用 EJB 接口和 WSDL 接口的相应方法实现,并且进行一定的异常处理。


  清单 6 SCA 组件实现


  package sca.demo.banksca;


 import java.rmi.RemoteException;


 import org.osoa.sca.annotations.Reference;
 import org.osoa.sca.annotations.Service;


 import sca.demo.bank.service.AccountTransfer;
 import sca.demo.bankservice.BankService;
 import ejbs.AccountEJB;
 
 @Service(BankClient.class)
 public class BankClientImpl implements BankClient {


 public AccountEJB ejbReference;


 public BankService wsReference;


 public AccountEJB getEjbReference() {
  return ejbReference;
 }


 @Reference
 public void setEjbReference(AccountEJB ejbReference) {
  this.ejbReference = ejbReference;
 }


 public BankService getWsReference() {
  return wsReference;
 }


 @Reference
 public void setWsReference(BankService wsReference) {
  this.wsReference = wsReference;
 }


 public void deposit(String accountId, double amount) {
  try {
   ejbReference.deposit(accountId, amount);
  } catch (RemoteException e) {
   e.printStackTrace();
  }
 }


 public double getBalance(String accountId) {
  try {
   return ejbReference.getBalance(accountId);
  } catch (RemoteException e) {
   e.printStackTrace();
   return 0;
  }
 }


 public boolean transfer(AccountTransfer transfer) {
  return wsReference.transfer(transfer);
 }


 public void withdraw(String accountId, double amount) {
  try {
   ejbReference.withdraw(accountId, amount);
  } catch (RemoteException e) {
   e.printStackTrace();
  }
 }
}
 
  SCA 组件部署


  清单 7 给出了我们所需要创建的 SCA 组件的 Composite 定义,其中,我们创建了名为 BankDemoComponent 的 SCA component,并且使用了“SCA 组件接口与实现”节中给出的 Java 实现作为其 implementation,为 BankDemoComponent 创建了两个 Reference:采用 EJB Binding 的 ejbReference 以及采用 Web Service Binding 的 wsReference。其中有以下几点需要注意的地方:


  由于在 SCA 组件中定义了 SDO,并且以 JavaBean 的形式使用,因此在 Composite 定义中需要声明 SDO 的工厂类。import.sdo 元素即为此声明的方式,它的名称空间为    
       uri=”corbaname:iiop:localhost:2809/NameServiceServerRoot#ejb/ejbs/AccountEJBHome” />
  
  
       interface=”sca.demo.bankservice.BankService” />
       wsdlElement=”
http://demo.sca/BankService#wsdl.port(BankService/BankServiceSOAP)” />
  
 
 
  最后我们为建立的 SCA 组件创建演示界面,清单 8 给出了演示界面中,调用 SCA 组件的代码,其中创建 SCA component 的过程与第 3 章中的示例类似。从此代码中可以看出 SCA 组件的使用方式,为非常简单的 Java 调用,SCA 运行环境会自动将 Java 调用转换成具体的 EJB 客户端调用或者 Web Service 客户端调用,从这里可以看到 SCA 架构良好的封装性。


  清单 8 演示界面部分代码


  CompositeContext compositeContext =  CurrentCompositeContext.getContext();
 BankClient bankClient = (BankClient) compositeContext.locateService (BankClient.class,
   “BankDemoComponent”);


 //deposit operation
 bankClient.deposit(accountId, amount);


 //getBalance operation
 double balance = bankClient.getBalance(accountId);


 //withdraw operation
 bankClient.withdraw(accountId, amount);


 //transfer operation
 AccountTransfer accountTransfer =  ServiceFactory.INSTANCE.createAccountTransfer();
 accountTransfer.setFromAccount(fromAccount);
 accountTransfer.setToAccount(toAccount);
 accountTransfer.setAmount(amount);
 bankClient.transfer(accountTransfer);
 
  将创建出的描述文件以及源文件按照图 3 的目录结构打成 war 包,然后按照文章上半部分中所描述的方法进行部署,在浏览器中输入示例 JSP 页面的地址,就可以看到如图 4 的运行结果。


  图 3 SCA 组件部署目录结构




 
  图 4 运行结果




 
  示例总结


  通过上面了示例演示了用 SOA Feature Pack 进行 SCA 集成应用开发的流程和方法,包括使用 XSD2Java 以及 WSDL2Java 生成 Java 类代码,EJB Binding 和 Web Service Binding 的声明和实现方式,以及 SCA 组件的开发和部署。


  总结


  SCA 规范是一种新的应用架构和编程模型,在 SOA 开发中具有强大的优势和生命力,对 SOA 的发展有着重要的意义。SOA Feature Pack 为在 WAS 上开发 SCA 应用提供了运行平台和工具。本文首先介绍了 SCA 的基本概念,接着描述了 SOA Feature Pack 的概况和新功能,然后通过两个具体的示例展示了如何使用 SOA Feature Pack 进行 SCA 开发。内容包括 Asset 的创建,Business Level Application 的创建,SCA 回调方式组件的开发,Web Service Binding 和 EJB Binding 的开发,以及 SCA 组件的部署,管理等。读者通过本文可以对 SCA 有较为具体的认识,同时对在 WAS 上进行 SCA 开发有较为形象的概念。

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

相关推荐