续上篇介绍了第一个ESB应用,本文介绍第二个ESB应用——Hello World Action。
说明:本文及后续文章虽非百分百的原创,但毕竟包含本人的努力和付出,所以希望大家转载时务请注明出处:http://yarafa.iteye.com,谢谢合作。
1 概述
该实例主要是用来演示在一个配置文件中配置多个action的调用,下面将要演示的是在一个action类中定义多个调用方法,当然也可以这些调用方法放在不同的类中。
通常,对于一个service而言,需要同时定义两个listener,其中一个是做为Gateway,只负责从外界获取JMS消息,然后转成ESB内部所需要的Message。而另一个listener是ESB Message在services内部之间通讯的通道。所以对于每个service来说,一定要至少定义一个listener来作为内部Message传输用,否则,需要将service的invmScope属性设置为GLOBAL。
在下面的例子中,需要定义三个消息队列,一个接收来自客户端的消息,第二个用作ESB内部Message通道,第三个接收来自ESB的反馈消息,客户端可从该消息队列中获取ESB的反馈消息。
2 新建ESB工程
操作过程略。
3 ESB配置
3.1 创建消息队列
如概述中所描述,这里将创建三个消息队列。在esbcontent文件夹下创建文件jbm-queue-service.xml用于配置消息队列,内容如下:
<?xml version="1.0" encoding="UTF-8"?> <server> <mbean code="org.jboss.jms.server.destination.QueueService" name="jboss.esb.helloworld.destination:service=Queue,name=helloworldRequest" xmbean-dd="xmdesc/Queue-xmbean.xml"> <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer </depends> <depends>jboss.messaging:service=PostOffice</depends> </mbean> <mbean code="org.jboss.jms.server.destination.QueueService" name="jboss.esb.helloworld.destination:service=Queue,name=helloworldEsb" xmbean-dd="xmdesc/Queue-xmbean.xml"> <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer </depends> <depends>jboss.messaging:service=PostOffice</depends> </mbean> <mbean code="org.jboss.jms.server.destination.QueueService" name="jboss.esb.helloworld.destination:service=Queue,name=helloworldResponse" xmbean-dd="xmdesc/Queue-xmbean.xml"> <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer </depends> <depends>jboss.messaging:service=PostOffice</depends> </mbean> </server>
3.2 定义Provider
这里将定义一个JMS Provider,同时定义两个消息通道,一个用于监听客户端发来的消息,另一个用作ESB消息通道。内容如下:
<jms-provider connection-factory="ConnectionFactory" name="JBossMQ"> <jms-bus busid="helloworldGwChanel"> <jms-message-filter dest-name="queue/helloworldRequest" dest-type="QUEUE" /> </jms-bus> <jms-bus busid="helloworldEsbChanel"> <jms-message-filter dest-name="queue/helloworldEsb" dest-type="QUEUE" /> </jms-bus> </jms-provider>
3.3 定义Service
<service category="HelloWorld" description="Hello World" name="HelloWorldService"> <listeners /> <actions / </service>
3.4 定义Listener
这里定义两个listener,分别用于监听客户端消息和ESB内部消息。其中,前者用于监听客户端消息,因此需要将其is-gateway属性设置为true。
<jms-listener busidref="helloworldGwChanel" is-gateway="true" name="helloworldJMSListener" /> <jms-listener busidref="helloworldEsbChanel" name="helloworldEsbListener" />
3.5 定义Action类
这里仍然使用自定义的action类,因此需要扩展AbstractActionLifecycle类。类的全部代码如下:
/***********************************************************************
* <p>Project Name: helloworldaction</p>
* <p>File Name: com.thu.afa.esb.jbossesb.action.HelloWorldAction.java</p>
* <p>Copyright: Copyright (c) 2010</p>
* <p>Company: <a href="http://afa.thu.com">http://afa.thu.com</a></p>
***********************************************************************/
package com.thu.afa.esb.jbossesb.action;
import org.jboss.soa.esb.actions.AbstractActionLifecycle;
import org.jboss.soa.esb.helpers.ConfigTree;
import org.jboss.soa.esb.message.Body;
import org.jboss.soa.esb.message.Message;
/**
* <p>Class Name: HelloWorldAction</p>
* <p>Description: </p>
* @author Afa
* @date 2010-9-7
* @version 1.0
*/
public class HelloWorldAction extends AbstractActionLifecycle
{
protected ConfigTree configTree;
public HelloWorldAction(ConfigTree configTree)
{
this.configTree = configTree;
}
public Message noOperation(Message message) throws Exception
{
return message;
}
public Message printMessage(Message message) throws Exception
{
System.out.println("Message Body: " + message.getBody().get().toString());
return message;
}
public Message playWithMessage(Message message) throws Exception
{
Body body = message.getBody();
String content = body.get().toString();
StringBuffer buffer = new StringBuffer();
buffer.append("Before------------------");
buffer.append(content);
buffer.append("After-------------------");
body.add(buffer.toString());
return message;
}
public void exceptionHandler(Message message, Throwable exception)
{
System.out.println("!ERROR!");
System.out.println(exception.getMessage());
System.out.println("For Message: ");
System.out.println(message.getBody().get());
}
}
类方法说明:printMessage方法用于在控制台打印输出消息的内容,playWithMessage方法用于处理消息,而exceptionHandler则是异常处理方法。
3.6 配置Action
由于使用了自定义的action类,因此在说明action配置之前介绍了action类的定义。下面将说明action的配置。
<actions mep="OneWay"> <action lass="com.thu.afa.esb.jbossesb.action.HelloWorldAction" name="printAction" process="printMessage"> <property name="exceptionMethod" value="exceptionHandler" /> </action> <action lass="com.thu.afa.esb.jbossesb.action.HelloWorldAction" name="playAction" process="playWithMessage"> <property name="exceptionMethod" value="exceptionHandler" /> </action> <action class="org.jboss.soa.esb.actions.Notifier" name="notificationAction"> <property name="okMethod" value="notifyOK" /> <property name="notification-details"> <NotificationList type="OK"> <target class="NotifyConsole" /> <target class="NotifyQueues"> <messageProp name="helloworld" value="Queue Notification" /> <queue jndiName="queue/helloworldResponse" /> </target> </NotificationList> </property> </action> </actions>
配置说明:这里定义了三个action,当有消息到来时,所有的action将会顺序执行。即当接收到客户端消息时,将首先执行printAction,该action将会调用HelloWorldAction类的printMessage方法打印消息内容。之后执行第二个action,即playAction,该action将会调用HelloWorldAction类的playWithMessage方法用于处理printAction传递过来的消息(ESB内部消息)。之后执行第三个action,即notificationAction,这是一个由JBoss ESB所提供的处理类,从类名可看出该类用于像指定的位置发出通知,这里的通知位置有两个,一个是控制台,由<target class="NotifyConsole" />指定,另一个是消息队列:queue/helloworldResponse,即被第二个action处理后的消息将会被发送到该消息队列,客户端或者其他的应用系统可在此读取消息。
3.7 配置部署文件
部署依赖文件deployment.xml内容如下:
<jbossesb-deployment> <depends>jboss.esb.helloworld.destination:service=Queue,name=helloworldRequest </depends> <depends>jboss.esb.helloworld.destination:service=Queue,name=helloworldEsb </depends> <depends>jboss.esb.helloworld.destination:service=Queue,name=helloworldResponse </depends> </jbossesb-deployment>
3.8 部署ESB
将整个工程导出成一个ESB文件,并保存至JBoss ESB Server的部署目录下,启动JBoss ESB Server即可。
4 ESB客户端
4.1 新建Java工程
这里略去操作过程以及添加所需要的Jar包,具体操作过程可参考第一个ESB实例说明。
4.2 发送消息的客户端
package com.thu.afa.esb.jbossesb.client;
import java.util.Properties;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.naming.Context;
import javax.naming.InitialContext;
public class Main {
private QueueConnection connection;
private QueueSession session;
private Queue queue;
public void setupConnection() throws Exception {
……
}
public void stop() throws Exception {
……
}
public void sendMessage(String text) throws Exception {
……
}
public static void main(String[] args) throws Exception
{
Main main = new Main();
main.setupConnection();
main.sendMessage("Llu, miss you, afa");
main.stop();
}
}
其中,省略部门代码如下:
public void setupConnection() throws Exception
{
System.out.println("Connection Starting...");
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
properties.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
properties.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");
InitialContext context = new InitialContext(properties);
QueueConnectionFactory factory = (QueueConnectionFactory) context.lookup("ConnectionFactory");
connection = factory.createQueueConnection();
queue = (Queue) context.lookup("queue/helloworldRequest");
session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
connection.start();
System.out.println("Connection Started");
}
public void stop() throws Exception
{
if(connection != null) connection.stop();
if(session != null) session.close();
if(connection != null) connection.close();
}
public void sendMessage(String text) throws Exception
{
QueueSender sender = session.createSender(queue);
Message message = session.createTextMessage(text);
sender.send(message);
sender.close();
}
运行程序将会在ESB服务器的控制台看到如下图所示输出信息,其中第一行即是printAction打印输出的来自客户端的消息。第二行显示的是经过playAction处理后的消息,由notificationAction指向控制台的输出通知。
4.3 接收消息的客户端
package com.thu.afa.esb.jbossesb.client;
import java.util.Properties;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.naming.Context;
import javax.naming.InitialContext;
public class Main {
private QueueConnection connection;
private QueueSession session;
private Queue queue;
public void setupConnection() throws Exception {
……
}
public void stop() throws Exception {
……
}
public void receiveMessage() throws Exception {
……
}
public static void main(String[] args) throws Exception
{
Main main = new Main();
main.setupConnection();
client.receiveMessage();
main.stop();
}
}
其中,省略部门代码如下:
public void setupConnection() throws Exception
{
System.out.println("Connection Starting...");
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
properties.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
properties.put(Context.PROVIDER_URL, "jnp://127.0.0.1:1099");
InitialContext context = new InitialContext(properties);
QueueConnectionFactory factory = (QueueConnectionFactory) context.lookup("ConnectionFactory");
connection = factory.createQueueConnection();
queue = (Queue) context.lookup("queue/helloworldResponse");
session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
connection.start();
System.out.println("Connection Started");
}
public void stop() throws Exception
{
if(connection != null) connection.stop();
if(session != null) session.close();
if(connection != null) connection.close();
}
public void receiveMessage() throws Exception
{
QueueReceiver receiver = session.createReceiver(queue);
Message message = receiver.receive();
if(message != null)
{
if(message instanceof ObjectMessage)
{
ObjectMessage objectMessage = (ObjectMessage) message; System.out.println(objectMessage.getObject().toString());
} else if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
System.out.println(textMessage.getText());
}
}
receiver.close();
}
运行程序将会在Java控制台看到如下图所示的输出信息,该信息即是notificationAction发往queue/helloworldResponse的消息。
上述便是ESB第二个应用实例。如有问题,欢迎指正。
-----------------------------------------------------
Stay Hungry, Stay Foolish!
http://yarafa.iteye.com
Afa
Dec 21st, 2010
-----------------------------------------------------