When I began this series of four articles introducing the WSFL, my goals were simple: to provide you with a basic understanding of what WSFL is, what it does, how to use it, and what it's good for. No discussion about WSFL, however, can be complete without touching on one of its core features: recursive composition of business processes.
The idea of recursive composition is simple: new business processes can be defined by combining existing business processes (see Figure 1). Because I'm talking about Web services here, that essentially means that using WSFL, you can wrap a Web services interface (WSDL document) around a business process and treat it just like any other Web service you may wish to interact with.
Figure 1: Recursive composition of Web services
You may ask now, "So what? Why does that matter?" I'd answer that question with a real-life scenario. For example, you work for the ReaderCo company, and you want to buy a book. Your company already has in place a procurement business process modeled using WSFL. Now, my company, SnellCo sells books. I have a business process set up for processing book orders. Your WSFL flow model includes an activity for submitting the order to some company that is capable of processing the order. My WSFL flow model can only be kicked off once a purchase order has been received. Therefore, by wrapping a WSDL interface around my business process and publishing that out on the Web as a "Book ordering Web service," your WSFL flow model can discover my service and submit its purchase order.
In this scenario, you don't care what my WSFL flow model looks like, you just want to be able to push a purchase order into it to get things rolling. And I really don't care what your WSFL flow model looks like, I just want to receive a purchase order from you so I can get things rolling. WSFL's support for recursive composition allows you and me to link our two business processes in a way that requires us only to agree on the format of the purchase order submitted. This simplifies the way business is done while maintaining the distributed workflow architecture.
In WSFL, every business process has both a private and a public life. There are things that an insider can see going on that an outsider cannot see. The private life of a business process is known as its private interface, likewise, the public life is its public interface. It is in the private interface that you will find the flow models and global models that define what that business process is actually doing. WSFL allows you to take individual parts of that process, such as the point at which a purchase order is received, or a receipt is pushed out, and export those as part of the business processes public interface. Figure 2 shows how exporting individual activities within WSFL allows you to build a WSDL interface for the business process through which other applications can interact.
Exporting a WSFL activity is roughly the equivalent of marking an operation
on a Java class as
public. That is, when a method is marked
it is visible and accessible to other applications making use of that Java
class. It's the exact same thing here, when you export an activity,
it becomes visible, a part of the Web service interface description described
using WSDL. To clarify that, I'll walk you through a simple example.
First, imagine a very simple workflow process, shown in Figure 3.
Figure 3: A simple workflow process
Here, you have only three activities: check stocks, determine best selling price, and sell stocks (the don't Sell bubble essentially ends the work flow without any additional activity). The flow model for this process would look like Listing 1.
<flowModel name="sample" serviceProviderType="sampleType"> <flowSource name="samplesource"> <output name="processInstanceData" message="tio:doStocks"/> </flowSource> <serviceProvider name="buyer" type="buyerType"/> <serviceProvider name="seller" type="sellerType"/> <export lifecycleAction="spawn"> <target portType="tio:sample" operation="doStocksRequest"> <map sourceMessage="doStocks" targetMessage="processInstanceData" targetPart="request"/> </target> </export> <activity name="checkStocks"> <input name="checkStocks" message="tio:checkStocks"/> <output name="checkStocksOutput" message="tio:stockQuote"/> <performedBy serviceProvider="buyer"/> <implement> <!--implementation details --> </implement> </activity> <activity name="determineSellPrice"> <input name="dataIn" message="tio:stockQuote" /> <output name="dataOut" message="tio:sellOrder"/> <performedBy serviceProvider="buyer"/> <implement> <!--implementation details --> </implement> </activity> <activity name="sellStocks" > <input name="sellOrder" message="tio:sellOrder"/> <output name="sellOrderOut" message="tio:sellConfirmation"/> <performedBy serviceProvider="buyer"/> <implement> <!--implementation details --> </implement> </activity> <controlLink name="c1" source="checkStocks" target="determineSellPrice"/> <controlLink name="c2" source="determineSellPrice" target="sellStocks"/> <dataLink name="c1" source="checkStocks" target="determineSellPrice"/> <dataLink name="gT-rS-data" source= "determineSellPrice" target="sellStocks"/> </flowModel>
Two of the operations, check stocks and sell stocks, require that the business process interact with Web services external to the business process itself, so what we need to do is export those activities as part of the processes public interface. We do that using the export mechanism in the flow model, as shown in Listing 2.
<activity name="checkStocks"> <input name="checkStocks" message="tio:checkStocks"/> <output name="checkStocksOutput" message="tio:stockQuote"/> <performedBy serviceProvider="buyer"/> <implement> <export portType="tio:stockBuyer" operation="checkStocks"> <map sourceMessage="checkStocks" sourcePart="check" targetMessage="checkStocksOutput" targetPart="stockQuote"/> </export> </implement> </activity>
A WSFL implementation engine can now take the global model, run it through a WSDL generation process and create the public Web service interface (WSDL portType) definition, as shown in Listing 3.
<definitions> <message name="checkStocks"> <part name="check" element="tio:checkStocks" /> </message> <message name="sellStocks"> <part name="order" element="tio:sellStocks" /> </message> <portType name="stockBuyer"> <operation name="checkStocks"> <input message="tns:checkStocks" /> <output message="tns:checkStocksOut" /> </operation> <operation name="sellStocks"> <input message="tns:sellStocks" /> <output message="tns:sellConfirmation" /> </operation> </portType> </definitions>
Now, to explain what just happened, I'll take a step back. Think about the check stocks operation. Essentially, in order to perform that activity, the WSFL engine must issue a Web service request to some stock quote service located somewhere out on the network. The engine, however, needs to know exactly how and what it is supposed to do to make that call. In WSDL terms, the check stocks operation is a request-response operation. Using the plug-link mechanism in the WSFL global model, you provide the engine with the information necessary to perform the operation and tie that back into the business process being executed.
So how does this tie back in to recursive composition? Every activity within a WSFL workflow is performed by an operation exposed by a Web service. Those operations are exposed using a WSDL port type definition. WSFL global models and pluglinks allow you to build a WSDL port type definition for various parts of a business process. You can link the two together so that an activity in one process is being implemented through the public interface of another process. Figure 4 shows a recursively composed process where an activity in one process is tied to the public interface of another process.
Figure 4: A recursively composed process
Recursive composition provides one method of aggregating services from various providers into a single solution. For example, a service provider may offer a purchase order Web service that is actually an aggregation of Web services provided from a number of different service providers (for doing things like credit card authorization, logistics, etc.). From the end user's point of view, he or she sees the purchase order service, not everything else going on behind the scenes.
Combining WSFL's ability to dynamically select which Web service implementations and service providers to use to perform any given activity within the workflow with the concept of recursive composition gives you an even greater level of flexibility. The process is exactly the same as I described it in the last installment of this column (see Resources).
Essentially, multiple service providers may implement two completely different workflows with exactly the same public interface. Because they export the same set of Web service operations, they are interchangeable with one another. Because WSFL flow models link to a Web services public interface (rather than a specific implementation of that interface), both providers are capable of stepping in to fulfill the activity. The WSFL engine, based on rules supplied by the designer of the WSFL flow model, can dynamically determine which provider to use in any given situation.
You can start experimenting with some of these concepts by using the Web Services Process Management Toolkit available at alphaWorks. While it is not a WSFL implementation, it does implement the concept of a "public interface" for existing MQ Series workflows. Complete information on how it works and what its capabilities are is included in the package.
Leveraged properly, WSFL can be an important component of a comprehensive Web services strategy within an enterprise. There is little doubt that many of the concepts are fairly complex and that designing successful business processes can be, at best, a nontrivial task. However, with the proper amount of practice, the right kind of tools, and a bit of patience, the benefit outweighs the complexity.
My goal with this series of articles has been merely to introduce you to WSFL. Because of that, there were many details that I just skimmed over, and others that I just completely ignored. The intent was to help you get your feet wet in WSFL's fundamental concepts, not to make you an expert. My suggestion is that, if you haven't done so already, you read the WSFL specification. Learn it, run through the concepts, and take the time to practice putting together work flows. And, as always, if you have any comments or questions, feel free to drop me a note.
- Be sure to check out three other installments of this column: Part 5, Part 6, and
Download the Web Services
Process Management Toolkit from alphaWorks.
Read the WSFL specification.
Learn about SOAP, WSDL
Learn about WebSphere MQ and its workflow components.
James Snell is both an author and a developer and is one of the newest members of the IBM Web Services development team. He comes to IBM with an extensive background in custom enterprise application development and business-to-business integration, and a passion for the cutting edge of Web technology. You can reach him at firstname.lastname@example.org.