您的位置:首页 > 其它

SCA 之Tuscany 9 ——helloworld JMS binding

2011-10-14 11:57 453 查看
使用SCA一个非常重要的理由就是可以自由的使用异步的框架。

关于这个技术详细的内容可见:http://tuscany.apache.org/sca-java-bindingjms.html

一个好的架构都是将复杂的逻辑多使用异步进行通信。而JMS是成熟的、被多家厂商支持的企业级异步通信API。在Tuscany中binding JMS可谓是轻车熟路。

我们可以在标签 <reference><service> 中使用 <binding.jms>
引用/发布 服务。

<binding.jms uri="jms:RequestQueue"/>

由以上,我们得到一个目的地是RequestQueue 的jms queue。其他配置为默认。

默认情况Tuscany将使用connection factory :'ConnectionFactory',可以被如下更改:

<binding.jms uri="jms:RequestQueue?connectionFactoryName=myCF"/>

如果是没有添加queue或topic的name,那么引用的目的地可以被临时创建。

而在service中,可以做到最大简化如下,此时绑定的queue或topic被默认看成和service名字一样:

<service name="MyService">
<binding.jms />
</service>

下面看一个例子:

POM中的依赖

<dependencies>

<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-base-runtime</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-binding-jms-runtime</artifactId>
<version>2.0-SNAPSHOT</version>
</dependency>

<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.3.0</version>
<scope>runtime</scope>
</dependency>

</dependencies>

<build>
<finalName>helloworld-jms</finalName>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.26</version>
<configuration>
<contextPath>helloworld-jms</contextPath>
<stopKey>foo</stopKey>
<stopPort>9999</stopPort>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>process-test-classes</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>8085</port>
</connector>
</connectors>
</configuration>
</execution>
<execution>
<id>stop-jetty</id>
<phase>prepare-package</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>


这里使用了嵌入式的activemq作为JMS Broker.

Jetty运行时将会加载一个xml文件,我们在这个文件中定义内嵌ActiveMQ的配置文件:

<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">

<Configure class="org.mortbay.jetty.webapp.WebAppContext">

<New id="cf" class="org.mortbay.jetty.plus.naming.Resource">
<Arg>ConnectionFactory</Arg>
<Arg>
<New class="org.apache.activemq.ActiveMQConnectionFactory">
<Arg>vm://localhost?broker.persistent=false</Arg>
</New>
</Arg>
</New>

<New id="myQueue"  class="org.mortbay.jetty.plus.naming.Resource">
<Arg>HelloWorldService</Arg>
<Arg>
<New class="org.apache.activemq.command.ActiveMQQueue">
<Arg>JMSDEMO</Arg>
</New>
</Arg>
</New>

</Configure>


web.xml

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web
Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>

<display-name>Apache Tuscany JMS Web Service Sample</display-name>

<filter>
<filter-name>tuscany</filter-name>
<filter-class>org.apache.tuscany.sca.host.webapp.TuscanyServletFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>tuscany</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<welcome-file-list id="WelcomeFileList">
<welcome-file>hello.jsp</welcome-file>
</welcome-file-list>

<!-- Uncomment this to use an appserver thread pool
<resource-ref>
<res-ref-name>wm/TuscanyWorkManager</res-ref-name>
<res-type>commonj.work.WorkManager</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
-->

<!-- Uncomment these to use local jndi name aliases
<resource-ref>
<res-ref-name>ConnectionFactory</res-ref-name>
<res-type>javax.jms.ConnectionFactory</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>

<resource-ref>
<res-ref-name>HelloWorldService</res-ref-name>
<res-type>javax.jms.Queue</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
-->

</web-app>


注意那些注释的行可以定义使用其他MQ的配置:

Configuring the JMS resources
-----------------------------

The sample requires JMS resources be manually configured in the server environment, these are:

- a JMS connection factory named "ConnectionFactory"
- a JMS queue named "HelloWorldService"

See the following for how to define these resources depending on the application server being used:

Tuscany with embedded ActiveMQ broker
-------------------------------------

Apache Tomcat
-------------

No configuration is necessary for Tomcat as the sample WAR includes everything pre-configured to run
an ActiveMQ embedded JMS broker and to configure the JMS resources in JNDI.

The JNDI resources are configured in the META-INF/comtext.xml file, for more information on running
ActiveMQ in Tomcat see: http://activemq.apache.org/tomcat.html 
Apache Geronimo
---------------

For Apache Geronimo 2.0.1 (2.0.2 fails to define JMS resources for me)

Logon to the Geronimo Server Console (http://localhost:8080/console, uid system, pswd manager)

In the Console Navigation on the left under Services click JMS Resources

At the bottom of the JMS Resources panel click under Create a new JMS Resource Group click For ActiveMQ

In Resource Group Name enter "MyRGN" and click next

At JMS Resource Group click Add Connection Factory

For JMS Factory Type choose javax.jms.ConnectionFactory and click Next

In Connection Factory Name enter "ConnectionFactory" and click Next

Click Add destination

For JMS Destination Type choose javax.jms.Queue and click Next

Enter "HelloWorldService" for both Message Destination Name and PhysicalName and click Next

Click Deploy Now

Thats it, you're done.

WebSphere
---------

To define the JMS resources in a new WebSphere Application Server 6.1 installation:

1) First define a Service integration bus:

