Web services are a boon when it comes to achieving a loosely coupled architecture since they are not locked down...
to a specific platform provider or consumer. In principle, this design is optimal for many enterprise settings, but also comes with its shortcomings. Up next we will address one important factor which requires a specific Web services approach on account of this same loosely coupled architecture : Application notification.
The concept of application notification is rooted in enterprise messaging technology such as Java JMS, Microsoft MSMQ and TIBCO Rendezvous. The adoption of such messaging technology came to the forefront in enterprise IT with the increased pressure of establishing communication channels as ample as possible between the many disparate applications in an organization. However, with this same approach of mixing and matching n-types of applications via messaging came the issue of establishing a uniform notification mechanism to confront the issues inherent in such a design.
Since Web services' primary objective is also that of bridging application disparities using a similar principle, that of of XML messaging, by consequence this same notification issue carries over to certain Web services scenarios. The weight notification carries in Web services is not only due to the various design variations that can arise when bridging different applications, but also on account of the network bound nature of such applications, which in turn bring issues like latency, network failure or unavailability into a design.
In an effort to address such challenges, OASIS, which is charged with advancing many Web services standards, created Web Services Notification (WSN) . WSN's intent is to provide an event-driven manner in which to create topic-based publish/subscribe Web services. The approach and terminology which might sound familiar, especially if you have worked with any of the previously mentioned enterprise messaging technologies, consists of the following parts:
- Subscriber: A Web service which registers itself to receive updates on a particular event/notification.
- Publisher: A Web service that dispatches notification message out to subscribers.
- An event/notification: The actual account which triggers a publisher to dispatch a notification message to a subscriber.
- A notification message: The payload which gets sent to a subscriber on account of the event/notification.
While WSN's working group breaks down the previous parts into even more specific concepts, at a high level these four concepts should be sufficient to grasp the Web services pattern WSN tries to address. It should also be noted that WSN is actually conformed by three specifications: WS-Base Notification, WS-Brokered Notification and WS-Topics, but as is the case with terms, knowing the intricacies of these three working groups should be of minimal concern for end users dealing with a WSN implementation.
Now that we have covered WSN's core concepts, let's move on to a hands-on WSN example. As in other columns, we will base our exploration on open source software produced by the Apache Software Foundation. For our particular case, Pubscribe will provides us with a WSN implementation that can be used in conjunction with the rest of the Web services stack produced by Apache, such as Axis for the core engine, Apache's WSRF implementation, Apache Kandula for WS-Coordination or Apache Sandesha for WS-ReliableMessaging, among other projects/specs.
Before we kick things off, you should be aware that Pubscribe from Apache is tightly integrated with Apache's WSRF (Web Services Resource Framework) implementation , to a certain extent this makes sense, since a Web service notification process implies maintaining some type of state on behalf of a publisher for later retrieval by a subscriber, but keep in mind this does not mean every Web service stack will require WSRF to use WSN. This is a specific choice made by Apache's WSN designers, a route which might or not be the same for other WSN implementations. You can read an earlier column on WSRF for core concepts on this other Web services specification.
Our application consists of two types of Web services used in a call center. One type is used for dispatching incoming requests (Publisher) while the others are used to attend such requests (Subscriber) with the actual payload (Notification message) consisting of an XML-encoded fragment. At a business level, the Web services publishers can represent an organization's head offices, while the subscribers can be thought of as branches or off-shore systems, which take incoming requests on a first-come-first-serve basis from the publisher.
Given this scenario, lets take a look at a fragment of the WSDL contract which would be published by the head office that and later need to be processed by each subscriber. Listing 1.1 shows such a contract.
Listing 1.1 WSDL contract using WSN.
<?xml version="1.0"?> <definitions name="SupportSystemResourceDefinition" targetNamespace="http://ws.apache.org/resource/example/filesystem" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd" xmlns:wsrpw="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl" xmlns:wsntw="http://docs.oasis-open.org/wsn/2004/06/wsn-WS-BaseNotification-1.2-draft-01.wsdl"> <!-- WSDL <import>, <types> and <message> sections omitted for brevity --> <portType name="SupportSystemPortType" wsrp:ResourceProperties="tns:SupportSystemProperties"> <!-- Resource operations --> <operation name="GetResourceProperty"> <input name="GetResourcePropertyRequest" message="wsrpw:GetResourcePropertyRequest"/> <output name="GetResourcePropertyResponse" message="wsrpw:GetResourcePropertyResponse"/> <fault name="ResourceUnknownFault" message="wsrpw:ResourceUnknownFault"/> <fault name="InvalidResourcePropertyQNameFault" message="wsrpw:InvalidResourcePropertyQNameFault"/> </operation> <operation name="SetResourceProperties"> <input name="SetResourcePropertiesRequest" message="wsrpw:SetResourcePropertiesRequest"/> <output name="SetResourcePropertiesResponse" message="wsrpw:SetResourcePropertiesResponse"/> <fault name="ResourceUnknownFault" message="wsrpw:ResourceUnknownFault"/> <fault name="InvalidResourcePropertyQNameFault" message="wsrpw:InvalidResourcePropertyQNameFault"/> </operation> <!-- Other Resource operations omitted for brevity --> <!-- Notification operations --> <operation name="Subscribe"> <input message="wsntw:SubscribeRequest" /> <output message="wsntw:SubscribeResponse" /> <fault name="ResourceUnknownFault" message="wsntw:ResourceUnknownFault" /> <fault name="SubscribeCreationFailedFault" message="wsntw:SubscribeCreationFailedFault" /> <fault name="TopicPathDialectUnknownFault" message="wsntw:TopicPathDialectUnknownFault" /> </operation> <operation name="GetCurrentMessage"> <input message="wsntw:GetCurrentMessageRequest" /> <output message="wsntw:GetCurrentMessageResponse" /> <fault name="ResourceUnknownFault" message="wsntw:ResourceUnknownFault" /> <fault name="InvalidTopicExpressionFault" message="wsntw:InvalidTopicExpressionFault" /> <fault name="TopicNotSupportedFault" message="wsntw:TopicNotSupportedFault" /> <fault name="NoCurrentMessageOnTopicFault" message="wsntw:NoCurrentMessageOnTopicFault" /> </operation> <!-- Other Resource operations omitted for brevity --> </portType> <binding name="SupportSystemSoapHttpBinding" type="tns:SupportSystemPortType"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/> <!-- Binding for notification operation(s) --> <operation name="Subscribe"> <soap:operation style="document"/> <input> <soap:body use="literal"/> </input> <output> <soap:body use="literal"/> </output> <fault name="ResourceUnknownFault"> <soap:fault name="ResourceUnknownFault" use="literal"/> </fault> <fault name="SubscribeCreationFailedFault"> <soap:fault name="SubscribeCreationFailedFault" use="literal"/> </fault> <fault name="TopicPathDialectUnknownFault"> <soap:fault name="TopicPathDialectUnknownFault" use="literal"/> </fault> </operation> <!-- Other bindings for operations omitted from brevity --> </binding> <!-- Service name declaration --> <service name="SupportSystemService"> <port name="filesystem" binding="tns:SupportSystemSoapHttpBinding"> <soap:address location="http://www.hqsupportsystem.com/pubscribe/services/pcsupport"/> </port> </service> </definitions>
Near the top you can observe the namespece
wsntw for Web Services Notification. Moving along you will also observe two operations related to notifications events:
GetCurrentMessage, methods which are invoked by the client Web service to inform the publisher it wishes to be notified of events and to obtain the latest message, respectively. Interspersed throughout the WSDL contract you will also find WSRF statements as well as the typical operations and bindings associated with a WSDL contract. However, we will limit ourselves to describing the fragments related to our central theme on notification.
Due to its length we won't illustrate the Web service implementation behind this WSDL, neither the publisher nor its corresponding subscriber Web services, but be assured that the life-cycle corresponding to the Web services notification process is concentrated in the two aforementioned methods in the WSDL with the logic behind these two methods being built with the API provided by Pubscribe.
With this we conclude our look into WSN. You should now be in a position to incorporate into the same loosely coupled architectures composed as Web services the capability of application notification and with it support the enterprise business needs of longer lived process that require event-based notification.
About the author
Daniel Rubio is an independent technology consultant specializing in enterprise and Web-based software. He blogs regularly on these and other software areas at http://www.webforefront.com/.