In this article, you'll learn how to create a Web service from the ground up, then apply Web Services Reliable Messaging (WS-RM) to it. You'll use Rational Application Developer V7.5 to deploy the application as a Web service and apply the WebSphere Application Server V7 implementation of the WS-RM specification to it. Along the way, we'll describe each WS-RM option, so that when you're ready to apply WS-RM to your own applications, you can make an informed decision about what options are best for your situation.
After finishing the article, you'll have a better understanding of what the WS-RM specification aims to achieve and how you can use it in WebSphere Application Server V7.
What is WS-RM?
WS-RM is a Web service specification that enables the reliable delivery of SOAP messages between Web service clients, or sources, and Web service providers. There are currently two levels of the specification, 1.0 and 1.1, both of which are supported in WebSphere Application Server Version 7 (hereafter Application Server).
The WS-RM specification defines an on-the-wire protocol that aims to solve two problems encountered when trying to deliver SOAP messages over, for example, a HTTP connection:
- How can a client ensure the delivery of a SOAP message when the source or destination endpoints become temporarily unavailable (for example, when a server is unexpectedly restarted)?
- How can a client ensure the delivery of a SOAP message when the path from the source to the destination endpoint crosses several distinct transport connections (such as passing through a firewall)? Any one of the connections could fail; for example, due to a timeout. How can the client detect the condition and retry the message transmission?
The WS-RM protocol solves both of these problems by defining how to resend messages that it determines have not been delivered successfully, and by preventing duplicate messages being delivered to the destination application. With the Application Server V7 WS-RM implementation, application developers can concentrate on specific application logic, rather than having to code application-independent retry logic.
Application Server supports the application of WS-RM only to Java™ API for XML (JAX-WS) applications and services. You cannot apply WS-RM to JAX-Remote Procedure Call (RPC) applications or to specific operations within a service.
WS-RM under the covers
The key to WS-RM is the concept of a sequence. A sequence in WS-RM is essentially a contract between a Web services client and a Web services provider, through which they agree to reliably transmit messages between them. The sequence is used to maintain the state of messages that have been sent and received. The sequence itself is specific to a provider's endpoint. When a client sends a message to a Web service provider's endpoint for the first time, a sequence to that provider's endpoint is created, and all subsequent messages from that client to that provider's endpoint are delivered on that sequence. The sequence allows client- and provider-side WS-RM to decide whether application messages need to be redelivered and to detect whether arriving messages are duplicates.
To define sequences and maintain current state, both client and provider WS-RM uses a collection of defined protocol messages that are sent back and forth. The following diagram shows a typical message flow for a request-reply Web service invocation using WS-RM . Descriptions of each of the message types shown in the diagram follow the diagram.
Figure 1. Message flow for a Web service using WS-RM
- CreateSequence: This WS-RM protocol message informs a client or
provider WS-RM implementation that a new sequence has been requested
to a specific Web Service providers endpoint. The createSequence
provides an endpoint wsrm:AcksTo which is used to send
<soapenv:Header> ……. </soapenv:Header> <soapenv:Body> <wsrm:CreateSequence xmlns:wsrm="http://docs.oasis-open.org/ws- rx/wsrm/200702"> <wsrm:AcksTo> <wsa:Address>http://docs.oasis-open.org/ws-rx/wsmc/200702/anonymous? id=urn:uuid:13EC8EEB4338FEE7CB1185807025917</wsa:Address> </wsrm:AcksTo> </wsrm:CreateSequence> </soapenv:Body>
- CreateSequenceResponse: This WS-RM protocol message informs the
client or provider WS-RM implementation that the createSequence
request to the specific endpoint has been accepted; it also provides a
wsrm:Identifier that is then used to describe the sequence.
<soapenv:Header> ……. </soapenv:Header> <soapenv:Body> <wsrm:CreateSequenceResponse xmlns:wsrm= "http://docs.oasis-open.org/ws-rx/wsrm/200702"> <wsrm:Identifier>urn:uuid:13EC8EEB4338FEE7CB1185807029442 </wsrm:Identifier> </wsrm:CreateSequenceResponse> </soapenv:Body>
- Sequence message: These messages carry the application message.
Each sequence message has a message number which starts at 1 and
increases incrementally for each application message sent.
<soapenv:Header> <wsa:To>http://127.0.0.1:9999/axis2/services/RMSampleService </wsa:To> <wsa:ReplyTo> <wsa:Address>http://docs.oasis-open.org/ws-rx/wsmc /200702/anonymous?id=urn:uuid:13EC8EEB4338FEE7CB1185807025917 </wsa:Address> </wsa:ReplyTo> <wsa:MessageID>urn:uuid:13EC8EEB4338FEE7CB1185807026684 </wsa:MessageID> <wsa:Action>urn:wsrm:EchoString</wsa:Action> <wsrm:Sequence xmlns:wsrm="http://docs.oasis-open.org/ ws-rx/wsrm/200702" soapenv:mustUnderstand="1"> <wsrm:Identifier>urn:uuid:13EC8EEB4338FEE7CB1185807029442 </wsrm:Identifier> <wsrm:MessageNumber>1</wsrm:MessageNumber> </wsrm:Sequence> </soapenv:Header> <soapenv:Body> ……. </soapenv:Body>
- SequenceAcknowledgement: These WS-RM protocol messages are used
to acknowledge the application messages. They will contain the
wsrm:AcknowledgementRange, which corresponds to the relevant sequence numbers. If there are any messages missing from the acknowledgment range, the client resends the messages.
<soapenv:Header> <wsrm:SequenceAcknowledgement xmlns:wsrm="http://docs.oasis-open.org/ws-rx/wsrm/200702" soapenv:mustUnderstand="1"> <wsrm:Identifier>urn:uuid:13EC8EEB4338FEE7CB1185807025137</wsrm:Identifier> <wsrm:AcknowledgementRange Lower="1" Upper="1" /> </wsrm:SequenceAcknowledgement> <wsa:To>http://127.0.0.1:9999/axis2/services/RMSampleService</wsa:To> <wsa:MessageID>urn:uuid:13EC8EEB4338FEE7CB1185807033601</wsa:MessageID> <wsa:Action>http://docs.oasis-open.org/ws-rx/wsrm/200702/SequenceAcknowledgement </wsa:Action> </soapenv:Header> <soapenv:Body> ……. </soapenv:Body>
Some points to note:
- There are other protocol messages (such as, closeSequence, terminateSequence) that are described in the WS-RM specifications that Application Server V7 supports. These are out of scope for this article, but you can find more information about them in the WS-RM specification.
- If a WS-RM client knows that a two way Message exchange protocol is in place it can offer a sequenceID as part of the initial create sequence protocol message. This then will be accepted or rejected as part of the createSequenceResponse protocol message. If accepted there is no need for the WS-RM provider to complete a sequence creation handshake to have a uence to send the application response message on.
Overview of the bank application
The value of WS-RM becomes apparent when an application's SOAP messages are of significant importance; for example if they contain details of financial transactions. Therefore, our scenario will use a simple bank application to introduce this technology.
The basis of the bank application is a single Java class containing
skeleton operations that might be used in such a scenario. For example the
depositFunds method might be used to transfer
money from one account to another; therefore, the underlying SOAP messages
would be of value to the participants. This method could benefit from the
use of WS-RM.
The rest of this article walks you through the process of using the bank application to generate a Web service and Web service client, and applying WS-RM using Rational Application Developer V7.5 (hereafter called Application Developer) tooling and the Application Server administrative console.
Create an application server
The first step is to create an application server in Rational Application Developer V7.5 that you can use to deploy and run your Web service and Web service client. It's important that the server you create is set up to allow you to configure applications directly in the administrative console.
- Start Rational Application Developer Version 7.5.
- Create a new Application Server V7 server by selecting File => New => Other.
- In the New dialog, start typing
server. When the server wizard displays, select it and click Next as shown in Figure 2.
Figure 2. Select server wizard
- In the next dialog, you can define the type of server you require. For
this example, accept all the defaults, and make sure the WebSphere
Application Server v7.0 is selected, as shown in Figure 3, then click
Figure 3. Define new server
- Finally you need to define the server settings. Uncheck Run server
with resources within the workspace, accept the defaults for
everything else, and click Finish, as shown in Figure 4.
Figure 4. Define server settings
Create a JAX-WS Web service and Web service client
In WebSphere Application Server V7, you can add WS-ReliableMessaging only to JAX-WS Web services. In this section, we'll walk through the steps to create a JAX-WS Web service from a Java class using Rational Application Developer.
- Start Rational Application Developer Version 7.5.
- Create a new Enterprise Application Project by selecting File
=> New => Enterprise Application Project, as
shown in Figure 5.
Figure 5. Create new Enterprise Application Project
- We'll call our project Bank and run it on the WebSphere
Application Server V7 runtime that you created in the previous
section. Enter the details as shown in Figure 6, and click
Figure 6. Specify project information
The project appears in the Enterprise Explorer view.
- Create a new Java project to contain the base Java code for our JAX-WS
Web service. Right-click the Bank enterprise application project and
select New => Project. Expand the Java section and
select Java Project, as shown in Figure 7 then click
Figure 7. Create Java project
BankProjectas the Project name and leave the default values, as shown in Figure 8. Then click Finish.
Figure 8. Specify project name
- Populate the project with some base source code to provide the
function of the Web service. To do this, download and import the
Bank.java source code provided with this
article. Once imported, you should see the code as shown in Figure 9.
Figure 9. Bank,java source code
- After importing the Bank.java code, the next step is to create a Web
service and Web service client from the source code. This style of Web
service generation is known as a bottom-up Web service creation. To do
this, right-click the Java class and select Web Services =>
Create Web service, as shown in Figure 10.
Figure 10. Create a Web service
- Fill in the Web service details as shown in Figure 11, being careful
with the slide bars.
Figure 11. Enter Web services details
- For the Test service, click the Server link under
Configuration and select the new WebSphere Application
Server V7 server you created earlier, as shown in Figure 12, then
click OK. Do the same for the Test client, then click
Figure 12. Select server and runtime for deployment
- On the next screen, make sure that Generate WSDL file into the
project is checked and click Finish, as shown in Figure
Figure 13. Generate WSDL file into the project
You've now generated a JAX-WS Web service from a Java class, and also a corresponding JAX-WS client (along with some JSP pages) to invoke this Web service.
To test the service, use the Web Services Test Client tab that is
now open. From here you can invoke the operations on the Bank Web service.
In Figure 14, you can see that we've invoked the
checkBalance operation with an argument of 0.
This has returned a result of 100.
Figure 14. checkBalance operation test
Along with this result, you'll see the following SystemOut message in the server console indicating that the service has been invoked:
[09/12/08 10:39:25:140 GMT] 0000003f SystemOut O checkBalance: 0
TCP/IP Monitor was enabled for this server when you created the Web service and checked Monitor the Web service, as shown in Figure 11. TCP/IP Monitor should have been enabled for this server. If you click the TCP/IP Monitor tab, you can see the underlying SOAP exchange. If the TCP/IP Monitor is not open, click Window =>Show View => Other, then find and open the TCP/IP Monitor view, as shown in Figure 15.
Figure 15. TCP/IP Monitor view
Enable a JAX-WS Web service provider and Web service client for WS-RM
Once you've created a JAX-WS Web service and Web service client, you can
enable them to exchange SOAP messages using WS-RM. In Application Server
V7 this means defining and attaching a policy set (a JAX-WS
configuration) that includes a WS-RM
policy type. Application Server Version 7 comes
with policy sets that have predefined WS-RM policy types. Our Web service
client will use one of these. The Bank Web service provider will use a
custom policy set with an WS-RM policy type that has properties set
manually. Before working with the policy sets, let's look at the WS-RM
properties you need to consider when defining an WS-RM policy type.
There are three attributes to consider when creating an WS-RM policy type:
RM specification level: Application Server V7 supports versions
1.0 and 1.1 of the WS-RM specification. Use
where possible. The Application Server V7 WS-RM 1.1 implementation
for all synchronous protocols. This specification defines a new protocol
message that enables connections to be made between a WS-RM client and
WS-RM provider so that messages trapped on the provider side can be sent
back to the client. The WS-RM 1.0 implementation does not support the
makeConnection specification, but uses a
different mechanism whereby the application messages are resent in order
to create connections. This second method can be less efficient because
makeConnection protocol messages are of
negligible size, whereas the sequence messages might not be.
Inorder delivery: If selected, Inorder delivery forces the WS-RM source or provider to deliver messages to the JAX-WS client or service in the order in which they were sent. One thing to be aware of with this option is that you can run up large backlogs of work that can take time to reduce (RM source or providers receive messages that stack up while waiting for redelivery of a previous message).
RM Quality of Service (QoS): The WS-RM policy type offers three storage options for SOAP messages:
- UnManagedNonPersistent: This configuration is the simplest to configure, but cannot be used in a clustered or z/OS environment, and stored messages cannot survive an application server restart. However, messages will survive application restarts and network failures.
- ManagedNonPersistent: This configuration allows clustering and is compatible with application servers running in a z/OS environment. This QoS requires slightly more set-up as you have to configure a messaging engine and assign an WS-RM binding to your service or application to point at this messaging engine. With this quality of service, WS-RM can survive network failures, application restarts and application server restarts, but not messaging engine restarts. Note: If your messaging engine is part of the application server that is being restarted, it will restart also.
- ManagedPersistent: This configuration is identical to
ManagedNonPersistent but has the added ability to survive a messaging
Configure the ManagedPersistent QoS on the client or provider (generally both) if you consider the SOAP messages exchanged to be of significant value. An example might be a banking application, where exchanged messages might represent the transfer of large sums of money, and therefore the possibility of losing a SOAP message is not acceptable. The disadvantage to this option is that performance is reduced compared to using an UnManagedNonPersistent quality of service. A final consideration is that a ManagedPersistent or ManagedNonPersistent QoS is not supported for clients running in JVMs outside of the server, such as in the client container or in thin clients.
A few other things to note:
- In Application Server V7, you can attach a policy set with an WS-RM policy type to an application or specific service within an application, but you cannot attach a policy set that contains an WS-RM policy type to a specific operation within a service. To achieve this you would have to split your operations into separate services.
- In Application Server V7 you can attach different policy sets with different WS-RM policy types to different services within the same application, but they must use the same level of WS-RM quality of service (UnmanagedNonPersistent, ManagedNonPersistent or ManagedPersistent).
Now that you understand the configuration options to consider when applying WS-RM, we'll walk through the process of making our Web service client talk reliably to the bank Web service. We'll start by applying a prepackaged WS-RM policy set with an UnManagedNonPersistent WS-RM QoS, to the Web service client, using the Application Developer workspace. Then we'll move on to applying a homegrown WS-RM policy set with a ManagedPersistent WS-RM QoS to the Web service provider, using the administrative console.
Create a policy set with a WS-RM policy type
The first step is to create a policy set that includes a WS-RM policy type. To do this, complete the following steps.
- To launch the administrative console, right-click the Application
Server V7 runtime and click Administration => Run
administrative console, as shown in Figure 16.
Figure 16. Open administrative console
- Select Services => Policy Sets => Application policy
sets, as shown in Figure 17. You'll see some of the most
common policy set configurations are already available. For the Bank
example, we want to import a less common configuration. To do this,
click Import and select default repository.
Figure 17. Import application policy set
- Select WSReliableMessaging default from the list, as shown in
Figure 18. You might want to take a look at the policy set before
importing it. If you drill down into the Reliable Messaging policy
type within the policy set, you'll see that it's using an
UnManagedNonPersistent WS-RM QoS.
Figure 18. Select the WSReliableMessaging default policy set
- Save these changes.
Export the policy set
The next step is to export the policy set from Application Server so that you can import it into Application Developer.
- From Services => Policy Sets, select
WSReliableMessaging default and then click Export. Save the
resulting ZIP file somewhere convenient, as shown in Figure 19.
Figure 19. Export policy set
- In Application Developer, select File => Import, then
select Web Services => WebSphere Policy Sets, as shown
in Figure 20.
Figure 20. Select WebSphere Policy Sets
- Navigate to the exported policy set and import it.
Apply the policy set to the Web service client
Now you can apply the policy set to the Web service client using Application Developer.
- Switch to the Web perspective and select WebServiceProjectClient
=> Services, then right-click the Clients
endpoint and select Manage Policy Set Attachment, as shown in
Figure 21. Select Manage Policy Set Attachment
- Select the options as shown in Figure 22 and click Next.
Figure 22. Select service to configure
- Click Add under Application, as shown in Figure 23.
Figure 23. Click Add to add policy set attachments
- For Policy Set, select WSReliableMessaging default, as
shown in Figure 24.
Figure 24. Select WSReliableMessaging default
Apply the policy set to the Bank Web service provider
The next step is to apply a WS-RM policy set to the Bank Web service provider. You can repeat the previous four steps to apply the default WS-RM policy set to the Bank Web service provider. Alternatively, you can complete the following steps using the Application Server administrative console to apply a managed WS-RM policy set instead. The difference is that the following steps show how to do two additional things: edit a policy set and configure a service integration bus, because a bus is required when using a managed WS-RM policy set.
- Open up the administrative console in Application Developer, if it
isn't already open, by right-clicking WebSphere Application Server
v7.0 runtime and selecting Administration => Run
administrative console, as shown in Figure 25.
Figure 25. Open the administrative console
- Select Services => Policy sets => Application policy
sets and click New, as shown in Figure 26.
Figure 26. Create new policy set
- In the next dialog, you can define the properties of your policy set,
such as the name and what policy types you would like to add. For this
example, you need to add both the WS-ReliableMessaging and
WS-Addressing policy types. The WS-Addressing policy type is required
if you are to use an asynchronous message exchange protocol.
Figure 27. Configure the custom policy set
- First select the WS-ReliableMessaging policy type so that you can
configure the WS-ReliableMessaging attributes. Specify the attributes
as shown in Figure 27, then Apply and Save the changes
to the policy set.
Figure 28. Specify WS-ReliableMessaging policy type attributes
- Next you need to configure a bus and messaging engine, because the
WS-ReliableMessaging policy type is configured to use one of the
managed WS-RM QoS's. This is where WS-RM will store messages and
sequence state. You'll learn how how to configure this as part of the
WS-RM binding shortly.
To create the bus, select Service integration => Buses and click New, as shown in Figue 29.
Figure 29. Create a new bus
- Give your bus the name
ReliableMessagingBus, click Next, then click Finish.
- The new bus is added, as shown in Figure 30. Click OK, then
Figure 30. New bus
- Select ReliableMessagingBus, then click Bus members under Topology/.
- On the Bus Members dialog, do the following:
- Click Add.
- Accept the default Server and click Next . (Note: If you were in a cluster and you wanted your ReliableMessagingBus to be accessible across the cluster, you'd need to select the cluster as the bus member.)
- Accept the default File Store and click Next.
- Accept the default configuration for the File Store and click Next.
- Accept the default performance parameters and click Next.
- Click Finish.
- Save the changes. You'll see the new bus member, as shown in Figure
31. Note that the bus member name is likely to be different, as your
server will running on your own node.
Figure 31. New bus member
- Now select the bus member and you'll see the messaging engine that has
been created, as shown in Figure 32. Note that the messaging engine
name is likely to be different as your server will be running on your
Figure 32. New messaging engine
You can see that the status is currently unavailable, because you need to restart the server for changes to take effect. We'll do this after we've completed the rest of the steps.
- Now you can go ahead and attach the new policy set to the Bank Web
service. To do this, select Services => Service
providers and select BankService, as shown in Figure
Figure 33. Select BankService
- Now attach the new policy set
WS-RM_DevWorks_PSby checking BankService and selecting the new policy set from the list, as shown in Figure 34. Then click Attach Policy Set and click Save to save the updates.
Figure 34. Attach the policy set
Assign WS-RM binding
Now that you've attached a managed WS-RM policy set to the BankService, you'll need to make sure there is an WS-RM binding assigned. A default binding is already assigned, so rather than create a new binding and assign that, we'll update the WS-RM policy type binding that is part of the default binding.
- Select Services => Policy sets => Default policy set
bindings. As you can see in Figure 35, the default service
provider binding is Provider sample, so you'll need to edit
Figure 35. Select default policy set binding
- To edit the provider sample binding, select Services =>
Policy sets => General provider policy set bindings,
and click Provider sample, as shown in Figure 36.
Figure 36. Provider sample
- Next select the WS-ReliableMessaging policy binding, and select the
bus name and messaging engine that you created earlier, as shown in
Figure 37. Note: The messaging engine is specific to your set-up and
won't necessarily have the same name as the one shown below.
Figure 37. WS-ReliableMessaging policy binding
- Click Apply and Save.
Restart and test the WS-RM Bank service
We're nearly ready to try our WS-RM enabled Bank service, but before we do that we'll need to restart the server.
- Right-click the WebSphere Application Server v7.0 runtime and click Restart.
- Once the server has restarted, open the Web Services Test
Client, and click Update to re-invoke the operations,
as shown in Figure 38.
Figure 38. Re invoke the operation
- If you re-invoke the
checkBalanceoperation the result will still be 100, but if you look at the TCP/IP Monitor, shown in Figure 39, you'll see that rather than the a single request/response communication, you can see four. Looking through these communications, you'll be able to see the WS-RM flow described earlier on in this article.
Figure 39. TCP/IP Monitor view
The Reliable Messaging offerings in WebSphere Application Server V7 allow JAX-WS application developers to concentrate on coding business logic rather than application-specific reliability. Using a hands-on approach, this article has shown you how to take advantage of this offering using a supplied JAX-WS application called Bank. We've discussed the WS-RM attributes you should consider when configuring WS-RM in WebSphere Application Server V7. You should now be able to configure WS-RM for your own applications and services.
Part 2 in this series will take you through the implementation of a scalable and highly available clustered server configuration to support WS-RM. You'll learn the configuration steps and best practices involved in setting up a clustered topology to which you can deploy and configure a JAX-WS application to receive WS-RM messages.
|Bank.java source code||Bank.java||1KB|
- Rational Application Developer V7 Programming Guide: This Redbook highlights the features and tooling included with Rational Application Developer V7.0. Many of the chapters provide working examples that demonstrate how to use the tooling to develop applications, as well as achieve the benefits of visual and rapid application development.
- Web Services Feature Pack for WebSphere Application Server V6.1: This Redbooks includes an extensive interoperability example using Reliable and Secure Web services with the Windows Communications Foundation. There are also lots of examples showing you how to use the feature pack, use the new Web services policy sets, and code Java Web services using the JAX-WS specification.
- Java Web services: JAXB and JAX-WS in Axis2 (developerWorks, 2009): Apache Axis2 supports a range of data-binding technologies, including the official Java™ standard, JAXB 2.x. Axis2 also supports the Java standard for Web service configuration, JAX-WS 2.x, as an alternative to its own custom configuration technique. Dennis Sosnoski continues his Java Web services column series by demonstrating how you can use each of these Java standards with Axis2 and discussing some of the limitations of Axis2's current support for them.
- Web services hints and tips: JAX-RPC versus JAX-WS, Part 1 (developerWorks, 2006): JAX-WS 2.0 is the successor to JAX-RPC 1.1. This article introduces a series that compares these two Java Web services programming models.
- WS-Reliable Messaging V1.1 specification