Service Oriented Architecture with WSE 2.0

 

Service Oriented Architecture (SOA) is a distributed architecture design pattern. This article is the first in a series that demonstrates how to implement a SOA using Microsoft's Web Service Extensions (WSE) 2.0 for .NET.  This initial article explains what a SOA is, and why a SOA is usually implemented as a Web service. Then the article will explain how Microsoft WSE 2.0 is designed to help you build a SOA based application, and how it differs from Microsoft's traditional ASMX technology. The article concludes with a brief description of the case study. Subsequent articles will use this case study to discuss the details of how the WSE classes relate to the new and proposed Web service specifications, and how they can be used to implement a SOA.

 

What is a Service Oriented Architecture?

 

We live in an asynchronous, distributed world. To align modern business applications with the appropriate technology choices, they must reflect this type of world. Think about the last time you went to a sandwich shop to place an order.

 

Order clerk:      What kind of sandwich do you want?

Customer:         I want a tuna, with mustard and roasted red peppers, on focaccia bread.

Order clerk:      What kind of mustard do you want: Dijon or regular?

Customer:         Let me think for a second… 

 

Order clerk moves on to the next customer and then returns

 

Customer:         I want regular.

Order clerk:      How would you like to pay for this?

Customer:         Here is my credit card.

Order clerk:      Ok sign this, here is your receipt, your number is 51… next...

Sandwich clerk: Number 51, we just ran out of focaccia bread, do you want French or whole wheat?

Customer:         If you do not have focaccia bread, I want my money back.

 

Customer gets back in order line

 

Order clerk:      Give me your credit card and we will give  you a charge back.

Customer:         Never mind… I want the sandwich with whole wheat.

 

The order is changed and resubmitted to the sandwich queue.

 

You engaged in a series of asynchronous messages that were not composed of simple programming types. These messages proceed through several service providers, and the order of the messages is not fixed to one flow pattern. Each message interaction is a discrete transaction. It would be hopelessly slow, and would not scale well, if you had one transaction open (including the credit card charge) until the sandwich was made. Instead you have compensating transactions such as credit card charge backs, and resubmission of the sandwich order, to fix problems. Also, services do not always have the most up to date information about dynamically changing information. The order clerk does not know the bread inventory.

 

Each service is independent. You can change the payment procedure, and improve the process of making sandwiches independently. Services interact through explicit, well-defined protocols. The services do not share data. You interact with these services based on policy: which credit cards are accepted, what ids are acceptable if personal checks are accepted, the hours that the store is open.

 

Our sandwich shop is an example of a real world business process that can be modeled with the Service Oriented Architecture (SOA), a distributed computer architecture design pattern. SOA is neither an architecture nor an implementation. It describes how a collection of loosely coupled business services can work together.

 

It is not a new concept. Business needs, however, have made it imperative for this approach to be used, and the state of technology has made this approach simpler to implement. With loosely coupled business services, it becomes easier to reuse existing services in new applications by integrating them together. Within one enterprise, this saves time and money. Under other circumstances, such as mergers and acquisitions, legacy systems, and outside vendors, integrating together different hardware and software platforms becomes mandatory.

 

Services, Objects, and XML Documents

 

We have heard the reuse argument before with objects, and large scale object reuse was rarely achieved. What is different this time? Let's look at the difference between services and objects.

 

Objects live in a single execution environment. Whether they are Java objects, C++ objects, or .NET objects they are typed and live through object references and memory addresses. Hence, they are tightly coupled through linking and loading, and do not interact well with objects from another execution environment. One of the great downfalls of both DCOM and CORBA was the lack of scalability due to the need to manage the lifetime of distributed objects. Lifetime management was necessary because state was stored with the objects, and hence had to be maintained. In addition, objects rarely corresponded directly with business processes.

 

With a service, XML documents are passed as messages. These service/message combinations correspond to business interactions. The interface, or contract, between a service and its user (client program or another service) is the order and contents of the message. The XML message structure is defined through some schema language such as XML Schema. Since there is no dependence on a specific execution environment (such as with objects), services function well in a heterogeneous environment. The services scale well because state is usually stored in the message, not the service. With interaction through messages, without sharing of code and data, services are loosely coupled. Loose coupling allows for independent evolution and deployment.  

 

Since there can be long delays between an initial message and a reply, services work asynchronously. When you submit a loan application, you do not get an answer right away. Real life is not "always connected".  Transactions should span only one service. Transactions should not span multiple long running services with a two-phase commit where you cannot guarantee a connection. If you must undo a transaction, you start a compensating one. In the sandwich shop example, you issue a credit card charge back, or resubmit an order. The autonomous nature of services is also important when third party security (such as federated identities) is used, or services need to control the order in which messages are processed based on priority or some other criterion.

 

With these characteristics, services are a more natural building block for an architecture designed to model real world business. You can wrap existing applications as services, and reuse them. Not every application needs to be built from scratch. This saves companies time and money. Objects, of course, can be used to implement services. Reconfiguring services allows you to adapt to changing business needs. One of the more interesting parts of the SOA pattern is that the User Interface is not present. Only if a program that interacts with a service interacts with a user, will that program will have a UI. The SOA pattern itself, however, only sees message flows between services.

 

SOA and Web Services

 

Nothing in the SOA design pattern requires the use of a Web service. You could use any distributed object technology. Web services, however, very naturally lend themselves to loose coupling, and connections between heterogeneous environments through SOAP messages. In addition, the Web service community is already in the process of developing specifications that solve many of the key problems associated with such heterogeneous messaging. With these advantages of interoperability, Web services are a natural implementation technology for a SOA that crosses departmental, or enterprise boundaries in a business. Some specifications such as WS-Security and SOAP have had their initial releases, others such as WS-Addressing and WSDL are being actively worked on.

 

Web Services Enhancements

 

If Microsoft already as has ASP.NET Web service (ASMX) technology, why does it need the Web Services Enhancement (WSE) technology? As will be discussed in the next section, the new specifications use the headers in a SOAP message. While ASP.NET Web services allow you to work with SOAP headers, they do not have classes that directly implement these specifications. At a minimum, WSE extends ASP.NET technology. As I will demonstrate in a future article in the series, ASP.NET Web services can use the WSE classes for some of these specifications through the Current property of the RequestSoapContext and ResponseSoapContext classes.

 

Fundamentally, however, ASMX gives a false view of the SOA world. ASP.NET Web services are based on HTTP and its synchronous request/response protocol. Using the WebMethod attribute on a method encourages programmers to think in terms of synchronous remote procedure calls (RPC) with environment specific programming constructs that may not be interoperable. SOA requires more flexible message exchange patterns. SOA does not preclude the use of synchronous two-way messaging. Nonetheless, one-way, broadcast, publish and subscribe, and callback messaging patterns are additional ways to transmit business documents. WSE has classes such as SoapSender and SoapReceiver that allow you to send and receive more flexible message exchange patterns. Out of the box, these classes work with HTTP and TCP.

 

The ASMX programming model encourages the view of Web services as a client / server interaction. In the real world, there can be intermediaries between the initiator of a request, and the ultimate recipient. Consider a client that wants to buy a widget. The request is first sent to a Purchasing Web service that checks to see if the request comes from a known client, with all the correct address and cost information. The request is then routed to a Credit Validation service to make sure the client can pay for the order. The order is then sent to an Accounting service to log the order. Finally the Shipping service (in conjunction with the Inventory service) ships the widget to the customer. The message transports and security requirements among these different services may be different. WSE makes it a lot easier to construct these kinds of Web services based on the SOA design pattern. WSE also makes it easier to work directly with the header and body of a SOAP message as XML.

 

Microsoft intends to ship new WSE functionality as the new specifications emerge without being constrained by the .NET Framework release schedule. Given the nature of these changes, however, backwards compatibility may not always be possible because of changes to the specifications.

 

WSE Architecture

 

Before using WSE to solve particular problems associated with the SOA design pattern, let us look at the underlying WSE architecture. The first step is to examine how a SOAP message is processed by WSE, the next step is to examine some of the key WSE classes.

 

A SOAP message consists of three XML elements. A parent Envelope element, and two children: header and body. The header element is optional, but must come before the body element. The body element is where the message is placed. The header element can be composed of several child elements called header blocks. Header blocks are used by the various Web service specifications to implement their protocols. Listing 1 has a sample simplified SOAP message. The namespace attributes have been omitted for clarity.

 

Listing 1 SOAP Message with Header Blocks for Security and Addressing Protocols

 

<soap:Envelope>

  <soap:Header>

    <wsa:Action>

      urn:Bank:LoanStatusResponse

    </wsa:Action>

    <wsa:MessageID>

      uuid:8284eed8-c0b3-4748-81af-7e4308834754

    </wsa:MessageID>

    <wsa:RelatesTo>

      uuid:40559d39-b49b-415b-b60a-16f1b15ae392

    </wsa:RelatesTo>

    <wsa:To>

      http://localhost/MP/MortgageProcessor.ashx

    </wsa:To>

    <wsse:Security>

      <wsu:Timestamp wsu:Id="Timestamp-06e0882f

                     -16f4-4595-80a7-d073efebce59">

      <wsu:Created>

         2004-12-20T21:55:10Z

      </wsu:Created>

      <wsu:Expires>

         2004-12-20T22:00:10Z

      </wsu:Expires>

      </wsu:Timestamp>

    </wsse:Security>

  </soap:Header>

  <soap:Body>

     <StatusRequest>

       <messageId>

         uuid:6e9686f6-473b-490f-8a28-dd668375a73a

       </messageId>

       <status>

         Approved

       </status>

     </StatusRequest>

  </soap:Body>

</soap:Envelope>

 

The header blocks with the wsa namespace prefix are used by the WS-Addressing protocol. The destination of the message is in the <To> element. The blocks with the wsse and wsu namespace prefixes are used by the WS-Security protocol.  The expiration date of the message is in the <Expires> element.

 

These header blocks are explained in more detail in subsequent articles. The critical point to understand now is to see that the protocols use these header blocks which are independent of the actual message contained in the Body element. The WSE infrastructure will process these header blocks on incoming messages, and create these header blocks on outgoing messages. If the Body element is encrypted, the WSE infrastructure will modify the Body element on output, or decrypt it on input. This processing is handled by the WSE input or output pipeline. Each pipeline is composed of a series of filters. Each protocol is handled by a particular filter. Some filters, such as the diagnostic trace, have nothing to do with a protocol. You can add your own custom input and output filters if necessary.

 

How do you instruct the WSE filters to do the right thing? The exact details belong to a discussion of the individual specifications, but let us review some of the basic WSE classes in the Microsoft.Web.Services2 namespace.

 

The SoapEnvelope class models the SOAP message. Since this class inherits from XmlDocument, you can manipulate this class as if it were an XML document.  It has three important properties: Body, Header, and Context. The Body and Header properties return XmlElement derived classes that correspond to the body and header of the message. The Context property returns a SoapContext class that represents the information that the filters use to read or create the WS-Security and WS-Addressing protocols. When creating messages you programmatically fill the appropriate fields in the current SoapContext class that correspond to the appropriate protocol settings for your message. When processing messages you read these fields to determine the appropriate actions you might take depending on the protocol settings. As mentioned earlier, some of the processing is handled automatically by the WSE infrastructure.

 

The appropriate transport classes are used to transmit the SoapEnvelope instance as a message. Out of the box, WSE 2.0 ships with the ability to use the HTTP and TCP transport protocols. Note that the message processing architecture is independent of the transport mechanism for the SOAP message. 

 

The WSE 2.0 classes are found within the Microsoft.WebServices2.dll assembly. The installation program adds this assembly to the GAC. Within Visual Studio.NET 2003, a dialog box is available through the Solution Explorer that makes it easy to add a reference to this assembly. Select a project and right mouse click and you will see the following context menu as shown in Figure 1.

 


Figure 1. Project Context Menu

 

Select WSE Settings 2.0 and the dialog box shown in Figure 2 will appear.

 

Figure 2. WSE Settings 2.0 Tool

 

Select the Enable this project for Web Services Enhancements and a reference to the assembly will be made. I will discuss the other tabs on this dialog in future articles.

 

Case Study Interface and Contract Definitions

 

To illustrate the use of WSE in building a SOA, future articles will use a case study of a simplified Mortgage Application system. This system will have 4 parts. A client application in a loan officer’s office will submit the application to the portal of a bank. The bank portal handles the initial phase of all online bank services, isolating the actual services from the outside world. It authenticates the user of the service. If it determines the application request is authorized, it forwards the request onto the appropriate bank service. In our simple example, we will only have the bank’s mortgage processing service. In processing the mortgage, the bank will request a credit report from an external credit reporting agency. Based on the credit report, the bank will approve or disapprove the mortgage application. In addition, the mortgage service will periodically update the portal as to the status of the application. The loan officer can query the portal as to the current status of the request.  While in the real world, people may participate in the process, this example is totally automated to keep the code simple. The application process itself has been greatly simplified for pedagogical purposes.

 

The messages move among the services as follows:

From the Client to Bank Portal: one-way request with Mortgage Application (no response message).

From the Client to Bank Portal: synchronous request / response for Mortgage Application status

From the Bank Portal to the Mortgage Processor: request (no response) with authorized Mortgage Application

From the Mortgage Processor to the Bank Portal: asynchronous responses (callbacks) with application status

From the Mortgage Processor to the Credit Agency: request (no response) for credit information

From the Credit Agency to the Mortgage Processor: asynchronous response (callback) with credit information

 

The next step is to define the contracts for the three services. These contracts will be used to define the interactions among the services, and between the bank portal service and the client application. To avoid dependencies on any application platform, or particular transport mechanism, XML Schema will be used to define the XML documents exchanged between the services. We will use these schemas, included with this article, in subsequent articles when we develop our case study. The mortgage application request message for both the Bank Portal and the Mortgage Processor is defined in MortgageApplication.xsd. The credit request to the Credit Agency and its response are defined in CreditReportRequest.xsd. The various status messages are defined in Status.xsd. Various shared data types are defined in BankExampleBaseTypes.xsd.

 

Conclusion

 

You now understand why Microsoft developed the Web Services Enhancements classes.  The asynchronous, distributed nature of the next generation of Web services requires a new programming paradigm.  The overview in this article will facilitate your understanding of future articles where WSE classes will help implement a case study of a Service Oriented Architecture.

 

Michael Stiefel is the principal of Reliable Software, Inc. where he does training and consulting in Microsoft technologies for companies ranging from startups to the Fortune 500. He is the co-author of “Application Development Using C# and .NET” published by Prentice-Hall. Go to www.reliablesoftware.com for more information about his development work and the training courses he offers.

 


All Content (c) 2000 - 2014 Reliable Software, Inc. All rights reserved.