Understand WS-Notification Message from Apache Muse Sample
通过Apache Muse来理解WS-Notification消息
1. WS-Notification
Web Service的订阅通知机制可以使用WS-Notification相关协议。当实现基于Web Service的订阅通知时,实现相关的WS-*协议是一个最佳实践。以下WS-*协议是直接在一个订阅通知场景中被使用到:
WS-BaseN
WS-Topics
WS-BrokeredN
另外,对WS-Addressing协议理解也是必须的。
从时序图中看到,要实现Web Service的订阅通知,就需要实现协议所规范的WS-Notification的相应SOAP消息。包括 wsn:Subscribe,wsn:SubscribeResponse , wsn:Notify等。下面将会通过实例来简要展示这些消息和发送的部分细节。
2. Apache Muse
Apache Muse是一个基于Java的对WSRF(Web Service Resource Framework)的开源实现,在其中,也实现了基于Web Service的订阅通知。Apache Muse的官方Sample中的wsn-consumer和wsn-producer两个子工程比较完全的展示的WS-Notification工作时WS-Notification消息发送和处理情况。如何部署运行这个Sample不在这里详细介绍,Apache Muse的相关文档中有详细的介绍。
3. Run them …
接下来,将运行起Apache Muse的这个例子,然后通过观察log来了解基于Web Service的订阅通知过程中WS-Notification的一些细节。
3.1. Subscriber
例子中由org.apache.muse.test.wsn.WsnTestClient.java充当Subscriber的角色,通过如下Ant脚本运行
>ant run –Dmain=org.apache.muse.test.wsn.WsnTestClient |
该脚本调用main方法,发出如下的SOAP消息到WSN-producer,该消息为WS-N协议中的中的Subscribe消息
[CLIENT TRACE] SOAP envelope contents (outgoing):
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> <soap:Header> <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://xxx.xxx.101.175:8 080/wsn-producer/services/WsResource</wsa:To> <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-o pen.org/wsn/bw-2/NotificationProducer/SubscribeRequest</wsa:Action> <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:bcff16d2-91 ca-967e-75fa-c6ef162d775a</wsa:MessageID> <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing"> <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous</wsa:Addres s> </wsa:From> </soap:Header> <soap:Body> <wsnt:Subscribe xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"> <wsnt:ConsumerReference> <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://16. 158.101.175:8080/wsn-consumer/services/consumer</wsa:Address> </wsnt:ConsumerReference> </wsnt:Subscribe> </soap:Body> </soap:Envelope> |
3.2. NotificationProducer
<wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://xxx.xxx.101.175:8 080/wsn-producer/services/WsResource</wsa:To> |
以上WS-Addressing所指向的NotificationProducer收到该消息。根据WS-Notification协议首先立刻回复给Subscriber一个Response消息:
[CLIENT TRACE] SOAP envelope contents (incoming):
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> <soap:Header> <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/ 08/addressing/role/anonymous</wsa:To> <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-o pen.org/wsn/bw-2/NotificationProducer/SubscribeResponse</wsa:Action> <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:1e6415b4-a8 ad-f1d0-52f2-fc68f0ed8743</wsa:MessageID> <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08 /addressing">uuid:bcff16d2-91ca-967e-75fa-c6ef162d775a</wsa:RelatesTo> <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing"> <wsa:Address>http://xxx.xxx.101.175:8080/wsn-producer/services/WsResource</ws a:Address> </wsa:From> </soap:Header> <soap:Body> <wsnt:SubscribeResponse xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"> <wsnt:SubscriptionReference> <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://16. 158.101.175:8080/wsn-producer/services/SubscriptionManager</wsa:Address> <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing "> <muse-wsa:ResourceId xmlns:muse-wsa="http://ws.apache.org/muse/addre ssing">MuseResource-1</muse-wsa:ResourceId> </wsa:ReferenceParameters> </wsnt:SubscriptionReference> <wsnt:CurrentTime>2007-07-19T15:10:57+08:00</wsnt:CurrentTime> </wsnt:SubscribeResponse> </soap:Body> </soap:Envelope> |
可以从Response的SOAP消息的wsa:RelateToRelationship中消息的uuid看出,是对哪个SubScribe消息作出的回复。这些是WS-Addressing协议所包含的内容。订阅(Subscribe)到此也即完成了。
当发布(Publish)发生时,NotificationProducer会立刻执行如下代码
final NotificationProducer wsn = (NotificationProducer)getResource().getCapability(WsnConstants.PRODUCER_URI); wsn.addTopic(_TOPIC_NAME); |
该代码会实例化一个NotificationProducer,用于发出Notification消息,该消息为WS-N协议中的中的Notify消息。发出消息的Java代码如下:
wsn.publish(_TOPIC_NAME, payload); |
发出的Message如下:
[CLIENT TRACE] SOAP envelope contents (outgoing):
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> <soap:Header> <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://xxx.xxx.101.175:8080/wsn-consumer/services/consumer</wsa:To> <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer/NotifyRequest</wsa:Action> <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:34381618-d677-0cad-0dca-60a079f1a2d9</wsa:MessageID> <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing"> <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing"/> <wsa:Address>http://xxx.xxx.101.175:8080/wsn-producer/services/WsResource</wsa:Address> </wsa:From> </soap:Header> <soap:Body> <wsnt:Notify xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"> <wsnt:NotificationMessage xmlns:muse-wsa="http://ws.apache.org/muse/addressing" xmlns:tns="http://ws.apache.org/muse/test/wsrf" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"> <wsnt:SubscriptionReference> <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://xxx.xxx.101.175:8080/wsn-producer/services/SubscriptionManager</wsa:Address> <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing"> <muse-wsa:ResourceId xmlns:muse-wsa="http://ws.apache.org/muse/addressing">MuseResource-1</muse-wsa:ResourceId> </wsa:ReferenceParameters> </wsnt:SubscriptionReference> <wsnt:Topic Dialect="http://docs.oasis-open.org/wsn/t-1/TopicExpression/Concrete" xmlns:tns="http://ws.apache.org/muse/test/wsrf">tns:MyTopic</wsnt:Topic> <wsnt:ProducerReference> <wsa:ReferenceParameters xmlns:wsa="http://www.w3.org/2005/08/addressing"/> <wsa:Address xmlns:wsa="http://www.w3.org/2005/08/addressing">http://xxx.xxx.101.175:8080/wsn-producer/services/WsResource</wsa:Address> </wsnt:ProducerReference> <wsnt:Message> <tns:MyMessage xmlns:tns="http://ws.apache.org/muse/test/wsrf">This is a message from muse-test.apache.org</tns:MyMessage> </wsnt:Message> </wsnt:NotificationMessage> </wsnt:Notify> </soap:Body> </soap:Envelope> |
可以从
<wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://xxx.xxx.101.175:8080/wsn-consumer/services/consumer</wsa:To> |
看出,该Notify发出到的目的地,也即是Subscriber在订阅时提供的consumer地址,另外就是从Notify消息中可以看到Topic的内容:
<wsnt:Message> <tns:MyMessage xmlns:tns="http://ws.apache.org/muse/test/wsrf">This is a message from muse-test.apache.org</tns:MyMessage> </wsnt:Message> |
3.3.NotificationConsumer
NotificationConsumer的实现类是org.apache.muse.test.wsn.impl.ConsumerCapabilityImpl.java,其process(…)将负责处理接受到的来自NotificationProducer的消息。对于NotificationConsumer来说,接受到的WS-N的消息就是NotificationProducer所Publish出的消息,即:
<wsnt:NotificationMessage… …. </wsnt:NotificationMessage> |
然后,根据WS-N的协议,NotificationConsumer还要发回一个Response的SOAP消息
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"> <soap:Header> <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing">http://xxx.xxx.101.175:8080/wsn-producer/services/WsResource</wsa:To> <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing">http://docs.oasis-open.org/wsn/bw-2/NotificationConsumer/NotifyResponse</wsa:Action> <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:4648251e-66a2-80ed-6ea0-84998f3d85c9</wsa:MessageID> <wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:34381618-d677-0cad-0dca-60a079f1a2d9</wsa:RelatesTo> <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing"> <wsa:Address>http://xxx.xxx.101.175:8080/wsn-consumer/services/consumer</wsa:Address> </wsa:From> </soap:Header> <soap:Body> <wsnt:NotifyResponse xmlns:wsnt="http://docs.oasis-open.org/wsn/b-2"/> </soap:Body> </soap:Envelope> |
很明显,从MessageID可以看出这个NotifyResponse同Notify之间的关系。至此,订阅、发布、通知即完整的完成了。
<wsa:RelatesTo RelationshipType="wsa:Reply" xmlns:wsa="http://www.w3.org/2005/08/addressing">uuid:34381618-d677-0cad-0dca-60a079f1a2d9</wsa:RelatesTo> |
-end-