Web service architecture emphasizes loose coupling between constituent services, and a Web service application is often considered a macro Web service-that is, an application formed by wiring together micro Web services. The terms composition and choreography in the context of Web services refer to wiring services together or wiring together fine-grained operations of a single Web service to create an executable business process. This is not by any means a new technique. "Integration servers" and workflow systems have been doing this for years, though using proprietary wiring languages and proprietary runtime environments.
Consider the simple example of a travel agency operation. A travel agency allows a consumer to book a travel reservation and then later confirm or cancel the booking. A travel agency Web service therefore must expose two operations: one to allow a consumer to send an itinerary to the service, and the other an operation that instructs the service to confirm the itinerary. As we saw in Chapter 5, WSDL provides an elegant way to describe the set of operations of this travel agency. It also provides a way for a program to invoke these operations by describing the transport (e.g., SOAP) bindings and the service location.
The business process of booking a trip involves executing operations in a sequence-the consumer first submits an itinerary, then confirms the reservation. But the WSDL description of the service does not provide this sequencing information-it lists the two operations but makes no attempt to describe the order in which they are invoked. WSDL also does not explain how the two operations can be correlated-that is, when operations exposed by WSDL are performed in sequence to accomplish a business function, the invocation of multiple operations is essentially stateless. Long-running, asynchronous business operations that involve multiple operations being invoked must somehow be performed as a part of the same conversation (state must be maintained by some mechanism). Correlation between the two operations is necessary, because they must be linked within the same business process context. In this example, the two operations are correlated by using the same itinerary: when confirming an itinerary, the consumer must provide a previously created itinerary ID as the context for confirmation.
Sequencing and correlation of operations to create a business process form the core of service composition. The description of how one or more operations of service(s) are composed to create a business process may not seem useful when considering a human playing the role of a service consumer. A person can infer the sequencing and correlation needs based on common sense and from the meaningful operation names used in WSDL. But what if we wanted machines to understand the business process? In such a situation, we must provide a means to describe the sequence of operations, and the system must provide a mechanism to maintain state across operations invoked.
Adding service composition description to WSDL is not sufficient for a complete description of a Web service. Additional information, such as legal contracts and agreements and quality of service descriptions, are also needed to fully automate the creation of a Web service application from constituent services. This third form of description is commonly called collaboration description. Figure 17.1 shows how the three forms of description can be depicted in layers of a service description stack.
At the very bottom of the service description stack is WSDL, which provides the service's entry points-its operations and messages. It also provides details on how the service can be invoked (SOAP bindings, address of the service, etc.) Service composition pertains to a description language used to describe the sequencing and correlation of activities. The collaboration protocol stack describes the legal agreements that must be in place between transacting businesses. Only the ebXML specification suite currently addresses this aspect of the description stack.
Now that we understand the role and position of Web service composition in the Web service description stack, we will examine two competing specifications that provide a language to describe service composition. Neither specification has been accepted as a standard by the industry, so we will describe the approach taken by each, without examining them in detail.
The WSCI (pronounced "whiskey") draft specification was created jointly by Sun Microsystems, BEA, and Intalio in June 2002. WSCI is an XML vocabulary that describes how Web services that participate in long-lived, stateful message exchanges can be wired together. WSCI builds on top of WSDL.
To illustrate WSCI's major features, we start with a simple example of Flute Bank's loan service. The WSDL document in Listing 17.1 is not complete, because we have not shown the types, message, or service elements. The WSDL shows that the Web service exposes three operations. We define an interface that defines the processes exposed to a Flute customer. The process of helping a customer get a loan is the sequential execution of three steps:
The consumer sends a loan application to Flute Bank. Based on the consumer's credit rating and financial worth, the bank returns a list of loan options.
Later, from the list of qualified loan options, the consumer sends a selected loan for closing.
Because Flute Bank takes five days to process loan closing, the consumer may send a cancel message to Flute to have the loan request canceled within five days of submitting the request.
<definitions> ... WSDL types, messages etc go here ... ... <portType name = "consumerLoan"> <operation name = "applyForLoan"> <input message = "tns:loanApplication"/> <output message = "tns:qualifiedLoans"/> </operation> <operation name = "selectLoan"> <input message = "tns:loan"/> <output message = "tns:loanConfirmation"/> </operation> <operation name = "cancelSelectedLoan"> <input message = "tns:loan"/> <output message = "tns:CancelNumber"/> </operation> </portType> </definitions>
These three steps are exposed as operations in the WSDL for the loan service, but as we mentioned before, the WSDL interface does not provide any sequencing information. Listing 17.2 expands the loan service WSDL and illustrates the WSCI elements that combine the operations in the correct order.
<wsdl:definitions> <types> ... </types> <message> ... </message> <portType> ... </portType> ... other WSDL elements ... <interface name = "LoanService"> <process name = "ProcessLoan" instantiation = "message"> <sequence> <action name = "receiveApplication" role = "tns:LoanService" operation = "tns:consumerLoan/applyForLoan"> <call process = "tns:CheckCredit" /> </action> <action name = "receiveConfirmation" role = "tns:LoanService " operation = "tns:consumerLoan/selectLoan"> <correlate correlation="tns:loanCorrelation"/> </action> </sequence> </process> <process name = "CheckCredit" instantiation = "other"> <action name = "checkCredit" role = "tns:LoanService" operation = "tns:CreditAgency/checkConsumerRating"> </action> </process> </interface> <correlation name = "loanCorrelation" property = "tns:loanRequestNumber"> </correlation> </wsdl:definitions>
WSCI elements appear within the WSDL definitions (root) element. The WSCI interface element is the container for process definitions. In the example, the Flute Bank loan service interacts with a consumer service and exposes one WSCI interface for the interaction between them. The interface defines a process-the process of requesting a loan. WSCI allows a Web service to have more than one interface element. The intent is to have one interface element contain processes relevant to a particular scenario of interaction.
For example, although not shown here, the loan service will be interacting with an external credit rating service to calculate the consumer's credit rating. The processes used for the interaction between the bank and the credit rating service can be contained in a different interface element.
A process is an activity that establishes a new context of execution. It models the observable behavior of the loan service with respect to a loan request. In the example, ProcessLoan is the process defined in WSCI that models the Web service's behavior for a loan application. Within the process element, we define all relevant information regarding the process: how it is started, which WSDL operations are part of it, the sequence of execution of the operations, and so on. The instantiation = message attribute signifies that the process is instantiated upon receipt of a message-that is, when the first action the process refers to is ready. In this case, the ProcessLoan process will be triggered when the loan service receives the receiveApplication message.
The ProcessLoan process consists of the execution of a set of actions in sequence. The WSCI process uses a sequence element to indicate that activities or actions declared in the element are to be executed in order. The action element identifies an atomic activity-one that performs a single operation. While performing the action, the Web service can represent more than one logical role; the role=loanService attribute specifies that the receiveApplication action is executed on behalf of the loanService role.
Because Flute Bank has to check with an external agency for the consumer's credit rating, the receiveApplication action calls another process that does the credit check. The credit check process is modeled as a separate business process and is declared later in the WSCI as follows:
<process name = "CheckCredit" instantiation = "other"> <action name = "checkCredit" role = "tns:LoanService" operation = "tns:CreditAgency/checkConsumerRating"> </action> </process>
In this case, the CheckCredit process has instantiation = "other", signifying that unlike the ProcessLoan process, which is instantiated by the receipt of a message, this process is started by an explicit call. Because receiveApplication is an atomic action, the call to check credit is done within the scope of the action. (Details of the external interface and the CheckCredit process are not shown.)
The second action declared in the ProcessLoan process is receiveConfirmation, which is declared much like the first action. One difference is that the second action declares a correlation element: <correlate correlation="tns:LoanCorrelation"/>. The correlation element provides the mechanism for modeling a conversation in WSCI. The correlation element in this example signifies that the receiveConfirmation action is to be correlated to the previous receiveApplication action if the values of the loanRequestNumber fields in the two messages are the same.
The simple example above showed how WSCI proposes to handle sequencing and correlation aspects of Web service business interactions. WSCI can also sequence and correlate message exchanges between two or more Web services. Additionally, it specifies how exceptions (or faults) are to be handled. WSCI supports the Java notion of a recoverable fault (in Java, an application can catch an exception and determine an alternate execution path).
Although WSCI does not define a mechanism to support transactional processes, it recognizes that activities may need to be processed within the scope of a transaction. In Chapter 14, we explained the BTP and WS-Transaction specifications. WSCI does not endorse any particular transactional specification-it provides support and guidelines for transactional activities within a process. WSCI also supports compensating activities for long-running transactions where locking may not be appropriate to provide transaction isolation (see Chapter 14 for long-running transactional properties).
Submitted jointly by IBM and Microsoft, BPEL4WS, or BPEL, is a specification that unifies and builds on the earlier XLANG (Microsoft) and WSFL (IBM) specifications for Web service composition.
Like WSCI, BPEL is an XML grammar to describe business processes that are a result of composing two or more Web services. BPEL defines two types of business processes: abstract and executable. Distinguishing between the two requires understanding the BPEL concept of a business protocol, which specifies the roles played by interacting businesses and the sequence of messages they must exchange to achieve a business function.
A BPEL process that shows only the details of the business protocol between two parties is called an abstract business process, because it does not define the private implementation view of the process. An executable business process shows not only the sequence of message exchanges but also the structure of each message, control flow, and so on. An executable business process in BPEL is like a WSCI business process. The BPEL construct that describes an abstract business process is a subset of the BPEL construct needed to describe an executable business process. BPEL, like WSCI, recognizes that WSDL supports only synchronous and uncorrelated asynchronous interactions between Web services. BPEL processes, like WSCI processes, represent long-running stateful (or correlated) conversations between Web services. In BPEL, a process can be conceptually thought of as sitting between interacting Web services (Figure 17.2). To a BPEL process, the participating Web services are partners in the business interaction.
The interaction between a BPEL process and the partner service is usually bilateral and often asynchronous. BPEL uses the notion of a serviceLink to model the peer-to-peer bilateral relationship between a process and its partners. A service link describes the roles played by the partner services and the message and portTypes used in the interactions.
We mentioned before that Web services (with WSDL) inherently do not provide the ability to describe or model long-running stateful message exchanges. In WSCI, correlation elements provide a mechanism to host stateful conversations over multiple WSDL operations. In a business process, messages exchanged between the partner services (a consumer and a loan service, for example) should provide the illusion of being exchanged directly between the partner services. In reality, the infrastructure that hosts the business process must provide a mechanism to correlate different message exchanges that form a part of the business process.
In WSCI, the correlation element instructs the runtime that activities are to be correlated based on the value of a particular field. In BPEL, a correlation set element correlates activities. Both these methods provide a declarative way to inform the runtime of how a set of activities in a process is to be correlated. Because the process must maintain state, the BPEL runtime must maintain all messages and intermediate data required for business logic. BPEL provides the container element to identify the messages and data that represent state information. All messages exchanged between the process and partners must be WSDL messages and should be identified in the container. Figure 17.3 illustrates the core elements of a BPEL process document.
BPEL also defines primitive and compound activities. Simple activities such as receive (receive input message for an operation) , reply (provide a response to an invoked operation), and invoke can be considered steps in the business process. Compound activities are formed by structuring these primitive activities. For example, sequence allows contained activities to be performed in order, flow allows activities to be performed in parallel, and conditional branching is provided for by the switch activity.
Unexpected errors during the execution of the process are handled by faultHandler declarations. FaultHandler elements contain activities performed when declared faults are caught. Long-running processes that do not use locking for concurrency may need to use compensating activities to recover from errors. Compensating activities are an application-specific attempt to undo the partial effects of a business process. BPEL provides the CompensationHandler element to list compensating activities.
Figure 17.4 is taken from the BPEL 1.0 specification and illustrates the basic structure of a BPEL document.
The SOAP specification allows intermediary SOAP nodes in the processing path but does not address ordering of SOAP intermediaries in the message path. WS-Routing extends the SOAP intermediary concept by allowing the initial SOAP sender to specify the order in which SOAP intermediaries process the message en route to its destination (see Figure 17.5).
The WS-Routing protocol uses the SOAP-supplied extensibility mechanisms to define a protocol for guiding a SOAP message through a well-defined path. In Chapter 4, we explained that the SOAP header, with its actor and mustUnderstand attributes, provides a foundation for vertical extensibility by allowing SOAP message header entries to be addressed to one or more SOAP intermediaries. However, SOAP does not have an inherent mechanism to specify the order in which intermediaries are to receive the message-that is, it does not define a message path. WS-Routing builds on top of SOAP and provides a means to specify a path for both one-way and request-response message exchange patterns. WS-Routing also describes the message path independently of the underlying protocol.
WS-Routing defines a single SOAP header entry to describe the forward (usually the SOAP request) message path and, optionally, the reverse (response) message path. Although the message originator may specify a particular path, WS-Routing allows WS-Routing intermediaries to add additional nodes to the path, thereby altering the original path:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"> <env:Header> <wsr:path xmlns:wsr="http://schemas.xmlsoap.org/rp/"> <wsr:action>http://www.flute.com/payeeDetails</wsr:action> <wsr:to>soap://www.flute.com/billPay</wsr:to> <wsr:fwd> <wsr:via>soap://www.authenticator.flute.com</wsr:via> <wsr:via>soap://www.cache.flute.com</wsr:via> </wsr:fwd> <wsr:from>mailto:firstname.lastname@example.org</wsr:from> <mwsr:id>uuid:84b9f5d0-33fb-4a81-b02b-5b760641c1d6</wsr:id> </wsr:path> </env:Header> <env:Body> ... </env:Body> </env:Envelope>
The above SOAP message fragment shows how WS-Routing proposes to define the message path. A SOAP message may contain only one header entry for WS-Routing. All WS-Routing elements belong to the namespace http://schemas.xmlsoap.org/rp.
A WS-Routing entry starts with the path element, which is a container for other WS-Routing elements that detail the message path. The action element, much like the SOAPAction HTTP header, shows the intent of the WS-Routing message. The action element is required; its value is a URI. The value of the action element is determined by the original SOAP sender and cannot be change en route. If the message is a SOAP fault message, the value of the action element must be http://schemas.xmlsoap.org/soap/fault. The to element identifies the ultimate SOAP receiver. The value of the to element is determined by the original sender and cannot be modified en route.
The fwd element describes the forward message path and lists the WS-Routing intermediaries in message path order. The forward path can be set by the initial sender and then modified as the message moves along the path. The via elements identify soap intermediaries using an absolute URI. In the above example, two intermediaries are identified. First, the message goes to the authenticator (presumably for authentication services), then to the cache server (to short-circuit the path by providing previously cached values of the result).
The from element value is a URI that identifies the original sender. The specification recommends a URI of the form "mailto: ..." The id element provides a unique identifier in the form of a URI. The value if the id element may be used to correlate the message with other related messages (e.g., if correlation is needed between a faulty message and the corresponding fault message)
WS-Routing specifies bindings to HTTP, TCP, and UDP. TCP and UDP require DIME (Direct Internet Message Encapsulation), a binary encapsulation mechanism for encapsulating the WS-Routing message. TCP and UDP bindings are not discussed in this section.
When using WS-Routing over HTTP, the mustUnderstand header attribute must be set to true and the SOAP actor attribute must be http://schemas.xmlsoap.org/soap/actor/next, so that all SOAP intermediaries either respect the semantic of the WS-Routing header or are forced to throw a SOAP fault.
When sending a WS-Routing SOAP message, the value of the Request-URI must be the URI of the next node in the message path. That is, if the SOAP message is to be routed via a WS-Routing intermediary, the value of the Request-URI should be the URI of the first intermediary listed in the fwd element. If there are no intermediaries in the path, the Request-URI must have the value of the to element. Also, as mentioned earlier, the value of the SOAPAction header must be the same as the value of the action element.
The simple example we used illustrated some of the basic concepts of WS-Routing. A mechanism to specify a message path for both SOAP requests and responses allows us to take advantage of a truly distributed architecture-each SOAP intermediary along the path can use its resources to provide some value-added service.
For example, while the sending and destination SOAP nodes provide the core business functionality, an intermediary can provide automatic authentication and authorization services. SOAP response messages that contain cacheable data can be routed to caching servers that cache responses for faster response to SOAP requests. In this context, WS-Routing is to be looked upon as a building block on which other specifications can rely on for providing value-added messaging patterns. Currently, the WS-Routing specification has not been endorsed or accepted as a routing standard by other industry players-IBM and Sun, for example, do not support WS-Routing.
The goal of JSR-181, initiated by BEA and supported by Sun Microsystems, is to simplify the process for developing and deploying Web services on the J2EE platform. JSR-181 builds on JSR-175, which proposes a metadata facility for the Java platform. Development and deployment tools, precompilers, and so on have been using different, nonstandard annotations to classes and methods so that these tools and libraries can provide some special processing to class or source files. In the J2EE platform, XML deployment descriptors, special method-name prefixes and method names, and so on are used to deploy and compile EJBs. JSR-181 is a proposal to create metadata specific to Web services on the J2EE platform. The goal of the metadata is to make it easier for a Java developer to develop and deploy synchronous and asynchronous Web services.
The JAX* APIs we have discussed in this book provide a Java application the ability to process XML and add the functionality of XML RPC and XML messaging to the Java platform. For J2ME-based applications, additional considerations, such as limited device configurations, memory, and processing power, limit the use of the JAXP and JAXM APIs built for J2SE. Applications running on J2ME-based wireless devices form a large part of the next-generation Web service consumer base, enabling enterprise services to be accessed by consumers who use J2ME devices. JSR-172 proposes two optional packages for J2ME that will add the following functionality:
XML parsing and processing capabilities
Accessibility to Web services from CLDC and CDC profiles (i.e., provide J2ME devices the capability to become service consumers)
JSR-172 proposes that a strict subset of JAXP 1.2 be used for XML processing API on J2ME devices. To allow for the maximum number of configurations, the aim of this specification is to use CLDC 1.0 as the lowest common platform for implementation and to limit the size of the JAXP API subset to 25 KB.
JSR-172 JAXP subset differs from the JAXP 1.2 specification in that it requires the subset to support only XML namespaces, predefined XML entity references, UTF-8 and UTF-16 encoding, and SAX 2.0 API. It further requires that the subset not support DOM (neither 1.0 nor 2.0), SAX 1.0 APIs, or XSLT. The subset may optionally support (within the SAX 2.0 API) validation against DTD's.
To provide J2ME device application access to Web services, JSR-172 also proposes a separate download package that provides a subset of the capabilities of the JAX-RPC 1.0 package. The optional package requires that J2ME clients only support the static stub model of invocation (see Chapter 10 for details on client invocation models). The generated stubs must use document-style and literal-use (doc/literal) operation (Chapter 4 explains the use of doc/rpc style and encoded/literal use).
The API subset should support the following data types:
Arrays of primitive and value types
XML Structs and complex types (mapped to Java Beans as per JAX-RPC mappings, but with a few limitations)
Finally, it must be noted that the J2ME API subset for Web services is meant only for service consumers, not for service providers.