Logon to the WebSphere Integrated Solutions Console (http://localhost:9060/ibm/console)

On the Left hand menu expand Service integration, and click on Buses.

In the Buses panel click on New

Enter a name for the bus, eg MyBus, and click Next, and then click Finish and Save the changes.

In the Buses panel click on MyBus

Find the Topology secion and click on Bus members

Click on Add, leave the defaults and click Next, Next, Next, Finish, and Save the changes.

Restart WebSphere and when back up logon back on to the Integrated Solutions Console

2) Now define the JMS rescources

On the Left hand menu expand Resources, and JMS and click on Connection Facotories.

In the Connection factories panel click New.

Leave the Default messaging provider and click OK

Enter "ConnectionFactory" in the Name and JNDI name and in the Bus name in the Connection pane choose MyBus and click OK

On the Left hand menu in JMS click on Queues

In the Queues panel click New, accept the defaults and click OK

Enter "HelloWorldService" for the Name and JNDI name and in the Bus name in the Connection pane choose MyBus,
and then in the Queue name drop down list choose "Create SIB destination"

In the Set queue attributes panel enter "HelloWorldService" for the Identifier and click Next, Next, and Finish

That should take you back to the Queues panel where you can click OK to create the new JMS queue.

Save the changes

Restart WebSphere and you're done.

Others...
---------


另:使用Tomcat ActiveMQ Broker 时还需要添加的context.xml文件

<Context>

<Resource name="ConnectionFactory" auth="Container" type="org.apache.activemq.ActiveMQConnectionFactory" description="JMS Connection Factory"
factory="org.apache.activemq.jndi.JNDIReferenceFactory" brokerURL="vm://localhost?broker.persistent=true" brokerName="LocalActiveMQBroker"/>

<Resource name="HelloWorldService" auth="Container" type="org.apache.activemq.command.ActiveMQQueue" description="my Queue"
factory="org.apache.activemq.jndi.JNDIReferenceFactory" physicalName="RequestQueue"/>

</Context>


实际的组件:

<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1"
targetNamespace="http://samples"
name="Helloworld">

<component name="foo">
<implementation.web web-uri=""/>
<reference name="service" target="HelloWorldClientComponent"/>
</component>

<component name="HelloWorldClientComponent">
<implementation.java class="sample.HelloWorldClient"/>
<reference name="helloWorldRef">
<binding.jms uri="jms:queue:HelloWorldService"/>
</reference>
</component>

<component name="HelloWorldServiceComponent">
<implementation.java class="sample.HelloWorldServiceImpl" />
<service name="HelloWorldService">
<binding.jms />
</service>
</component>

</composite>


由此我们可知道这个组件内有两个构件,一个发一个读JMS的消息。

接口:

package sample;

import org.oasisopen.sca.annotation.Remotable;

/**
* The interface for the helloworld service
*/
@Remotable
public interface HelloWorldService {
public String sayHello(String name);
}


consumer:

package sample;

/**
* The HelloWorld client implementation
*/
public class HelloWorldClient implements HelloWorldService {

HelloWorldService helloWorldRef;

public String sayHello(String name) {
System.out.println("HelloWorldClient.sayHello " + name);
return helloWorldRef.sayHello(name);
}

public void setHelloWorldRef(HelloWorldService helloWorldRef) {
System.out.println("HelloWorldClient.setHelloWorldService " + helloWorldRef);
this.helloWorldRef = helloWorldRef;
}
}


provider:

package sample;

/**
* This class implements the HelloWorld service.
*/
public class HelloWorldServiceImpl implements HelloWorldService {

public String sayHello(String name) {
System.out.println("HelloWorldServiceImpl.sayHello " + name);
return "Hello " + name;
}

}


在JSP中执行:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://www.osoa.org/sca/sca_jsp.tld" prefix="sca" %>

<sca:reference name="service" type="sample.HelloWorldService" />

<html>
<head><title>HelloWorld JMS sample</title></head>

<body>

If this sample is working correctly you should see "Hello World" on the next line...
<p>
<%= service.sayHello("world") %>
<p>
If you do not see "Hello World" on the line above then there has been a problem.
<p>
The sample requires JMS resources be manually configured in the server environment, these are:
a JMS connection factory named "ConnectionFactory", and a destination queues named "HelloWorldService".
See the sample README file for more information.

</body>
</html>


验证:



关于使用外部独立的JMS broker可以如下定义:

<binding.jms initialContextFactory="org.apache.activemq.jndi.ActiveMQInitialContextFactory" jndiURL="tcp://localhost:61616">
<destination name="DestQueueA"/>
</binding.jms>


关于使用JMS选择器:

<binding.jms uri="jms:ServiceTopic" >
<SubscriptionHeaders JMSSelector="JMSType = 'type1'"/>
</binding.jms>


关于使用JMS属性:

<binding.jms uri="jms:ServiceQueue">
<headers JMSType="someTypeValue" />
<operationProperties name="op2">
<headers JMSType="op2SpecificTypeValue" />
</operationProperties>
</binding.jms>


这些就能帮助我们实现一个实际的功能了。

如果是大的环境,复杂的域,需要定义策略等,可参考文章开始提供的地址后面的内容,apache提供了完整的方案。

really very complicated !

but valuable .
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: