Specifying what to call: the operation names, their signatures,

Một phần của tài liệu Sams building web services with java making sense of XML SOAP WSDL and UDDI (Trang 268 - 320)

In a typical distributed computing architecture, a tool called an IDL compiler combines the information in an IDL file together with the conventions on how to make invocations

to code-generate the pieces that make the bridge work. The client that wants to invoke operations will use a client proxy (sometimes called a client stub). The proxy has the same interface as the operation provider. It can be used as a local object on the client.

The proxy implementation knows how to encode and marshal the invocation data to the operation provider and how to capture the operation result and return it to the client. The operation provider will wrap its implementation inside a skeleton (sometimes called a server stub) implementation that is code-generated by the IDL compiler. The skeleton knows how to capture the data sent by the proxy and pass it to the actual

implementation. It also knows how to package the result of operations and send it back to the client. Proxies and skeletons are helped by a lot of sophisticated distributed computing middleware. A key part of the story is that proxies and skeletons need not be generated by the same IDL compilers, as long as these compilers are following the same distributed computing conventions. This is the power of IDL—it describes everything that is necessary to make invocation possible in a distributed environment.

DCE IDL specified flat function interfaces. There was no notion of object instance context when making calls. CORBA IDL changed that by adding many important extensions to IDL. CORBA IDL is the de facto IDL standard on non-Microsoft environments. It is also standardized internationally as ISO/IEC 14750.

CORBA IDL is purely declarative; it provides no implementation details. It defines a remote object API concisely (the spec is less than 40 pages long) and covers key issues such as naming, complex type definition, in/out/in-out parameters and exceptions. The syntax is reminiscent of C++ with some additional keywords to cover additional

concepts. The following is a brief example of a CORBA IDL specification for an account and an interest account:

module Accounts {

interface Account {

readonly attribute string number;

readonly attribute float balance;

exception InsuffucientFunds (string detail);

float debit(in float amount) raises (InsufficientFunds);

float credit(in float amount);

}

interface InterestAccount : Account {

readonly attribute float rate;

} }

The information in the IDL file is self-describing and very readable. You can also see that IDL supports the notion of inheritance, which makes it convenient to describe object- oriented distributed systems. In fact, CORBA IDL even supports the notion of multiple interface inheritance as in MyPetTurtle deriving from both Pet and Animal.

In a CORBA-enabled environment, the previous IDL above can be used to invoke the CORBA object via dynamic invocation from a scripting language, generate proxies for client access to the object, generate skeletons for the actual account implementation to be plugged into the CORBA middleware, regardless of its actual implementation

language, and store information about the implementation in an interface repository (a central store of metadata about CORBA components' interfaces).

For various historical reasons, Microsoft used to have two versions of IDL. COM IDL was closely based on DCE IDL, although it lacked some of the advanced features supported by COM. COM ODL had support for these features but was incompatible with COM IDL.

Clearly, that was an odd state of affairs, and Microsoft fixed things a few years ago when it merged the two IDL languages. The following example shows a somewhat simplified version of the Account and InterestAccount interfaces in Microsoft's IDL:

[

object, uuid(E9FF28F4-B79F-469A-B2D9-477FF19873A0), dual ]

interface IAccount : IDispatch {

[propget, id(1)] HRESULT balance([out, retval] float *pVal);

[id(2)] HRESULT debit(in float amount, [out, retval] float *pVal);

[id(3)] HRESULT credit(in float amount, [out, retval] float *pVal);

} ;

[

object, uuid(5B93E296-4FF5-4A6C-A64E-51A7B6C20B6C), dual ]

interface IInterestAccount : IAccount {

[propget, id(1)] HRESULT rate([out, retval] float *pVal);

} ;

[

uuid(22AE9E3F-DC3C-478E-BC00-13A735D57167), version(1.0) ]

library AccountLib {

[

uuid(0D1630F9-C4E0-46A6-BCDF-A9B752DBDD94) ]

coclass Account {

[default] interface IAccount;

} ;

[

uuid(F949F2A1-18C1-4010-A062-6B8DF49D4BCE) ]

coclass InterestAccount {

[default] interface IInterestAccount;

} ; } ;

Needless to say, Microsoft's ODL is not syntax-compatible, or even concept-compatible, with CORBA IDL. For example, metadata about elements is provided via attributes.

Attributes prefix elements using the format [ name(value), ... ]. The convention is to prefix interface names with a capital I. To support dynamic invocation from scripting languages, interfaces must inherit from IDispatch and methods need to identify their location in dynamic dispatch tables with the id attribute. COM does not support

exceptions. Error information is communicated via the return value of a method, which must be an HRESULT (an integer with well-defined error codes). Therefore, the real return value of a method is identified as [out, retval] in the IDL. Finally, COM supports a true separation of interfaces (IAccount and IInterestAccount) from implementations

(Account and InterestAccount). The latter are identified by the coclass keyword in the account library. COM uses UUIDs exclusively to register interfaces and implementation classes under unique names. Apart from these differences, COM objects can be used exactly like CORBA objects.

Programmers working with modern languages, such as Java, C#, and any other .NET Common Language Runtime (CLR) languages have the luxury of being able to engage in distributed computing applications typically without having to worry much about IDL. Has IDL become irrelevant in these cases? Not at all! IDL is not present on the surface, but IDL concepts are working behind the scenes.

Both Java and the CLR languages are fully introspectable. This means that a compiled language component carries complete metadata about itself, such as information about its parent class, properties, methods, and any supported interfaces. This information is sufficient to replace the need for an explicit IDL description of the component. That is why, for example, Java developers can invoke the RMI compiler directly on their object without having to generate IDL first.

However, in the cases where these languages need to interoperate with components built using other programming languages, there is no substitute for IDL. In short, separating interfaces from implementations is the only guaranteed mechanism for ensuring the potential for interoperability across programming languages, platforms, machines, address spaces, memory models and object versions. On the Web, where heterogeneity is the rule, this is more important than ever.

Web Services Definition Language (WSDL)

The Web Services Definition Language (WSDL) is a proposed standard to describe the technical invocation syntax of a Web service. WSDL was submitted to the W3C for standardization by IBM, Microsoft, and others in September 2000. The current version of the specification, WSDL 1.1, is available at http://www.w3.org/TR/wsdl.

A WSDL service description is an XML document conformant to the WSDL schema definition. As we asserted earlier, a WSDL document is not a complete service

description, but rather it covers the lower levels of the service description stack—the raw technical description of the service's interface. WSDL is the IDL for Web services.

Essentially, a WSDL description describes three fundamental properties of a Web service:

• What a service does—the operations (methods) the service provides

• How a service is accessed—details of the data formats and protocols necessary to access the service's operations

• Where a service is located—details of the protocol-specific network address, such as a URL

WSDL Information Model

The WSDL information model takes full advantage of the separation between abstract specifications and concrete implementations of these specifications. This reflects the split between service interface definition (abstract interface) and service implementation definition (concrete endpoint) discussed previously in the context of the service description stack.

The description of the endpoint's capabilities is the abstract interface specification represented in WSDL by a portType . A binding mechanism , represented in WSDL by a binding element, is used to map the abstract definition of the Web service to a specific implementation using a particular messaging protocol, data encoding model, and underlying communication protocol. When the binding is combined with an address where the implementation can be accessed, the abstract endpoint has become a concrete endpoint that service requestors can invoke. This combination is represented by a WSDL port element.

An abstract interface can support any number of operations . An operation is defined by the set of messages that define its interaction pattern.

For the abstract concepts of message and operation, concrete counterparts are specified in the binding element.

Like all good applications of XML, the WSDL schema defines several high level or major elements in the language. Let's take a look at Web service description in terms of the major elements in WSDL:

• portType— A Web service's abstract interface definition (think Java interface definition) where each child operation element defines an abstract method signature.

• message— Defines a set of parameters referred to by the method signatures or operations. A message can be further decomposed into parts (think detailed method parameter format definitions).

• types— Defines the collection of all the data types used in the Web service as referenced by various message part elements (think base data types; think XML).

• binding— Contains details of how the elements in an abstract interface (portType) are converted into a concrete representation in a particular

combination of data formats and protocols (think encoding schemes; think SOAP over HTTP).

• port — Expresses how a binding is deployed at a particular network endpoint (think details about a particular server on a particular network location;

think place where you specify HTTP URL).

• service— A poorly named element. A named collection of ports (think arbitrary bag of Web services, for example, the ports associated with steps in a multistep business transaction).

So the portType (with details from the message and type elements) describes the what of the Web service. The binding element describes the how, and the port and service elements describe the where of the Web service.

Figure 6.3 shows the relationship between these elements in WSDL.

Figure 6.3. The WSDL information model.

The figure shows one possible view of the organization of the WSDL information model.

You can see a clear relationship between the abstract and concrete notions of message and operation as contained in the portType and binding elements. The words in bold on the diagram signify the terms from the WSDL specification. The element names used in WSDL are somewhat confusing because no consistent naming convention allows you to distinguish between abstract and concrete concepts. You simply have to memorize which elements represent abstract concepts and which elements represent concrete concepts.

At first glance, WSDL seems to be quite complicated. Part of this appearance is due to the factoring chosen by the WSDL authors. This complexity feels a lot like the complexity observed with a highly normalized relational data model. Although the same information can be more succinctly expressed, the flexibility that results from the factoring in WSDL is occasionally quite necessary. So, just as you might have learned to cope with

understanding highly normalized relational models, practice with reading WSDL

documents will help you to focus on the important aspects of a Web service description.

Origin of WSDL

WSDL was not the first IDL language for Web services. IBM had developed a language called Network Accessible Service Specification Language (NASSL) to further early internal adoption of SOAP. Meanwhile, Microsoft had developed SOAP Contract Language (SCL), which itself was an evolution of Microsoft's earlier attempt at a SOAP IDL called Service Definition Language.

IBM and Microsoft realized that having competing IDLs in the SOAP space would hinder rapid adoption of Web services. WSDL is the result of hard work and compromise in merging NASSL and SCL. As a result of this merger, a single ubiquitous mechanism describes the interface definition of Web services: WSDL.

To make WSDL a standard, IBM, Microsoft, and several other companies brought it forward to the W3C for standardization.

Elements of the WSDL Language

Let's take a closer look at the elements of a WSDL description. Although we examine these elements in detail, the good news is that you don't have to become an expert in WSDL. The software industry continues to churn out tools to generate WSDL from existing IT assets like COM objects and Enterprise Java Beans (EJBs) and to generate client-side stubs or proxies (access mechanism helper classes) from WSDL on the service requestor side to ease the burden of invoking Web services. Later in this chapter, we will take a closer look at the WSDL tooling available in Axis. However, by reviewing WSDL, you will get a good background in case the tools don't generate exactly the WSDL or Java to fit your particular circumstances.

None of the tools to date support the entire breadth of WSDL features. For some time to come, WSDL descriptions will need to be hand crafted, and client and Web service implementation code will have to be manually developed.

The best way to learn WSDL is to examine a collection of WSDL documents. An excellent registry of WSDL documents can be found at the salcentral Web services brokerage (http://www.salcentral.com) or the xmethods Web site (www.xmethods.net). Go to either of these sites and browse the collection of WSDL documents found there. After a little practice, reading a WSDL document will become as familiar as reading Java code.

So, what does a WSDL description look like? Let's discuss the WSDL language in the context of two WSDL examples. In the following sections, we will discuss how the various elements of the WSDL language are used to describe two of SkatesTown's Web services.

Example WSDL Documents

We will examine the WSDL description for the (relatively simple) priceCheck service provided by SkatesTown. The priceCheck service was added by Al Rosen in response to growing demand from customers to extend the inventoryCheck Web service to include price information as well as availability. You will see in Chapter 7 how this service prepares SkatesTown to participate in dynamic e-marketplaces.

The priceCheck Web service is an extension of the inventoryCheck Web service, allowing a requestor to determine the price of one of SkatesTown's products. The response is a price and the number of units of that item currently available from inventory.

The entire priceCheck WSDL document is shown in Listing 6.1.

Listing 6.1 The priceCheck WSDL Document

<?xml version="1.0"?>

<definitions name="PriceCheck"

targetNamespace="http://www.skatestown.com/services/PriceCheck"

xmlns:pc="http://www.skatestown.com/services/PriceCheck"

xmlns:avail="http://www.skatestown.com/ns/availability"

xmlns:xsd="http://www.w3.org/2001/XMLSchema"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"

xmlns="http://schemas.xmlsoap.org/wsdl/">

<!-- Type definitions -->

<types>

<xsd:schema targetNamespace="http://www.skatestown.com/ns/availability"

xmlns:xsd="http://www.w3.org/2001/XMLSchema">

<xsd:complexType name="availabilityType">

<xsd:sequence>

<xsd:element name="sku" type="xsd:string"/>

<xsd:element name="price" type="xsd:double"/>

<xsd:element name="quantityAvailable" type="xsd:integer"/>

</xsd:sequence>

</xsd:complexType>

</xsd:schema>

</types>

<!-- Message definitions -->

<!-- A PriceCheckRequest is simply an item code (sku) -->

<message name="PriceCheckRequest">

<part name="sku" type="xsd:string"/>

</message>

<!-- A PriceCheckResponse consists of an availability structure, -->

<!-- defined above. -->

<message name="PriceCheckResponse">

<part name="result" type="avail:availabilityType"/>

</message>

<!-- Port type definitions -->

<portType name="PriceCheckPortType">

<operation name="checkPrice">

<input message="pc:PriceCheckRequest"/>

<output message="pc:PriceCheckResponse"/>

</operation>

</portType>

<!-- Binding definitions -->

<binding name="PriceCheckSOAPBinding" type="pc:PriceCheckPortType">

<soap:binding style="rpc"

transport="http://schemas.xmlsoap.org/soap/http"/>

<operation name="checkPrice">

<soap:operation soapAction=""/>

<input>

<soap:body use="encoded"

namespace=

"http://www.skatestown.com/services/PriceCheck"

encodingStyle=

"http://schemas.xmlsoap.org/soap/encoding/"/>

</input>

<output>

<soap:body use="encoded"

namespace=

"http://www.skatestown.com/services/PriceCheck"

encodingStyle=

"http://schemas.xmlsoap.org/soap/encoding/"/>

</output>

</operation>

</binding>

<!-- Service definition -->

<service name="PriceCheckService">

<port name="PriceCheck" binding="pc:PriceCheckSOAPBinding">

<soap:address location=

"http://localhost:8080/axis/services/PriceCheck"/>

</port>

</service>

</definitions>

This WSDL document will come up again in Chapter 7 when we discuss how WSDL documents are published and found in a UDDI registry.

The second example woven into the next sections illustrates more sophisticated uses of WSDL (but by no means is it the most complicated use). We have included the entire WSDL file in Listing 6.2, but don't panic; we explain the business purpose of this Web service and each part of the WSDL in subsequent paragraphs. For now, just take a quick glance at it, and let the explanations clarify any questions. Refer back to this listing frequently.

Listing 6.2 The StockAvailableNotification WSDL Document

<?xml version="1.0" ?>

<definitions name="StockAvailableNotification"

targetNamespace=

"http://www.skatestown.com/services/StockAvailableNotification"

xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"

xmlns:reg="http://www.skatestown.com/ns/registrationRequest"

xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"

xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"

xmlns="http://schemas.xmlsoap.org/wsdl/">

<!-- Type definitions from the registration schema-->

<types>

<xsd:schema targetNamespace=

"http://www.skatestown.com/ns/registrationRequest"

xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"

xmlns="http://www.skatestown.com/schemas/ns/registrationRequest">

<xsd:complexType name="registrationRequest">

<xsd:sequence>

<xsd:element name="items">

<xsd:complexType name="ArrayOfItem">

<complexContent>

<restriction base="soapenc:Array">

<attribute ref="soapenc:arrayType"

wsdl:arrayType="xsd:string[]"/>

</restriction>

</complexContent>

</complexType>

</xsd:element>

<xsd:element name="address" type="xsd:uriReference"/>

<xsd:element name="transport"

default="http://schemas.xmlsoap.org/soap/smtp"

minOccurs="0">

<xsd:simpleType>

<xsd:restriction base="xsd:uriReference">

<xsd:enumeration

value="http://schemas.xmlsoap.org/soap/http"/>

<xsd:enumeration

value="http://schemas.xmlsoap.org/soap/smtp"/>

</xsd:restriction>

</xsd:simpleType>

</xsd:element>

<xsd:element name="clientArg" type="xsd:string" minOccurs="0"/>

</xsd:sequence>

</xsd:complexType>

<xsd:simpleType name="correlationID">

<xsd:restriction base="xsd:string">

<!-- some appropriate restriction -->

</xsd:restriction>

</xsd:simpleType>

</xsd:schema>

</types>

<!-- Message definitions -->

<message name="StockAvailableRegistrationRequest">

<part name="registration" element="reg:registrationRequest"/>

<part name="expiration" type="xsd:timeInstant"/>

</message>

<message name="StockAvailableRegistrationResponse">

<part name="correlationID" type="reg:correlationID"/>

</message>

<message name="StockAvailableRegistrationError">

<part name="errorString" type="xsd:string"/>

</message>

<message name="StockAvailableExpirationError">

<part name="errorString" type="xsd:string"/>

</message>

<message name="StockAvailableNotification">

Một phần của tài liệu Sams building web services with java making sense of XML SOAP WSDL and UDDI (Trang 268 - 320)

Tải bản đầy đủ (PDF)

(481 trang)