Skip to main content

skip to main content

developerWorks  >  SOA and Web services | XML  >

Firewalls: Web services' Achilles' Heel?

Asyncrhonous message delivery with firewalls

developerWorks
Document options

Document options requiring JavaScript are not displayed


Rate this page

Help us improve this content


Level: Intermediate

Doug Davis, Architect, IBM

27 Oct 2005

Overcome asynchronous messaging challenges by using Web Services Polling (WS-Polling). In a previous paper, "The hidden impact of WS-Addressing on SOAP" (see Resources), the author talked about how the WS-Addressing specification would have a dramatic impact on SOAP itself. The notion of any SOAP message being routed dynamically based on information inside of the WS-Addressing Headers introduces a new level of freedom to SOAP users. They are no longer limited to simple HTTP request/response message flows. Specifications such as WS-Coordination/Transactions and WS-Reliable Messaging can now assume there's an asynchronous message processing model -- and one that is defined in a standard way -- simply by using the WS-Addressing headers. However, as with many things, there's a downside to using asynchronous message processing and an obstacle to its adoption -- firewalls.

Firewalls bad? Say it isn't so!

Well, ok -- firewalls themselves aren't bad, but if you think about what asynchronous message processing means, they certainly throw an interesting monkey-wrench into the mix. Suppose you have a Web service client running on your home computer and you try to call out to some service on the Web that will take a while to execute. In that case there's a chance that either the HTTP connection will not stay open long enough for you to receive the response or, even if it did, you might not want it to -- why tie up resources while waiting? And besides, you're talking about asynchronous message processing so you're expecting the result to come back to you through a new connection. First let's examine how you tell the service you're expecting the response back asynchronously; your request message will contain a WS-Addressing ReplyTo header that might look something like the following:


Listing 1. Sample WS-Addressing ReplyTo header
				
  <wsa:ReplyTo>
    <wsa:Address>http://myhomemachine.com/inMessages</wsa:Address>
  </wsa:ReplyTo>

This of course indicates that any response message should be sent over a new HTTP connection to http://myhomemachine.com/inMessages. Seems easy enough, but it means two things must be true: first, a SOAP server/listener must be running on that machine (my home machine) in order to receive incoming messages, and second, the machine on the Internet must be able to open a connection back to that machine -- through my firewall.

The first problem may or may not be a big deal depending on your level of experience. The act of setting up a SOAP server might be too much to ask of a non-technical person, and not everyone would really want something as big as a SOAP server running on their home machine. However, the second problem is even more bothersome. With all of the viruses and security holes in operating systems out there, most people wouldn't want to risk it, so they would never open up any ports in their home router or firewall. So, even though some people have the technical knowledge to setup a SOAP server, given many people's justified paranoia, right now there's no way a SOAP response message will ever get back to some people asynchronously. So, what can you do?



Back to top


Those who learn from history repeat it anyway

If you look at how this problem was solved for other Internet-based messaging systems, you can reuse some of the same solutions. In particular, look at the most popular messaging system in use today: e-mail. Much like in the SOAP scenario previously described, you could open up the SMTP port (25) on your firewall and have an SMTP server running to receive incoming e-mail. But that kind of technical know-how would be beyond most non-technical people. Instead, most people delegate the hosting of their e-mail address to someone else (some mail hosting service provider). They then simply use some mail client to download their e-mail messages. This solves both problems: no need to set up a local (and complicated) server and no need to open up their firewall and risk attacks.

So, how do you do this in SOAP? The answer presented itself once the WS-Addressing specification was developed. With WS-Addressing you now have the ability to tell the recipient of your message where to send responses - much like the "From" field in your e-mails. So, change your wsa:ReplyTo header to something like the following:


Listing 2. Sample wsa:ReplyTo using a Mailbox
				
  <wsa:ReplyTo>
    <wsa:Address>http://mailbox.soaphub.org/soaphub/services/soaphub</wsa:Address>
  </wsa:ReplyTo>

