Web Services, SOA, and WS-BPEL Technologies

0
265
15 min read

Nowadays, the most common way to build composite applications based on service-oriented principles is to use the Service-Oriented Architecture, Webservices, and WS-BPEL (Web Services Business Process Execution Language) technologies together.

While Web Services is a technology that defines a standard mechanism for exposure and consumption of data and application logic over Internet protocols such as HTTP, WS-BPEL is an orchestration language that is used to define business processes describing Web services’ interactions, thus providing a foundation for building SOA solutions based on Web services. So, to build an SOA solution utilizing Web services with WS-BPEL, you have to perform the following steps:

  • Build and then publish Web services to be utilized within an SOA solution
  • Compose the Web services into business flows with WS-BPEL

This article gives an overview of the Web services, SOA, and WS-BPEL technologies and how these technologies are interrelated. It also contains references to related documentation and other chapters of the book SOA and WS-BPEL, which discuss the topics touched upon in this introductory article in greater detail.

Web Services

The Web Services technology provides an efficient way to share application logic across multiple machines running various operating systems and using different development environments. To achieve this, Web Services utilizes the SOAP, WSDL, XML Schema, and some other XML-based technologies, providing a standards-based approach to overcoming the platform and language differences.

The following sections give you an overview of these technologies, explaining how they fit into the big picture.

Communicating via SOAP

In a nutshell, SOAP is a messaging protocol used to transfer application data in XML format over a transport protocol, such as HTTP. Nowadays, Web service applications employ SOAP as a standard protocol for exchanging information in a decentralized, distributed manner.

For detailed information about SOAP, you can refer the W3C SOAP Recommendation documents. Links to these documents can be found at http://www.w3.org/TR/soap/.

SOAP-based interfaces interact with each other by means of SOAP messages that are specially formatted XML documents used to carry data and metadata. The general structure of a SOAP message is shown below:

    <SOAP-ENV:Envelope ...>
<SOAP_ENV:Header>
...
...
</SOAP_ENV:Header>
<SOAP_ENV:Body>
...
...
</SOAP_ENV:Body>
</SOAP-ENV:Envelope ...>

As you can see in the previous code snippet, an XML document representing a SOAP message consists of the following elements:

  • An Envelope element wrapping the entire message.
  • A Header element, which is actually optional and may contain subelements carrying metadata associated with the message.
  • A Body element, which contains the payload of the message. This element may contain an optional fault element, which describes an error if it occurs.

While SOAP messages may be used in various message exchange scenarios, the most popular one is the request/response pattern, which is normally used when calling a remote function exposed by a Web service. Diagrammatically, the request/response scenario might look like the following figure:

Web Services, SOA, and WS-BPEL Technologies

As you can see in the above figure, both the service requestor and service provider include the message processing logic required to send/receive and process SOAP messages involved in the request/response scenario used here. If the service requestor is calling a remote function exposed by the service provider, the request message is supposed to carry the values of the parameters passed to the exposed function. After the request message is received, the service provider processes it, extracting the payload (in this case, the parameters passed to the function) from theenvelope. Then, the requested function is invoked, utilizing the parameters specified. Once the function result is ready, the service provider wraps this result in a SOAP envelope and sends it back to the service requestor in the response message. The service requestor in turn extracts the function result from the response message and sends it to the calling code.

In Chapter 2 of the book SOA and WS-BPEL, you will learn how to implement service providers andservice requestors with PHP using the PHP SOAP extension.

Now that you have a rough idea of how the remote procedure call (RPC) scenario works with SOAP, let’s look at an example.

Suppose you have a Web service that exposes the getOrderStatus function, taking the number of a purchase order as the parameter and returning the status of that order as the result.

It is important to understand that the getOrderStatus function discussed in this example may be implemented in any programming language and run on any platform, provided they allow you to expose this function through SOAP. The fact is that Web services hide the details of underlying logic from their consumers, publicly exposing only their interfaces. In the book SOA and WS-BPEL, you will see a few examples of implementing service underlying logic with PHP.

The following figure depicts a scenario where a service requestor invokes the getOrderStatus function exposed as a Web service:

Web Services, SOA, and WS-BPEL Technologies

The general steps performed at run time are the following:

  1. The service requestor sends a SOAP request message containing the number of a purchase order to the service provider.
  2. The service provider processes the request message, extracting the PO number from the SOAP envelope.
  3. The service provider invokes the getOrderStatus underlying function, passing the extracted PO number as the parameter.
  4. The service provider encapsulates the result produced by the getOrderStatus function into a SOAP response message.
  5. The service provider sends the SOAP response message back to the requestor.

In this example, the SOAP request message sent to the Web service provider might look like the following:

    <?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
>
<SOAP-ENV:Body>
<SOAP-ENV:getOrderStatus>
<body>US-247860</body>
</SOAP-ENV:getOrderStatus>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

