Suhayl Masud

Subscribe to Suhayl Masud: eMailAlertsEmail Alerts
Get Suhayl Masud: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


Related Topics: Apache Web Server Journal

Apache Web Server: Article

Building a Real-World Web Service - Part 3

Building a Real-World Web Service - Part 3

Web services are the new "it" in the IT world, and vendors are rushing in to stake claims in this landscape, each with a different marketing spin on how they "do Web services." However, simply sending SOAP-based messages between machines is not really "doing Web services"; this is a limited view that obscures the bigger picture.

This series of articles demonstrates what a real-world Web service is and how to build one using features of Web services with components and knowledge of RosettaNet, an industry leader in e-business process standards. Having defined the WSDL definitions and constructed an abstract process in BPEL4WS in the first two installments, I now focus on implementation. This article is all about implementation and construction ...bring your hard hat along.

Using the Engine: BPWS4J
This installment demonstrates the creation and execution of a simple version of the e-business dialogues we've been building in this series. I'll create a bunch of BPEL, WSDL, and Java files using the BPEL4WS Editor, and Eclipse, and then execute them on the runtime engine, BPWS4J. I'll also show you how to install all the tools and components necessary to create and run e-business dialogues for yourself. The complete source code for this article is available at www.sys-con.com/xml/sourcec.cfm.

Setting up the Environment
Before I talk about the business dialogue we're constructing in this article, I want to dive right into setting up the environment. I encourage you to take a hands-on approach and experiment with the environment as you work through the article. The purpose is to set up an environment to develop and execute asynchronous business processes to perform the e-business dialogue we've been developing. Here is a list of requirements for this task:

  • Java SDK from Sun Microsystems: http://java.sun.com/j2se. I used J2SE 1.4.1.
  • Eclipse, an open-source IDE from Eclipse.org: www.eclipse.org/downloads/index.php. I used version 2.0.2.
  • Apache Tomcat 4.1, an open-source server solution for servlets and JSPs: http://jakarta.apache.org/tomcat/index.html
  • BPEL4WS Engine and Editor from IBM alphaWorks: www.alphaworks.ibm.com/aw.nsf/download/bpws4j
  • JavaBeans Activation activation.jar: http://java.sun.com/products/javabeans/glasgow/jaf.html
  • JavaMail mail.jar: http://java.sun.com/products/javamail

    To run Eclipse, Tomcat, or the BPWS4J engine, we need the Java runtime. We'll use Eclipse to write, compile, and execute any Java classes that we build along the way. To create a process, we'll use the BPEL editor, which is available as an Eclipse plug-in. To run a business process we need the BPWS4J engine, which runs on Tomcat. Finally, the activation and mail APIs are used for communication between the engine and clients.

    Installing the Components
    The first step is to install the Java SDK; just click on the installer file you downloaded and follow instructions. Test the installation by typing java -version in a command/shell window. You should see:

    java version "1.4.1"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-b21)
    Java HotSpot(TM) Client VM (build 1.4.1-b21, mixed mode)

    The next step is to install the Java Activation Framework. I simply removed activation.jar from the jaf-1_0_2.zip file I'd downloaded and placed it in the jre/lib/ext directory. To install JavaMail, I opened up the javamail-1_3.zip file imap.jar, mail.jar, smtp.jar, pop3.jar, and mailapi.jar into /jre/lib/ext. These files are automatically picked up by the Java runtime.

    Next we install Apache Tomcat. The installation is straightforward; just follow the steps in the installation wizard. To test the installation, start up Tomcat and type http://localhost:8080/ in your Web browser. If the installation is working, you should see the Apache administration page.

    Next we install Eclipse, which is a breeze as well; the install program finds the Java runtime and handles the necessary properties. If Eclipse doesn't find the runtime automatically, you might need to reboot to update the environment and install Eclipse again.

    We'll install the BPEL4WS editor, which is an Eclipse plug-in and needs to be deployed into /eclipse/plugin directory. To do this, unzip the contents of the BPEL4WS Editor zip file into your /eclipse folder - the contents will be extracted into /eclipse/plugins. That's it, you're done installing the editor. Now you can launch Eclipse and open up a "BPWS Perspective." Once you open a .bpel file, or create a new one, you should see BPEL constructs on the toolbar. The editor lets you create BPEL processes in a visual environment as well as a source code view.

    It's now time to install the BPEL engine. This is a fairly simple task as well: extract the contents of the zip file to a directory of your choosing and simply grab the bpws4j.war file from this directory, then drop it into the Tomcat4.1/webapps directory. To test the installation, start the Tomcat server (see Figure 1), and point the browser to http://localhost:8080/bpws4j. If the installation worked, you should see a Web page that allows you to run the admin client. To ensure that the server is configured properly, point the browser to http://localhost:8080/bpws4j/soaprpcrouter. You should see a message stating: "Sorry, I don't speak via HTTP GET - you have to use HTTP POST to talk to me". You should test the installation further and smooth out any problems by working with the samples provided with the BPWS4J package. Simply drop the bpws4j-samples.war file into the Tomcat4.1/webapps directory, and load the samples package in your Eclipse project. Follow the samples installation instructions for each process and you should soon have the environment warmed up for the development task ahead.

    Easing the Development Process
    We're working with Java, WSDL, and BPEL code. Since BPEL, WSDL, and especially the BPWS4J engine are all young efforts, sophisticated integrated development environments are a few months away. For now you'll have to get your hands dirty working with the nuts and bolts of code, but I have three tips to make the development process easier.

    First, make full use of the logger tool log4j, an indispensable tool developed by Apache and shipped with the BPWS4J engine. Your BPWS4J engine will log errors, information, and warnings into a log file using this tool, and this data is critical to understanding how your BPEL process is working. To enable the logger, go to where you installed BPWS4J on Tomcat, navigate to the bpws4j\WEB-INF\classes\log4j.properties file, and insert the lines shown below into the file. The engine will start logging into a file named bpel.log:

    log4j.rootLogger=DEBUG, R
    log4j.appender.R=org.apache.log4j.RollingFileAppender
    log4j.appender.R.File=bpel.log
    log4j.appender.R.MaxFileSize=100KB
    log4j.appender.R.MaxBackupIndex=1
    log4j.appender.R.layout=org.apache.log4j.PatternLayout
    log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n

    Second, try to simulate partner processes on different machines. If that isn't possible and you have to use the same machine, at least run separate instances of the BPWS4J engine on different instances of Tomcat. This makes it easy to follow code execution on each engine.

    Third, use Eclipse to do all your code development, with the BPEL editor integrated into the environment. It becomes easy to debug and run Java and BPEL files.

    The End-to-End Purchase Order Scenario
    It's now time to explore the e-business dialogue we're constructing. Figure 2 shows an end-to-end scenario of how a purchase order process would work in a BPEL environment at both ACME and Laptops, Inc. In this scenario, ACME and Laptops, Inc., are communicating publicly. ACME places a purchase order request and first receives a receipt acknowledging that Laptops, Inc., has received the purchase order request. Then ACME receives a purchase order acceptance from Laptops, Inc., which ACME acknowledges with a receipt message as well. On the private side, the processes at both ACME and Laptops, Inc., are interacting with internal Web services and Java applications.

    Let's look at what the processes are doing on the private side at both ACME and Laptops, Inc. At ACME the purchase order process is triggered by an Inventory Manager Java application. The process completes execution by sending the results of the execution to an internal Web service. On the Laptops, Inc., side the process is started by the PO request received from ACME. The process invokes an internal Web service to get the acceptance for the purchase order and finally wraps up by sending the results of the process to another internal Web service. There are 12 components in this scenario, 2 BPEL processes, 4 internal Web services, 4 Java apps, and 2 public Web services. The scenario describes reliable asynchronous messaging between the partners using actual RosettaNet purchase order processes.

    We'll build the public interactions between ACME and Laptops, Inc. (components 1-6 in Figure 2), leaving the private interactions to be completed in the next article. I've simplified the business scenario and will properly cover how the processes work as well as how WSDL, BPEL, and the runtime engine interact before going further and creating the rest of the components.

    Building the Public Web Service Definitions
    I'll start by building the WSDL definitions for the one private and two public Web services, starting with the poRequester.wsdl Web service (component 2 in Figure 2) to be deployed on ACME. This Web service allows the Inventory Manager to replenish inventory by placing a purchase order. For more details on working with WSDL, refer to Part 1 of this series (XML-J Vol. 4, issue 2). BPEL-enabled WSDL definitions require some additional information and since this WSDL file will be used in the BPEL process, it requires a service link definition to be added to the file. Service links enable partners in the BPEL process to be linked to actual "actions" defined in the Web service. Another deviation from the normal WSDL definition is that we don't have to describe the binding section for the WSDL definition - BPWS4J automatically generates the bindings necessary to interact with the defined port types. The poRequester.wsdl file begins with the namespace declarations:

    <definitions targetNamespace=
    "http://www.acme.com/services/poRequester"
    xmlns:ACME="http://www.acme.com/services/poRequester"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:slt="http://schemas.xmlsoap.org/ws/2002
    /07/service-link/"
    xmlns="http://schemas.xmlsoap.org/wsdl/">

    There are two messages in this Web service: a request for purchase order, and a message that acknowledges the receipt of the request. In the complete scenario, the replenish PO message is a complete RosettaNet purchase order, and the receipt message is also more elaborate and contains a copy of the message it is acknowledging. These features will be added in the next installment, but for now we'll keep both messages simple.

    <message name="ReplenishRequestType">
    <part name="replenishPO" type="xsd:string"/>
    </message>
    <message name="ReceiptAckType">
    <part name="receiptAck" type="xsd:string"/>
    </message>

    Next, define the port types and the collection of operations that the port type supports. This is a very simple service that has only one operation. When the Inventory Manager interacts with the Web service, the Web service receives an incoming replenish request and sends a receipt acknowledgment back to the Inventory Manager.

    <portType name="replenishRequestPort">
    <operation name="replenishRequest">
    <input message="ACME:ReplenishRequestType"/>
    <output message="ACME:ReceiptAckType"/>
    </operation>
    </portType>

    The BPEL process defines capabilities of partners by using service links that link a partner to a port type and a set of operations in the WSDL file. For more information on service links, please refer to Part 2 of this series (XML-J Vol. 4, issue 3). Here is the service link definition:

    <slt:serviceLinkType name="replenishRequestSLT">
    <slt:role name="inventoryService">
    <slt:portType name="ACME:replenishRequestPort"/>
    </slt:role>
    </slt:serviceLinkType>

    In a typical WSDL definition the next section is for defining the binding information that specifies the format of the messages sent to the Web service, and the address to send the messages to. However, since we're deploying this Web service as an associated component of a BPEL process, the BPWS4J engine generates the necessary bindings so the BPEL process can absorb the Web service, listening to the defined ports for any activity. Therefore, the bindings and service sections of the WSDL definition are empty.

    <service name="ACMEPORequesterServiceBP">
    </service>
    </definitions>

    The public Laptops, Inc., Web service, LaptopsIncPlacePO.wsdl (component 4 in Figure 2), takes a purchase order request as input and sends a receipt acknowledgment as a response. It has a structure very similar to the Web service we just defined (see Listing 1).

    Let's reflect on the public process: ACME sends a purchase order request with Laptops, Inc., and receives a receipt message. Next, Laptops, Inc., needs to send ACME a substantive purchase order acceptance response. To receive this PO acceptance message, define the poAcceptanceReceiver.wsdl Web service on ACME (component 6 in Figure 2). Its purpose is to receive a PO acceptance and to send a response acknowledging receipt of the PO acceptance. The definition is pretty straightforward and follows the same logic as the previous two definitions (see Listing 2).

    Now that we've defined the WSDL definitions, the next step is to create the BPEL processes that will use these Web service definitions to conduct business processes.

    Building the BPEL Processes
    Conceptually, we need to build only two BPEL processes, one for ACME and another for Laptops, Inc. However, due to a minor bug in the early alpha version of the BPWS4J engine, I have to split the process for ACME into two separate BPEL processes. IBM will hopefully fix this minor nuisance soon.

    The first BPEL process at ACME is ACMEPORequester.bpel (the first half of component 1 in Figure 2); it's layered on top of the poRequester.wsdl created earlier. This process takes a PO request from an Inventory Manager, and then sends that request to Laptops, Inc., by invoking the placePORequest operation on the Web service hosted by Laptops, Inc. The process passes the result of this invocation, just a receipt acknowledgment for our simple scenario, back to the Inventory Manager.

    The second BPEL process on ACME is ACMEPOReceiver.bpel (second half of component 1 in Figure 2), layered on top of poAcceptanceReceiver.wsdl. This process receives the PO acceptance message sent by Laptops, Inc., and sends back a receipt message to Laptops, Inc.

    Laptops, Inc., hosts the third BPEL process (component 5 in Figure 2); it receives a PO request (from ACMEPORequester process) and sends a receipt message to the requester, and then it sends the requester (ACMEPOReceiver process) a PO Acceptance message, and receives a receipt message.

    During the construction and testing phase of the BPEL processes, it's important to examine the log files on both BPWS4J engines to gain insight into how the processes are working. I'll next define ACMEPORequester.bpel (see Figure 3). The process definition begins with a namespace declaration:

    <process name="acmePORequesterProcess"
    targetNamespace="http://www.acme.com/services/acme
    PORequesterProcess"
    xmlns="http://schemas.xmlsoap.org/ws/2002/07/business-
    process/"
    xmlns:acmePOR="http://www.acme.com/services/poRequester"
    xmlns:laptopsPO="http://localhost:8080/laptops/
    LaptopsIncPlacePO.wsdl">

    Next I define the partners of the process. There are two partners: the first is the Inventory Manager, defined as the inventory service in the definition below. The Inventory Manager interacts with the process through operations defined in the "replenishRequestSLT" service link. The second partner plays the role of a PO fulfiller in this process, and the partner definition allows the process to interact with Laptops, Inc., through the "PORequestSLT" service link defined in the Laptops, Inc., WSDL file.

    <partners>
    <partner name="inventoryService" serviceLinkType=
    "acmePOR:replenishRequestSLT"/>
    <partner name="POFulfiller" serviceLinkType=
    "laptopsPO:PORequestSLT"/>
    </partners>

    I'll build the containers required to contain the data the process is receiving and sending. There are four containers in this process - the first two are used to receive from and respond to the Inventory Manager. The next two are used in interaction with Laptops, Inc. They are sent as part of an invoke request, with an input container containing the message being sent to Laptops, Inc., and the output container containing the message sent from Laptops, Inc. (see Listing 3).

    I'll now define the activity of the process. I'm using a simple sequence activity to coordinate the process; it performs the following tasks:

    Begin Sequence
    -Receive a PO request from the Inventory Manager
    -Assign the data from the request container to the container to be sent to Laptops, Inc.
    -Invoke a "place purchase order" request with Laptops, Inc.
    -Assign the information from Laptops, Inc., to the container being sent to the Inventory Manager
    -Reply to the Inventory Manager with the response from Laptops, Inc.
    End Sequence

    Here's how the sequence is defined:

    <sequence name="placePOSequence">
    <receive name="ReplenishRecieve" partner="inventory
    Service" portType="acmePOR:replenishRequestPort"
    operation="replenishRequest"
    container="replenishRequest"
    createInstance="yes">
    </receive>

    The receive activity defines the type of partners that can interact with the process and which operations they can use. The incoming request message is stored in the replenishRequest container. The next activity of interest is the invoke activity:

    <invoke name="PlacePOwithSeller"
    partner="POFulfiller" portType="laptopsPO:
    placePORequest" operation="placePORequest"
    inputContainer="inputPORequestContainer"
    outputContainer="outputPORequestAckContainer">
    </invoke>

    This invoke activity requires two actions from the receiver (Laptops, Inc., in our case). In the definition above, the invoke activity interacts with the placePORequest operation of the Laptops, Inc., Web service defined in LaptopsIncPlacePO.wsdl. The input container of the invoke activity is treated as the input message of the operation, and the output container will receive the output message from the placePORequest operation. The above definition will enable the acmePORequesterProcess to place a purchase order request with Laptops, Inc., and receive the receipt acknowledgment message in the output container.

    Next I'll define an assign activity that copies the information returned from Laptops, Inc., to the container that will be used to send information to the Inventory Manager.

    <assign name="copyreceivedreceipt">
    <copy>
    <from container="outputPORequestAckContainer"
    part="receipt"/>
    <to container="replenishResponse" part=
    "receiptAck"/>
    </copy>
    </assign>

    In the simple scenario, the information sent back to the Inventory Manager is only a receipt acknowledgment message; in the complete scenario, the Inventory Manager will receive the PO Acceptance message instead.

    To wrap up the acmePORequesterProcess I'll define the reply activity, which is the response to the request that the Inventory Manager sent at the beginning of the process. This is what the reply activity looks like:

    <reply name="ReplenishResponse"
    partner="inventoryService" portType="acmePOR:
    replenishRequestPort" operation="replenishRequest"
    container="replenishResponse">
    </reply>
    </sequence>
    </process>

    The second BPEL process at ACME is the ACMEPOReceiver.bpel, and it works like this:

    Begin Sequence
    -Receive the PO Acceptance from Laptops, Inc.
    -Assign a receipt acknowledging message to the container sent in the reply activity
    -Reply to Laptops, Inc., with the receipt acknowledgment
    End Sequence

    Listing 4 shows how it is defined.

    Finally, here is what the LaptopPlacePOProcess does (see component 5 in Figure 2) and how it is defined:

    Begin Sequence
    -Receive the PO Request from ACMEPORequester process
    -Assign a receipt message in the container used in the reply activity
    -Reply to ACMEPORequester process
    -Assign an acceptance message in the input container used in the invoke activity
    -Invoke the ACMEPOReceiver process and send the PO Acceptance message

    The acceptance message in this simple scenario is a simple string. In the complete scenario, it will be a purchase order acceptance message.

    Listing 5 (available on the Web) shows what the LaptopPlacePOProcess.bpel definition looks like.

    We're almost finished. We now have the WSDL and BPEL process definitions for both ACME and Laptops, Inc. Now I'll show you how to install the processes and how to write the Inventory Manager in Java to start the ACMEPORequester.bpel process, which in turn triggers the rest of the simple scenario.

    Installing and Running the Processes
    Start Tomcat and then point your browser to http://localhost:8080/bpws4j/admin/index.html and click on deploy (see Figure 4). First, deploy the poAcceptanceReceiver.wsdl and ACMEPOReceiver.bpel. You'll need to get the installed version of the WSDL file supplied by the BPEL process by clicking on the "External WSDL" link on the process listing in the admin client. Next, deploy the LaptopsIncPlacePO.wsdl and LaptopsIncPlacePOProcess.bpel. When asked for "acceptanceReceiver", supply the external wsdl file you just saved. You'll also need to get the external WSDL from this process as well. Deploy poRequester.wsdl and ACMEPORequester.bpel. When asked for "POFulfiller", provide the external wsdl file saved from the Laptops process. Load the InventoryManager.java class into Eclipse. You can pass the following sample arguments to check the installation: http://localhost:8080/bpws4j/soaprpcrouter "Acme requesting 105 IBM Laptops".

    Checking Results
    After running the process you should receive a message in the console halfway through the process: "Receipt Acknowledgement This message is to acknowledge that Laptops Inc have received your PO Request. We are working on the response which you will receive shortly". The rest of the processes carry on and their activity is recorded in the bpel.log file defined in the log4j.properties file. If your installation was accurate, you should see output similar to Figure 5.

    What's Next?
    So far, this series has covered important e-business dialogue conceptual, architectural, and construction issues. I've discussed the components of e-business dialogues and relevant standards like RosettaNet and EbXML, related these standards to Web services and BPEL4WS, and built sample WSDL and BPEL definitions. We now have executable BPEL processes that enable a simple e-business dialogue scenario using a reliable asynchronous interaction mode.

    Are we there yet? Do we have a real-world Web service? Almost. We have to construct the remaining six components described in Figure 2 to enable BPEL processes to interact with internal applications and Web services. We need to start exchanging real RosettaNet-based purchase order data, and we need to add features like correlation to the BPEL processes to make them more reliable. We also need to explore the real-world challenges faced when constructing a real-world Web service with BPEL and WSDL. Tune in next month as I expand the simple scenario created here into a robust e-business dialogue.

  • More Stories By Suhayl Masud

    Suhayl Masud is an experienced software architect with over 8 years of experience in designing and developing e-Business and e-Commerce systems. Suhayl recently helped RosettaNet develop the next generation of e-business processes. Suhayl has worked extensively with Java and Smalltalk, and served as an instructor and mentor for Fortune 500 companies

    Comments (1) View Comments

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


    Most Recent Comments
    Jeff Wilson 04/30/03 04:33:00 PM EDT

    Does this 19-page document (part 3 of a series) describe a lot of work for a lot of specialized people? It seems so. But there are other possible approaches. See www.waterlang.org, for instance.