Then your response message will now go to your SOAP message hosting provider mailbox.soaphub.org instead. This site will simply accept the message and wait for your SOAP client to retrieve it. Now you don't need a heavy SOAP server running on your client, and you don't need to open up your firewall. One other interesting thing to note about this is that the Web service you're invoking doesn't need to change at all to support this (assuming it at least supports WS-Addressing). From the service's point of view, it just sends the response where the client told it to -- whether it's to the actual client or to some "message hosting provider;" it doesn't know or care -- it simply opens a connection to the wsa:ReplyTo endpoint regardless of its value.

Of course, there's a catch -- currently SOAP clients are not written to "ask for" (in other words, poll for) the result of a Web services call. However, the good news is that there is a specification (WS-Polling) that defines a standard way of polling for the results of a Web services call, and it doesn't really require a lot of code to do it.



Back to top


WS-Polling

WS-Polling, at its simplest level, just defines a single SOAP operation called GetMessage, which the SOAP client can use against the message hosting provider. This operation will either return the desired SOAP message or return nothing at all if there are no messages waiting to be delivered to this SOAP client. Let's take a look at an example. Suppose a SOAP client is calling an echoString service (one that just returns the String passed in). The request message might look something like the following:


Listing 3. Request messaging pointing to a SOAP message provider
				
  <s:Envelope>
    <s:Header>
      <wsa:MessageID>uuid:705738e3907891e3</wsa:MessageID>
      <wsa:To>http://www.echostring.com/echoString</wsa:To>
      <wsa:Action>echoString</wsa:Action>
      <wsa:ReplyTo>
        <wsa:Address>http://mailbox.soaphub.org/soaphub/services/soaphub</wsa:Address>
      </wsa:ReplyTo>
      </s:Header>
    <s:Body>
      <echoString>
        <Text>Hello World</Text>
      </echoString>
    </s:Body>
  </s:Envelope>

Notice that the wsa:ReplyTo header is neither the anonymous URI or myhomemachine.com, but instead the URL of the SOAP message hosting provider. So, when the echoString service generates its result it will send it to mailbox.soaphub.org, and it will look something like the following:


Listing 4. Response message headed to the SOAP message provider
				
  <s:Envelope>
    <s:Header>
      <wsa:MessageID>uuid:5e73f8b9893821f0</wsa:MessageID>
      <wsa:To>http://mailbox.soaphub.org/soaphub/services/soaphub</wsa:To>
      <wsa:Action>echoStringResponse</wsa:Action>
      <wsa:From>
        <wsa:Address>
          http://www.echostring.com/services/echoString
        </wsa:Address>
      </wsa:From>
      <wsa:RelatesTo>uuid:705738e3907891e3</wsa:RelatesTo>
    </s:Header>
    <s:Body>
      <echoStringResponse>
        <Text>Hello World</Text>
      </echoStringResponse>
    </s:Body>
  </s:Envelope>

Notice that it looks no different than what you would expect based on the WS-Addressing processing rules. Now your SOAP client must poll for the response:


Listing 5. WS-Polling request
				
  <s:Envelope>
    <s:Header>
      <wsa:MessageID>uuid:705738e3dbb46924</wsa:MessageID>
      <wsa:To>http://mailbox.soaphub.org/soaphub/services/soaphub</wsa:To>
      <wsa:Action>
        http://www.w3.org/2005/08/ws-polling/GetMessage
      </wsa:Action>
      <wsa:ReplyTo>
        <wsa:Address>
   http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous
        </wsa:Address>
      </wsa:ReplyTo>
    </s:Header>
    <s:Body>
      <wsp:GetMessage>
        <wsa:MessageID>uuid:705738e3907891e3</wsa:MessageID>
      </wsp:GetMessage>
    </s:Body>
  </s:Envelope>

The GetMessage operation has a couple of variants, but the one you're using here takes just a single MessageID parameter, indicating the wsa:MessageID of the request message whose response you're looking for. Or, said another way, you previously sent a message to a Web service and that request message had a wsa:MessageID header with a value of uuid:705738e3907891e3. You're now asking mailbox.soaphub.org for its response message. Note that since the wsa:ReplyTo header has the anonymous URI, the response from GetMessage will be returned on the HTTP response flow, thus allowing the response from your original message to be delivered back to you through the firewall. One other point that's worth repeating; notice that the Web service that you invoked was unaware of your use of mailbox.soaphub.org. WS-Polling can be used transparently to any existing Web service that supports WS-Addressing.

If the SOAP message provider does not have the response message available yet, then it simply returns the following:


Listing 6. WS-Polling NoMessageAvailable response
				
  <s:Envelope>
    <s:Header>
      <wsa:MessageID>uuid:49fd3860900fa472</wsa:MessageID>
      <wsa:To>
    http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous
      </wsa:To>
      <wsa:Action>
    http://www.w3.org/2005/08/ws-polling/NoMessageAvailable
      </wsa:Action>
      <wsa:From>
        <wsa:Address>
          http://mailbox.soaphub.org/soaphub/services/soaphub
        </wsa:Address>
      </wsa:From>
      <wsa:RelatesTo> uuid:705738e3dbb46924</wsa:RelatesTo>
    </s:Header>
    <s:Body>
      <wsp:NoMessageAvailable reason="wsp:UnknownMessageID"/>
    </s:Body>
  </s:Envelope>

The key element in this message is wsp:NoMessageAvailable -- meaning that the requested response message is not available, so the requester (your client) should poll again later.

And for completeness, eventually when the response from your echoString is available, the response message from GetMessage() might look like the following:


Listing 7. WS-Polling successful response
				
  <s:Envelope>
    <s:Header>
      <wsa:MessageID>uuid:5e73f8b9893821f0</wsa:MessageID>
      <wsa:To>
  http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous
      </wsa:To>
      <wsa:Action>echoStringResponse</wsa:Action>
      <wsa:From>
        <wsa:Address>
          http://www.echostring.com/services/echoString
        </wsa:Address>
      </wsa:From>
      <wsa:RelatesTo>uuid:705738e3907891e3</wsa:RelatesTo>
      <wsa:RelatesTo>uuid:705738e3dbb46924</wsa:RelatesTo>
    </s:Header>
    <s:Body>
      <echoStringResponse>
        <Text>Hello World</Text>
      </echoStringResponse>
    </s:Body>
  </s:Envelope>

Some things to pay close attention to are the wsa:RelatesTo headers. Notice that there are two of them. This is because this response message is actually a response for two different request messages -- one being the WS-Polling GetMessage request and the other being the echoString request. Yet another interesting feature of WS-Addressing.

As shown in this example, unlike the service-side of the message exchange, the SOAP client cannot be oblivious to the use of WS-Polling. Currently SOAP clients, in one form or another, wait around for a response message to be delivered back to the client (either through a new socket or on the HTTP response flow). SOAP clients that wish to support asynchronous messaging through firewalls (and without a client needing a SOAP server running) would need to add support for WS-Polling. The logic isn't terribly difficult -- instead of waiting for the response message to arrive, the client would periodically use the GetMessage operation to poll its SOAP messaging provider for the desired response message. Not a lot of work or code, but keep in mind that it not yet finalized as of today.



Back to top


Other scenarios

WS-Polling can be used in a wide variety of scenarios. Below are just a few of the ones I think are worth special mention.

Unsolicited Messages

If a SOAP client has subscribed to a notification system (using, for example, WS-Notification or WS-Eventing) but they are behind a firewall any notification messages wishing to be sent to a subscriber client behind a firewall, can now be delivered. The subscriber (client) simply needs to use WS-Polling to periodically query its SOAP messaging host for any messages waiting to be delivered to it. Of course, when the client subscribed to the notification system it must have specified its SOAP messaging host as the target EPR of its messages, but the notification system is unaware of its use. It is important to note that WS-Polling allows for its GetMessage request to query for any messages destined for the client -- not just responses messages. It defines some common query dialects that can be used, but is extensible enough to allow for new ones to be defined as well (see the 24x7 Web presence scenario below).