As you can see, the body of the above SOAP message contains the purchase order number passed as the parameter to the getOrderStatus function. The response to this message might look like the following:

    <?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
>
<SOAP-ENV:Body>
<SOAP-ENV:getOrderStatusResponse>
<body>Shipped</body>
</SOAP-ENV:getOrderStatusResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The getOrderStatus function may be designed so that it throws a SOAP exception when something goes wrong. For example, an exception may be thrown upon a failure to connect to the database that contains information about the purchase orders placed. A fault message generated by the Web service exposing the getOrderStatus function might look like the following:

    <?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Failed to determine the order status</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

As you can see, the fault section resides within the body section of the message, and includes two subelements detailing the fault that occurred, namely: faultcode and faultstring.

Binding with WSDL

Looking through the SOAP request message discussed in the preceding section, you may notice that it carries only the parameter for the getOrderStatus function exposed by the service. The message doesn’t actually contain any information about how to get to the service, what remote function is to be invoked, and what that function is to return. Obviously, there must be another document that describes the Web service, providing all this information to consumers of the service. Web Services Description Language (WSDL) provides a mechanism to describe Web services, making them available for external consumption. A WSDL service description is an XML document that defines how to communicate with the Web service, describing the way in which that Web service has to be consumed.

For detailed information about WSDL, you can refer to the WebServices Description Language (WSDL) W3C Note available athttp://www.w3.org/TR/wsdl.

Actually, a WSDL service description document consists of two parts: logical and physical. The logical part of a WSDL describes the abstract characteristics of a Web service and includes the following sections:

  • types is an optional section in which you can define types for the data being carried, normally using the XSD type system.
  • message contains one or more logical parts representing input and output parameters being used with an operation.
  • operation describes an action performed by the service, specifying input and output messages being used as parameters of the operation.
  • portType establishes an abstract set of operations supported by the service.

The physical part of a WSDL describes the concrete characteristics of a Web service and includes the following sections:

  • binding associates a concrete protocol and message format specifications to operations and messages defined within a particular port type established in the logical part of the document.
  • port establishes an endpoint by associating a binding with a concrete network address.
  • service contains one or more port elements representing related endpoints.

Turning back to the example discussed in the preceding section, the WSDL description document that describes the Web service exposing the getOrderStatus function might look like the following:

<?xml version="1.0" encoding="utf-8"?>
<definitions name ="poService"




targetNamespace="http://localhost/WebServices/ch1/poService">
<message name="getOrderStatusInput">
<part name="body" element="xsd:string"/>
</message>
<message name="getOrderStatusOutput">
<part name="body" element="xsd:string"/>
</message>
<portType name="poServicePortType">
<operation name="getOrderStatus">
<input message="tns:getOrderStatusInput"/>
<output message="tns:getOrderStatusOutput"/>
</operation>
</portType>
<binding name="poServiceBinding" type="tns:poServicePortType">
<soap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="getOrderStatus">
<soap:operation
soapAction=
"http://localhost/WebServices/ch1/getOrderStatus"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="poService">
<port name="poServicePort" binding="tns:poServiceBinding">
<soap:address
location=
"http://localhost/WebServices/ch1/SOAPserver.php"/>
</port>
</service>
</definitions>

Let’s go through this document in detail to understand the format of a WSDL description document.

The definitions element is the root in every WSDL document, wrapping all the WSDL definitions used in the document. Also, it houses the namespaces used within the document:

    <definitions name ="poService"




targetNamespace=
"http://localhost/WebServices/ch1/poService">

Next, you define the abstract definitions for the messages to be used for exchanging data. Here is the abstract definition for the message that will be used for carrying the input parameter for the getOrderStatus function:

          <message name="getOrderStatusInput">
<part name="body" element="xsd:string"/>
</message>

Here is the abstract definition for the message to be used for sending back the result of the getOrderStatus function:

          <message name="getOrderStatusOutput">
<part name="body" element="xsd:string"/>
</message>

Once you have messages defined, you can group them into operations, which in turn are grouped into a service interface. Here is the portType section representing an abstract view of the service interface, which, in this example, supports onlyone operation:

          <portType name="poServicePortType">
<operation name="getOrderStatus">
<input message="tns:getOrderStatusInput"/>
<output message="tns:getOrderStatusOutput"/>
</operation>
</portType>

Now that you have an abstract service interface defined, you can go ahead and specify physical details of the data exchange. In a binding section, you map the abstract service interface defined within a portType section earlier into a concrete format, specifying the concrete protocol for data transmission and message format specifications. In this example, the binding section is used to deploy thegetOrderStatus operation—the only operation supported by the service:

         <binding name="poServiceBinding" type="tns:poServicePortType">
<soap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="getOrderStatus">
<soap:operation soapAction=
"http://localhost/WebServices/ch1/getOrderStatus"/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>

In the above snippet, you define a SOAP binding of the request-response RPC operation over HTTP and specify the concrete URI indicating the purpose of the SOAP HTTP request.

Finally, you use the service element hosting the port element to specify the physical address of the service.

         <service name="poService">
<port name="poServicePort" binding="tns:poServiceBinding">
<soap:address location=
"http://localhost/WebServices/ch1/SOAPServer.php"/>
</port>
</service>

In the above example, the getOrderStatus function exposed as a Web service takes only one input parameter. But what if you need to pass more than one parameter to a Web service? Suppose you modify the getOrderStatus function so that it takes one more parameter, say, poDate specifying the date an order was placed. If so, you have to include a new part element to the message construct describing the logical abstract content of an input message in the WSDL document:

    <definitions name ="poService"




targetNamespace=
"http://localhost/WebServices/ch1/poService">
<message name="getOrderStatusInput">
<part name="poNumber" element="xsd:string"/>
<part name="poDate" element="xsd:string"/>
</message>
<message name="getOrderStatusOutput">
<part name="body" element="xsd:string"/>
</message>
...
</definitions>

Now, a SOAP message issued by a service requestor when calling the getOrderStatus remote function would look as follows:

    <?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
>
<SOAP-ENV:Body>
<SOAP-ENV:getOrderStatus>
<poNumber>US-247860</poNumber>
<poDate>21-jan-07</poDate>
</SOAP-ENV:getOrderStatus>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Using XML Schema Types within WSDL

Definitions

As you might notice, the WSDL document discussed in the preceding section doesn’t contain the types construct. It is OK in this particular example because you don’t actually need any custom XML Schema Definition (XSD) types when defining message parts in the WSDL document. Instead, you use the native XSD schema type string.

However, in some situations you may find it useful to utilize custom XML Schema types within a WSDL document. You can define custom XSD types within the types construct of a WSDL document and then reference them within message elements. For example, you might define a complex XSD type in the types section of the WSDL document discussed in the previous section and then reference this XSD type when creating the abstract definition of the output message:

    <?xml version="1.0" encoding="utf-8"?>
<definitions name ="poService"





targetNamespace=
"http://localhost/WebServices/ch1/po.wsdl">
<types>
<xsd:schema
targetNamespace="http://localhost/WebServices/schema/">
<xsd:element name="poInfo">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="pono" type="xsd:string" />
<xsd:element name="shippingDate" type="xsd:string" />
<xsd:element name="status" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</types>
<message name="getOrderStatusInput">
<part name="poNumber" element="xsd:string"/>
<part name="poDate" element="xsd:string"/>
</message>
<message name="getOrderStatusOutput">
<part name="poStatus" element="xsd1:poInfo"/>
</message>
...
</definitions>

In this example, a response message sent by the service to a service request or mightlook as follows:

    <SOAP-ENV:Envelope
>
<SOAP-ENV:Body>
<SOAP-ENV:getOrderStatusResponse>
<poStatus>
<pono>US-247860</pono>
<shippingDate>21-jan-07</shippingDate>
<status>Shipped</status>
</poStatus>
</SOAP-ENV:getOrderStatusResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

While this example shows how to define custom XML Schema types within the types construct of a WSDL document, you can achieve better reusability by putting XSD type definitions in a single XSD document.

Continuing with this example, you might remove the contents of the types construct into a separate file so that it’s available, say, at http://localhost/WebServices/schema/po.xsd. The contents of this file should look as follows:

    <?xml version="1.0"?>
<schema targetNamespace="http://localhost/WebServices/schema/"
>
<element name="poInfo">
<complexType>
<sequence>
<element name="pono" type="string" />
<element name="shippingDate" type="string" />
<element name="status" type="string" />
</sequence>
</complexType>
</element>
</schema>
</schema>

With that done, you can make use of the import statement in the WSDL documentin order to associate the namespace representing the custom XSD schema with the location of the above document, thus making the contents of the schema available within the WSDL document:

    <?xml version="1.0" encoding="utf-8"?>
<definitions name ="poService"





targetNamespace=
"http://localhost/WebServices/ch1/po.wsdl">
<import namespace="http://localhost/WebServices/schema/"
location="http://localhost/WebServices/schema/po.xsd"/>
<message name="getOrderStatusInput">
<part name="poNumber" element="xsd:string"/>
<part name="poDate" element="xsd:string"/>
</message>
<message name="getOrderStatusOutput">
<part name="poStatus" element="xsd1:poInfo"/>
</message>
... </definitions>

As you no doubt have realized, having XSD type definitions in separate files allows you to build more flexible, reusable, and modular solutions. In Chapter 3 of the book SOA and WS-BPEL, you will see how the XSD documents referenced in WSDL can be then reused by an Oracle database holding and processing SOAPmessages data.


Subscribe to the weekly Packt Hub newsletter

* indicates required

LEAVE A REPLY

Please enter your comment!
Please enter your name here