Introducing Web Services, and Implementing the Service-Oriented Architecture


From a high level, the Web Service architecture is a textbook implementation of the Service-Oriented Architecture pattern. It provides a directory ”most often Universal Description, Discovery, and Integration (UDDI) ”service implementations , and clients to the services. All components communicate via an XML-based protocol to publish, locate, and communicate. Figure 3-3 shows the overall Web Service architecture.

click to expand
Figure 3-3: Web Service conceptual design

In reality, at the next level of architectural detail, you find that the Web Service architecture is simply a layer on top of the underlying service implementation architecture. A client interacts with Web Services over an XML communication mechanism, SOAP. The Web Service implementation translates the request into the service implementation's architecture. In this case, the Web Service implementation talks to a service implementation over a Java protocol. In this sense, a service actually consists of two parts : the service interaction implementation and the service behavior implementation (see Figure 3-4).

click to expand
Figure 3-4: Two-part service implementation
Note  

No part of the Web Service specification mandates that you write service implementations in Java. The service implementation could just as easily be in C or Perl, as long as the Web Service knows how to communicate with the service implementation over the native protocols of the language.

Each major component of the Web Service architecture uses this two-part pattern implementation; the next chapter discusses a pattern for this type of implementation: the architecture adapter. Even the directory holds conversations using the XML-based communication protocol. The implementation of UDDI translates the XML-based message to the native implementation of the UDDI directory.

For the remainder of this chapter, you will see a simple service implementation and its conversion to a first-class Web Service. The simple service implementation is a single business object, a company with a name attribute. The Java implementation of the service is a JavaBean with get and set methods for the name attribute, as shown in Listing 3-1.

Listing 3-1: A Simple Service Implementation
start example
 public class SmallCompanyImpl {     public String getName(){              return name;         }     public void setName(String name){              this.name = name;         }     private String name="P.T. Monday Coffee Company"; } 
end example
 

Notice there is no knowledge of Web Services in the Java class itself. With this service implementation completed, you have to deploy it to a Web Service implementation that handles the Web Service calls for you and turns them into calls to an instance of your Java class. After that, you can communicate with the service using SOAP. You can also publish your service to a directory to make it available for others to use. You will briefly see these pieces of Web Services to help clarify the environment and the pattern.

Deploying a Service

Consider that Web Services deal with how services communicate and that there is no standard underlying language for implementing a service. I chose to implement the SmallCompanyImpl class using the Java language; this class forms the behavior of a Web Service. Service implementations, such as SmallCompanyImpl , do not typically process messages directly; instead, they rely on the Web Service environment, such as Apache Axis, to route the message to the service implementation and return a response in the proper format to the client. Depending on the Web Service platform you choose, there will be a variety of different ways to deploy your service.

In this section, and throughout the book, you will rely on the Apache Axis service that plugs into the Apache Tomcat servlet engine. The Apache tools are nice because they are both free and widely used in the field.

You will concentrate on a very simple example of deployment to the Apache Axis environment. In the next chapter, you will spend much more time learning how the adaptation of a Java class to the Web Service's environment occurs.

Deploying Services Using Apache Axis

Tools in Apache Axis simplify the deployment and usage of your service implementation. As long as you can describe how to connect to your service, Apache Axis generates the half of your service that communicates through the Web Service environment. After compiling the SmallCompanyImpl class using the Java compiler, you copy it to the Axis deployment directories.

Next, you supply Axis with enough information so that it can route requests to an instance of the class. For Axis, you build a Web Service Deployment Descriptor (WSDD) that gives Axis the necessary information. Listing 3-2 illustrates a simple WSDD file.

Listing 3-2: Apache Axis WSDD
start example
 <service name="SmallCompanyImpl" provider="java:RPC">   <parameter name="className"      value="com.servicefoundry.books.webservices.entities.SmallCompanyImpl"/>   <parameter name="scope" value="Application"/>   <parameter name="allowedMethods" value="getName setName"/> </service> 
end example
 

In the WSDD file, Axis requires several critical pieces:

  • The first line of Listing 3-2 contains the service name and the provider that Axis should use to hold a conversation with the service implementation. A provider is the Axis mechanism for holding a conversation with a service implementation.

  • The second line contains the Java class name for your service implementation.

  • The third line contains the lifecycle of the service implementation. By specifying Application , you tell Axis that any Web Service access for this class can use this single service implementation; other values allow only a session to use the object instance or to create a new instance for each request.

  • The final parameter line in the WSDD file identifies what methods Axis will elevate through the Web Service interface.

With this information, Axis can properly route SOAP requests through a series of handlers and into an instance of your service implementation. After Axis calls the requested operation on your service implementation, the method response returns through the handler chain until it reaches the client that invoked the service. You submit this information to the Axis administration client via a simple call to the administration client shown here:

 java org.apache.axis.client.AdminClient deploy.wsdd 

At this point, the service is available for clients to access as a Web Service.

Every Web Service platform is different with respect to how to deploy a service and the required information to accompany the service registration. The important thing to realize is that tools will ease the adoption of a service implementation into a Web Service platform.

Using the Web Services Description Language (WSDL)

