ITPub博客

首页 > Linux操作系统 > Linux操作系统 > WID/WPS 中开发、配置 JMS 作为消息中间件的应用

WID/WPS 中开发、配置 JMS 作为消息中间件的应用

原创 Linux操作系统 作者:isoa 时间:2009-05-07 14:37:45 0 删除 编辑

WPS 的消息体系概述

WPS 支持面向服务的应用架构 (Service-Oriented Architecture,SOA) 和企业服务总线 (Enterprise Service Bus,ESB),使用统一的服务调用和业务表现模型,并遵循业界的开放标准。图 1 描述了 WPS 运行环境的基本组成。


图 1. WPS 的体系结构
WPS 的体系结构

WPS 使用服务组件架构(Service Component Architecture,SCA)作为统一的服务调用模型。SCA 是一种通用的面向业务服务的组件模型。它使现有的各种服务,包括 EJB,Web 服务,Java 代码以及业务流程执行语言(Business Process Execution Language,BPEL)等,有了统一的抽象表示,从而实现了业务逻辑和实现逻辑的分离。

SCA 运行环境中最基本的单位是 SCA 模块(SCA Module)。一个 SCA 模块由一个或多个 SCA 组件(SCA Component)构成,SCA 组件通过其接口向其客户提供服务。一般,组件之间存在着依赖关系,即一个组件可以使用其它组件提供的服务,也可以为其它组件提供服务。

SCA 支持客户以同步或者异步交互方式来调用服务接口中的方法。同步交互方式是指客户端调用方法后一直等待,直到方法返回结果。此外,SCA 支持三种异步交互方式:

1)限时响应 (Deferred Response),客户调用方法后,过一段时间后读取结果;

2)单向调用 (One-way),客户调用方法后,不等待调用结果,继续自己的动作;

3)回调方法 (Callback),客户调用方法后,继续自己的动作,当结果返回时,另一个客户线程被触发以读取结果。