Server-side support

While this paper focuses on using a SOAP messaging host as a mailbox, it's also possible for a service endpoint to directly support WS-Polling itself. WS-Polling defines a way for the client and service to know that the other supports (and will use) WS-Polling when appropriate. This would allow for asynchronous messaging between two endpoints without the need for a 3rd party mailbox.

Security

WS-Polling is designed to be composed with the other WS-* specifications, including the security ones (WS-Security and WS-SecureConversation). The WS-Polling specification explains how to use some of its features to ensure that message integrity is not compromised, even when using a 3rd party mailbox.

Message delivery control

WS-Polling can be used as a means for an endpoint to control the rate at which messages are delivered and processed by its SOAP engine. Without firewalls, if an endpoint hosted a SOAP server, it could not easily control the rate at which messages would be delivered (or attempt to be delivered). Using WS-Polling, an endpoint has complete control over how often messages are delivered to its engine for processing.

24x7 Web presence

There can be cases where a service cannot be available on the Web all day every day. If the service provider used a WS-Polling mailbox as the EPR of its services, then incoming messages could be delivered at any time. Then when the service does come on-line, it could retrieve the pending messages from the mailbox and process them. This gives the appearance of the service being available 24x7.

Reverse protocol

WS-Polling can be viewed as a reverse protocol. Once the initial WS-Polling GetMessage is sent, request messages can flow on the HTTP response flow. Then responses to those requests can flow on a new HTTP connection -- on the request side. This allows WS-Polling to be used as a means to initiate a connection between two endpoints, when the requesting side could not normally do it itself.

Optimizations:

WS-Polling optimizes the act of polling by defining additional SOAP headers that can be included in non-WS-Polling messages as a means for the two endpoints to communicate the presence of messages needing to be delivered. This could dramatically improve the network overhead normally associated with periodic polling.

Implementation:

As with other WS-* specifications, such as WS-MetadataExchange, it can be used two different ways. Client applications can issue the GetMessage request themselves, and then they would be expected to manually process any possible response. Or, the SOAP stack itself could issue the GetMessage request from its infrastructural code. For example, if the client application indicates that it wants to use a mailbox for its wsa:ReplyTo then when the response flow doesn't include the reply message, the SOAP stack can automatically poll the mailbox. This would hide most of the use of WS-Polling from the client application. (Yes, it still needs to indicate which mailbox to use, but the client application is free from doing the polling itself). Likewise, the client SOAP stack could also use the "hold it" URI in place of the anonymous URI with or without the client application's knowledge, allowing it to poll for responses without the application having to deal with it explicitly.

These are just some of the possible uses and features of WS-Polling. See the specification for a more complete explanation of each one (see Resources).



Back to top


Conclusion

There are already several polling solutions popping up various specifications, so clearly there is a need for this type of solution. While those work for the particular problem space of each individual spec, WS-Polling allows for a more generic solution that can be used to address all of these concerns and allows for a single infrastructural implementation to be reused for all of them. Duplication of functionality across WS-* specifications would lead to more confusion for implementers as well as their customers.

This paper explored how WS-Polling can be used to enable a truly asynchronous messaging delivery model even when firewalls get in the way - and of course how WS-Addressing has made all of this possible. WS-Polling has been submitted to the W3C as a Member Submission, and IBM's external WS-RM interop endpoint allows for WS-Polling to be used if you would like to see it in action. It uses a WS-Polling SOAP message host located at http://mailbox.soaphub.org. For more information on this new specification feel free to contact the author.



Resources



About the author

Doug Davis is an architect in the Software Standards division of IBM. His previous roles include technical lead of the Emerging Technologies Toolkit, WebSphere Machine Translation, Team Connection, and the IBM Fortran 90. Contact Doug at dug at us.ibm.com.




Rate this page


Please take a moment to complete this form to help us better serve you.



YesNoDon't know
 


 


12345
Not
useful
Extremely
useful
 


Back to top