Web Services Description Language (WSDL) describes the interfaces and binding mechanisms for particular services. WSDL is an XML-based language similar in nature to CORBA's Interface Description Language (IDL). It is a platform-neutral and language-neutral mechanism for describing the interface and the location of a particular Web Service. There is a subtle difference in a WSDL from a common interface language; the WSDL contains the network address information for the Web Service as well as the protocol used to access the service.

With Apache Axis, as well as with most Web Service platforms, the Web Service platform generates WSDL files from the service implementation interface and input to a tool. This is a bit different, as you would expect the interface to be a prerequisite to deploying a service implementation. WSDL files are important not so much for describing a runtime interface to a service but for allowing potential clients to generate and understand how to package data to send to the service. Most often, a Web Service platform tool will consume the WSDL file. For example, the WSDL2Java tool in Apache Axis reads a WSDL file and builds aproxy to a remote service for Java clients to use.

Another scenario is the case where you would like to implement a service implementation that adheres to a particular standardized interface, given to you in a WSDL file. In this scenario, you use a tool, WSDL2Java again in Axis, to generate stub implementation in the language you want to use for the service implementation.

WSDL files are large and complex, even for the simplest services. A WSDL file consists of data type definitions, message descriptions, port types, binding descriptions, and the service type and location. The data type definitions use XML Schema to define any data types that are not native to Web Services. For your SmallCompanyImpl class, all data types are native to Web Services, so there is no data type section.

Message descriptions define the documents that Web Services pass in a network to make a request and return a response. For each method exposed on a class there is request and response message. For the getName method on the SmallCompanyImpl , the request and response pair is relatively simple. Recall that the getName request uses no parameters, and the response returns a String to the caller. The fragment of WSDL in Listing 3-3 shows the pair of getName message definitions in the WSDL file.

Listing 3-3: WSDL Message Definition
start example
 <wsdl:message name="getNameResponse">    <wsdl:part name="return" type="xsd:string" /> </wsdl:message> <wsdl:message name="getNameRequest"/> 
end example
 

Port types describe the operations offered by a service. The operations are similar to the methods offered by a service and put in terms of the messages (defined previously) that facilitate the operation. The getName operation on your Web Service consists of the request and response messages defined in the message definition section of the WSDL, shown in Listing 3-4.

Listing 3-4: WSDL Port Type Definition
start example
 <wsdl:portType name="SmallCompanyImpl">    <wsdl:operation name="getName">       <wsdl:input message="intf:getNameRequest" name="getNameRequest"/>       <wsdl:output message="intf:getNameResponse" name="getNameResponse"/>    </wsdl:operation> </wsdl:portType> 
end example
 

The binding descriptions for a service move the generic interface described thus far to an implementation level of how a particular Web Service will accept messages intended for the interface. For example, some of the binding information about getName includes treating the request as a Remote Procedure Call (RPC) and using SOAP messages transported across HTTP to access the service. Further, a binding will give specific encoding styles for requests and responses. This expansion of the interface to binding information will give service callers no room for ambiguity about how to call particular operations on the service. Listing 3-5 shows the binding information for your service.

Listing 3-5: WSDL Binding Information
start example
 <wsdl:binding name="SmallCompanyImplSoapBinding"          type="intf:SmallCompanyImpl">    <wsdlsoap:binding style="rpc"          transport="http://schemas.xmlsoap.org/soap/http" />          <wsdl:operation name="getName">             <wsdlsoap:operation soapAction=""/>             <wsdl:input name="getNameRequest">                  <wsdlsoap:body                           encodingStyle="..."                           namespace="..."                           use="encoded" />             </wsdl:input>             <wsdl:output name="getNameResponse">                 <wsdlsoap:body                          encodingStyle="..."                          namespace="..."                          use="encoded" />             </wsdl:output>        </wsdl:operation>    </wsdl:binding> 
end example
 

Finally, the WSDL file contains information about how to access a particular service, shown in Listing 3-6. Starting from this point in the file, you could chain all the way back up through the file to obtain the operations on a service as well as the semantics for how to have a conversation with the service.

Listing 3-6: WSDL Service Definition
start example
 <wsdl:service name="SmallCompanyImplService">    <wsdl:port         binding="intf:SmallCompanyImplSoapBinding"         name="SmallCompanyImpl">       <wsdlsoap:address         location="http://localhost:8080/axis/services/SmallCompanyImpl" />    </wsdl:port> </wsdl:service> 
end example
 

The casual reader receives no joy from reading WSDL files. They are complex and, frequently, very large. Luckily, tools consume the WSDL, not humans . In the next chapter, you will see how WSDL facilitate the creation of architecture adapters, the portion of the Web Service that translates the Web Service request to the Java method call, for clients to access a service.

Communicating Using Simple Object Access Protocol (SOAP)

SOAP is an XML-based communication protocol that fulfills the requirement of implementation independence for communication between services and clients. Any platform and language that can build an XML document or translate an XML document to its own mechanism for fulfilling functionality can participate in Web Service implementations. The ubiquitousness of XML capabilities in computing languages makes participation in the Web Service implementations possible from almost every platform and language, including Perl, C, C#, Java, Python, and more.

There are two considerations to keep in mind while using Web Services: one is the content of messages passed between services, and the other is how delivery of messages occurs. The level of detail in the following sections is relatively coarse in nature. Although it is important to understand what is happening with SOAP messaging, you will learn in Chapter 4, "Exploring the Architecture Adapter Pattern," that your application will not directly access XML from code. Instead, architecture adapters generated by tools build and send SOAP messages for you.

Understanding SOAP Message Structure

SOAP messages are simple and generic in structure. The key to SOAP, as with any XML-based schema, is that both ends of a conversation understand the content of a particular message. The root node of a SOAP message is the envelope. Within an envelope are a header and a body. The SOAP header contains header blocks that have information about the message, meta- information. Receivers of the message determine how to process the message or what to do with the message by using the meta-information . The SOAP body contains the message itself. The body contains subelements that are the information sent between the sender and the receiver. Both ends of the conversation must understand these subelements. Figure 3-5 shows the encapsulation of the SOAP content within the envelope.

click to expand
Figure 3-5: SOAP message structure

It is important to understand that SOAP messages are simply XML-based documents. The power of SOAP is not in its ability to represent an RPC and subsequently make that call; rather, the power is in the versatility of the document. SOAP message deliveries typically go through HTTP, but even Simple Mail Transfer Protocol (SMTP) or any other network protocols can carry SOAP documents for processing by the destination.

Understanding SOAP Message Content

Clients use SOAP to make requests of Web Services. Web Services then return data to the caller using SOAP. A Web Service call consists of two separate SOAP documents, a request document and a response document, as defined by the WSDL file.

Recall that the request message for the getName operation on the SmallCompanyImpl Web Service did not contain any parameters but does have a response. The SOAP request message, shown in Listing 3-7, contains only information about the operation, so the body of the SOAP message is simple, a getName tag.

Listing 3-7: SOAP Request Message
start example
 <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope      SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"      xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"      xmlns:xsd="http://www.w3.org/2001/XMLSchema"      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"      xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">   <SOAP-ENV:Body>    <getName/>   </SOAP-ENV:Body>  </SOAP-ENV:Envelope> 
end example
 

Upon receiving the SOAP request message, Apache Axis instantiates SmallCompanyImpl and converts the SOAP message to the getName Java method call on SmallCompanyImpl . Next, Axis receives a response from the method and converts the response back into a SOAP response message that Axis returns to the caller. The response message is slightly more complex because it is returning a String to the caller that contains the name of the company. The body to the SOAP message, shown in Listing 3-8, conforms to the WSDL interface described earlier. The body identifies the getNameResponse message, and it contains the getNameReturn data of type String .

Listing 3-8: SOAP Response Message
start example
 <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope    xmlns:soapenv=http://schemas.xmlsoap.org/soap/envelope/    xmlns:xsd=http://www.w3.org/2001/XMLSchema    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">    <soapenv:Body>       <getNameResponse              soapenv:encodingStyle=              "http://schemas.xmlsoap.org/soap/encoding/">                   <getNameReturn xsi:type="xsd:string">                       P.T. Monday Coffee Company                   </getNameReturn>       </getNameResponse>    </soapenv:Body> </soapenv:Envelope> 
end example
 

The most important aspect of the SOAP communication in Listing 3-8 is the flexibility that this paradigm offers. The document driven concept allows requests and responses to be delivered in any way that a service provider can handle, SMTP, HTTP, socket connections, and so on.

Delivering the Request Message to the Proper Location

With the flexibility of document delivery, it is important to understand that creation of the request document is separate from the delivery of the request document. Looking one more time at the WSDL file, you will see that there is an end point in the service definition that you can deliver the document to for each port defined in the WSDL. For the request document in Listing 3-8, you will deliver it to the address defined in the WSDL document:

 <wsdlsoap:address location="http://localhost:8080/axis/services/SmallCompanyImpl"/> 

Upon delivery of the message to the Uniform Resource Indicator (URI) identified, Axis uses the information from the WSDD file to convert the message to the proper service implementation and gather the response for return to the caller.

Publishing a Service with Universal Description, Discovery, Integration (UDDI)

With the service available via Apache Axis, and your knowledge of how to communicate with the service via SOAP messages, you could go ahead and register it with a directory so that others can locate the service. There are many available public UDDI registries: IBM, HP and Microsoft each have registries you can use. Registration with a directory is a purely optional step when using services. Without using a registry, potential service clients have to be in possession of the interface information for your service, the WSDL file.

Although you can register with a public directory or with no directory at all, there is a third option of deploying a private registry for your own application usage. As lightweight directories become more common, this is becoming a simple and powerful mechanism for maintaining the benefits of service-oriented architecture without the public implementation of services.

If you do want the benefits of registering your services in a registry, there is some basic structural information that you will want to understand about a registry. The Service Directory pattern (described in Chapter 5, "Exploring the Service Directory Pattern") gives more information about service registration and the directory implementation.




Web Service Patterns
Web Services Patterns: Java Edition
ISBN: 1590590848
EAN: 2147483647
Year: 2003
Pages: 190

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net