SCA 使用内嵌的 Service Integration Bus (SIBus) 消息引擎来支持组件间的异步通信。SIBus 实际上是一个基于 Java Message Service (JMS) 规范的消息中间件。为了便于集成使用其他消息机制的企业应用,WPS 还包含对以下 JMS 提供者的支持,这些 JMS 提供者必须符合 JMS 规范 V1.1:

  • WebSphere MQ JMS 提供者
  • 通用 JMS 提供者 (Generic JMS Provider)
  • V5 消息传递提供者

    JMS 提供者简介

    通用 JMS 绑定应用程序需要与通用 JMS 提供者一起工作。WPS 提供了对通用 JMS 提供者的支持。通用 JMS 提供者是为使用任何第三方消息传递系统而提供的。对 WPS 来说,通用 JMS 提供者提供这样一种产品,该产品支持在 JMS 规范 V1.1 中定义的应用程序服务器工具 (ASF) 功能而不支持在 JCA 规范 V1.5 中定义的入站资源适配器。通用 JMS 产品主要有 Oracle WebLogic, Oracle Advanced Queuing (AQ), SonicMQ, TIBCO 和 webMethods。SIB 不在此列,因为它是 JCA 1.5 JMS 提供者。

    Oracle AQ 是 Oracle 公司发行的基于 Oracle 数据库的高级消息队列处理系统。本例以 Oracle AQ 作为外部消息系统,介绍 SCA 模块如何在 WPS 与 Oracle AQ 之间通过 JMS 绑定来接受和发送消息。您将在后面的介绍中看到如何在 WID/WPS 中开发、配置、部署以 Oracle AQ 为通用 JMS 提供者的应用程序。

    实现业务场景

    下面我们以一个简单的场景为例,介绍如何在 WebSphere Integration Developer(WID) 中开发使用通用 JMS 服务的应用程序。WID 是一个基于 Eclipse 的集成开发环境,它使用一系列可视化构造工具便于用户开发 SCA 组件和业务应用。

    场景描述:记录客户从网页输入的个人信息,并通过 Oracle AQ 传递给后台应用,用网页输出模拟后台应用。

    创建 SCA 模块

    打开 WID 并关闭欢迎界面,以进入 Business Integration 透视图。如果此透视图已关闭,可以通过选择 Window -> Open Perspective -> Other -> Business Integration 来重新打开它:


    图 2. Business Integration 透视图
    Business Integration 透视图

    创建 SCA 模块的步骤如下:

    1. 选择 File -> New -> Module;
    2. 输入模块名字 HelloGenJMS,点击 Next;
    3. 保留默认设置,点击 Finish。

    此时在左边的 Business Integration 窗口中会创建一个名为 HelloGenJMS 的项目。

    创建接口

    选择 HelloGenJMS-> Interfaces,右键菜单选择 New->Interface,输入接口名字 IHello,点击 Finish。这时将打开一个新接口编辑页面,目前此页面大部分为空白,因为这个接口尚未定义任何方法。接下来我们要为接口添加方法,这里的方法代表服务的实现。为了简单起见,我们将创建一个“单向的”(one-way) 方法,该方法没有返回值。

    创建方法的步骤如下:

    1. 单击 Add One Way Operation 图标,以向接口表添加一个行。
    2. 将此行中的缺省名称由 operation1 更改为 hello。
    3. 将输入参数的缺省名称由 input1 更改为 customerInfo。
    4. 单击 Type 列并选择 New,以创建一个新业务对象类型来充当输入。在 Data Type Selection 弹出菜单中单击 New。

      图 3. 定义接口
      定义接口

    5. 在随即打开的 New Business Object 对话框中,指定名称 CustomerInfo,并单击 Finish -> OK。
    6. 新 CustomerInfo 业务对象现在应出现在 Type 列中。右键单击它,并选择 Open in Business Object Editor,将打开一个新编辑器,可以在其中详细定义这个新业务对象。
    7. 重复单击 Business object 右侧的 Add an attribute to a business object,设置 first_name, last_name, email 的属性。

      图 4. 编辑业务对象
      编辑业务对象

    8. 关闭面板,并选择保存更改。
    9. 保存接口。

    创建 SCA 组件

    双击 HelloGenJMS->Assembly Diagram,在打开的 Assembly Diagram Editor 里创建如下组件:


    图 5. HelloGenJMS 组装关系图
    组装关系图

    其中 Stand-alone References 是一个独立引用,客户通过网页操作可以输入个人信息,并获得 getInput 组件提供的服务;getInput 是一个 Java 组件,它将实现接口 IHello 里的方法,完成记录客户信息,并请求后台服务的功能; GenericJMSImport 是一个导入组件,它是后台服务在 SCA 模块中的代表,它将把来自 getInput 组件的请求以及客户信息传递给后台应用。

    实现接口方法

    双击图 5 中的 getInput 组件,并选择缺省选项,系统会在文本编辑器中打开 java 类 getInputImpl,该类提供了接口中详细说明的所有方法的基本框架。在我们的简单示例中,这意味着我们仅使用 hello 方法和 getMyService,locateService_IHelloPartner 方法返回类实例。

    使用下面部分中给出的代码替换 hello 方法:


    清单 1. getInputImpl 中的 hello 方法

    public void hello(DataObject customerInfo) {
    //TODO Needs to be implemented.
    String name = customerInfo.getString("first_name")+" "+
                  customerInfo.getString("last_name");
    System.out.println("Hello, " + name);
    Service service = (Service)ServiceManager.INSTANCE.locateService("IHelloPartner");
    service.invokeAsync("hello", customerInfo);
    }
    

    配置 Generic JMS 绑定

    右键单击图 5 里的 GenericJMSImport 组件,选择 Generate Binding->Messaging Binding->Generic JMS Binding,如下图所示:


    图 6. 创建 Generic JMS 绑定
    创建 Generic JMS 绑定

    Generic JMS 导入服务的配置页面被自动打开,在此页面配置连接工厂 (connection factory),目的地 (Destination) 等 JMS 资源,选择数据绑定 (Data binding) 和函数选择器 (Function selector)。目的地用于接收请求消息;连接工厂用于连接到 JMS 提供者(在此例中为 Oracle AQ)和访问目的地;数据绑定用于 WPS 内部数据对象与 JMS 消息之间的格式转换;函数选择器将事件方法映射到接口方法。配置如下:


    图 7. 配置 JMS 资源
    配置 JMS 资源

    创建 Web 项目

    打开 J2EE 透视图,在左边的 Project Explorer 里可以看到自动创建的 HelloGenJMSWeb 项目,在这个 Web 项目下创建本例的 Web 入口。

    1. 右键单击 WebContent, NEW->JSP;
    2. 输入 JSP 名字 TestInput.jsp,此页面用于输入用户信息,并请求 SCA 组件的服务。保持默认设置,Finish;
    3. 使用下面部分的代码替换 TestInput.jsp 源代码:

      清单 2. TestInput.jsp 源代码
      <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
       pageEncoding="ISO-8859-1"
       import="com.ibm.websphere.bo.BOFactory"
       import="com.ibm.websphere.bo.BODataObject"
       import="com.ibm.websphere.sca.Service"
       import="com.ibm.websphere.sca.ServiceManager"
       import="commonj.sdo.DataObject"
      %>
      
      
      
      HelloGenJMS: Input
      
       
       
      Enter Your first name   last name  
      Email address  
      <% try{ request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); }catch(java.lang.Exception e){ e.printStackTrace(); } %> <% try{ ServiceManager sm = new ServiceManager(); Service service = (Service) sm.locateService("IHelloPartner"); BOFactory bofactory = (BOFactory)sm.locateService("com/ibm/websphere/bo/BOFactory"); String firstname = request.getParameter("firstname"); String lastname = request.getParameter("lastname"); String mail = request.getParameter("email"); if(firstname != null){ DataObject input=bofactory.create("http://HelloGenJMS","CustomerInfo"); input.setString("first_name",firstname); input.setString("last_name",lastname); input.setString("email",mail); service.invokeAsync("hello", input); out.println("request sent
      "); } }catch(Exception e){ } %>

    4. 右键单击 WebContent, NEW-> JSP;
    5. 输入 JSP 名字 TestOutput.jsp,此页面用于显示从 Oracle AQ 队列中接收的消息。保持默认设置,Finish;
    6. 使用下面部分的代码替换 TestOutput.jsp 源代码:

      清单 3. TestOutput.jsp 源代码
      
      
      
      
      <%@ page language="java" contentType="text/html; charset=UTF-8"
      pageEncoding="UTF-8"
      import="javax.jms.BytesMessage" 
      import="javax.jms.Connection" 
      import="javax.jms.ConnectionFactory" 
      import="javax.jms.Destination" 
      import="javax.jms.JMSException" 
      import="javax.jms.Message" 
      import="javax.jms.MessageConsumer" 
      import="javax.jms.Session" 
      import="javax.jms.TextMessage" 
      import="javax.naming.directory.InitialDirContext" 
      import="javax.naming.NamingException" %>
      
      
      
      HelloGenJMS: Output
      
      
      

      Output message

      <% try { InitialDirContext ctx = new InitialDirContext(); ConnectionFactory factory = (ConnectionFactory) ctx.lookup("gjms/cf"); Connection connection = factory.createConnection(); connection.start(); Destination q1 = (Destination) ctx.lookup("gjms/q01"); boolean transacted = false; Session session1 = connection.createSession(transacted, Session.AUTO_ACKNOWLEDGE); MessageConsumer receiver = session1.createConsumer(q1); Message receivedMessage = receiver.receive(5000); // Check to see if the receive call has actually returned a // message. If it hasn't, report this and throw an exception... if (receivedMessage == null) { out.println("Timed out
      "); receiver.close(); session1.close(); out.println("Operation Timed out
      "); } else if (receivedMessage instanceof TextMessage) { session1.close(); String resp = ((TextMessage) receivedMessage).getText(); System.out.println("Custom's information as bellow:"); System.out.println(resp); System.out.println("Custom BO had transformed into XML format successfully!"); out.println(resp+"
      "); } else { out.println("The message retrieved has to be TextMessage type"); } }catch(NamingException ne){ ne.printStackTrace(System.out); }catch(Exception e){ if(e instanceof JMSException){ ((JMSException) e).getLinkedException().printStackTrace(System.out); } } %>

    现在可以将 HelloGenJMS 项目导出到 .ear 文件 HelloGenJMSApp.ear 中,并从管理控制台安装该文件。

    部署业务应用

    Oracle AQ 资源配置

    注册数据库实例 oradb 到 OID (Oracle Internet Directory),指定注册用户名 DN(cn=orcladmin) 和密码。

    创建名为 ASGUEST 的全局方案 (Schemas),并且给它赋予可以创建会话的权限。步骤如下,打开 SQL plus 窗口,以 sysdba 身份登陆,执行如下命令:

    CREATE USER ASGUEST IDENTIFIED GLOBALLY AS '';

    GRANT CREATE SESSION, resource TO ASGUEST;

    注册连接工厂到 OID,这里我们使用 Oracle AQ JMS 自身提供的应用程序接口来实现,详细实现程序见清单 4,然后我们用 javac 命令对其进行编译,java 命令执行它即可。

    USER ASGUEST IDENTIFIED GLOBALLY AS '';

    GRANT CREATE SESSION, resource TO ASGUEST;


    清单 4. 注册连接工厂详细代码

    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Hashtable;
    import java.util.Properties;
    import javax.jms.*;
    import javax.naming.*;
    import javax.naming.directory.*;
    import oracle.jms.*;
    public class CreateAQ{
    public static void main(String[] args){
     createCF();
     }
     private static void createCF(){
     /*
     * register queue connection factory for database "oradb", host
    * "9.125.63.86", port 1521, driver "thin"
    */
    String url = "jdbc:oracle:thin:@9.125.63.86:1521:oradb";
    java.sql.Connection db_conn;
    // To set username and password
    Properties prop = new Properties();
    prop.put("user", "orcladmin");
    prop.put("password", "staf4pat");
     // register connection factory by using JMS API
    try {
    	Class.forName("oracle.jdbc.OracleDriver");
    	db_conn = DriverManager.getConnection(url, prop);
     System.out.println("-----connect successfully-----"+db_conn);
    	// Type: queue, Connection Factory's name: queue_cf
    	AQjmsFactory.registerConnectionFactory(db_conn, "queue_cf", url,
    	prop, "queue"); 
    	} catch (SQLException e) {
    		e.printStackTrace();
    		} catch (ClassNotFoundException e) {
    		e.printStackTrace();
    		} catch (JMSException e) {
    			e.printStackTrace();
    			}
     }
    }
    

    这样我们就在 Oracle 数据库 oradb 上成功创建了一个名为 queue_cf 的连接工厂。

    :要成功编译执行此程序,类路径中必须包含必要的 Oracle 和 JMS 的相关类。

    创建队列表,打开一个 SQL plus 窗口,以注册用户名 (orcladmin) 登陆,创建队列表,命令如下:

    connect orcladmin/;

    EXEC DBMS_AQADM.CREATE_QUEUE_TABLE(queue_table => 'Q_TextMsg_Table',queue_payload_type =>'SYS.AQ$_JMS_TEXT_MESSAGE');

    在已知队列表上创建队列并启动该队列,命令如下:

    EXEC DBMS_AQADM.CREATE_QUEUE(queue_name => 'q01', queue_table => ' Q_TextMsg_Table ');

    EXEC DBMS_AQADM.START_QUEUE(queue_name => 'q01');

    WPS 资源配置

    新建 JMS 提供程序,进入管理控制台,在导航窗格中,单击资源 -> JMS -> JMS 提供程序,在内容窗格中指定作用域为:节点 =ndtest2Node01,单击新建,详细配置如图 8。


    图 8. JMS 提供程序
    JMS 提供程序

    配置 JMS 连接工厂,进入管理控制台,在导航窗格中,单击资源 -> JMS -> 连接工厂,在内容窗格中指定作用域为:节点 =ndtest2Node01,单击新建,选择 JMS 资源提供程序,确定 Oracle AQ 提供程序被选中,单击确定,连接工厂的详细配置如图 9。


    图 9. JMS 连接工厂

    配置 JMS 队列,进入管理控制台,在导航窗格中,单击资源 -> JMS -> 队列,在内容窗格中指定作用域为:节点 =ndtest2Node01,单击新建,选择 JMS 资源提供程序,确定 Oracle AQ 提供程序被选中,单击确定,队列的详细配置信息如图 10。


    图 10. 队列配置

    应用程序部署

    进入管理控制台,在导航窗格中,单击应用程序 -〉企业应用程序,在内容窗格中,单击安装按钮。在本地浏览系统右侧单击浏览,指定将要安装目标文件 (HelloGenJMSApp.ear),打开,单击下一步,直至完成。安装完成后,单击安装页面下部的保存按钮,确保安装信息保存到主配置。保存后系统自动跳转到企业应用程序浏览页面,在这里我们可以启动 / 停止我们选中的应用,这样我们的配置与部署工作全部完成。

    测试一下刚刚部署的应用程序。打开浏览器,键入 URL:http://localhost:9080/HelloGenJMSWeb/TestInput.jsp,此时我们可得到应用程序的输入界面,根据提示键入相应值,如下图所示。


    图 11. 输入界面
    输入界面

    单击 submit 按钮,提交请求。然后我们调用 URL:http://localhost:9080/HelloGenJMSWeb/TestOutput.jsp 得到输出界面。


    图 12. 输出界面
    输出界面

    以上输出证明我们的应用运行正常,同时我们也可在 SystemOut.log 中可以看到相应输出日志,见清单 5。


    清单 5. 输出日志

    [12/31/08 3:59:23:125 CST] 0000003d SystemOut O Hello, WebSphere Process Server
    [12/31/08 3:59:37:562 CST] 00000037 SystemOut O Custom's information as bellow:
    [12/31/08 3:59:37:562 CST] 00000037 SystemOut O 
    
     WebSphere Process Server
     wps@ibm.com.cn
    
    [12/31/08 3:59:37:562 CST] 00000037 SystemOut O Custom BO had transformed into 
    XML format successfully!
    

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14780828/viewspace-594429/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-07-07

  • 博文量
    251
  • 访问量
    295000