rev. 1.1 - May 19, 2006
Contents
Overview
Preliminary Setup
Getting Started
Implementing the Custom Invoke Handler
Process Deployment Considerations
Conclusions

Creating and Using Custom Invoke Handlers, Part 3: Enterprise Java Bean Invocation

Overview

Part one gives you an introduction to replacing the ActiveBPEL server's standard invocation mechanism (SOAP over HTTP) with a custom invocation mechanism when calling partner-provided Web services. If are not yet familiar with custom invoke handlers please take a look at part one first.

Part two explores more advanced topics of the custom invoke handler including WSDL definitions containing multiple operations for a given port type, messages containing complex message types rather than simple message types, and how to return service faults defined for a given operation.

In part three, we will re-create the custom invoke handler for the ApproveLoan service as an Enterprise JavaBean (EJB) and understand how to configure and deploy this to ActiveBPEL Enterprise running in a full J2EE application server.

To get the most from this article, you need a reasonable understanding of BPEL and the standard deployment mechanisms of BPEL processes to an ActiveBPEL server. You should also be familiar with EJB implementation and deployment - this tutorial will not cover that topic in any detail.

This article discusses EJB invocation in conjunction with ActiveBPEL Enterprise for JBoss, WebLogic and WebSphere.

Note: the procedures discussed in this article (Part 3) will not work with the free ActiveBPEL Designer / Engine or ActiveBPEL Enterprise for Tomcat, as EJBs are not supported in those configurations.

Preliminary Setup

All code segments shown in this article are from the included sample code. The example contains the complete implementation including project files for use in Eclipse and/or ActiveBPEL Designer. The custom invoke handler API classes you need are located in ae_wsio.jar. In addition to this JAR you need to reference a few other JARs to successfully compile the custom invoke handler example. All of these files are made available through the Samples Library archive.

If you plan to use Eclipse to view and compile the example project then you need to import the existing project included with the download into Eclipse as follows:

  1. From Eclipse, select File / Import / Existing project into workspace and navigate to the custom_invoke folder where you unzip'd the example project and click the OK button
  2. At this point you may see errors about "Unbound classpath variable"; to correct this right click on the project in the Package Explorer and select Properties. Next, select Java Build Path, select the Libraries tab, and click the Add Variable... button. Click the Configure Variables... button in the dialog that appears, and then click the New... button. Create a variable named AESAMPLES_LIB that points to the sample library directory. Note that you may need to run the 'ant JBoss', 'ant WebLogic' or 'ant WebSphere' target in that directory to get the currently active libraries in use by ActiveBPEL Enterprise for the application server you're using. Click here or more information on the Sample Library.

If you plan to use ActiveBPEL Designer to view, simulate, or deploy the example process then you need to import the existing project included with the download as follows:

  1. From ActiveBPEL Designer, select File / Import / Existing project into workspace and navigate to the custom_invoke folder where you unzip'd the example project and click the OK button

If you're not using either of these tools, you can still use the files in this sample. Here's an explanation of the archive's directory structure:

custom_invoke
├─── doc
├─── ejbsupport
│    ├─── custom_invoke  <-- EJB deployment artifacts
│    │    ├─── ear
│    │    │     └─── ...
│    │    └─── jar
│    │          └─── ...
│    └─── lib   <-- J2EE library JAR
├─── src
│    └─── org
│         └─── activebpel
│              └─── samples
│                   └─── custom_invoke  
│                        ├─── ejb  <-- EJB source files
│                        ├─── pojo <-- Custom invoke handler source
│                        └─── util <-- utility class source files
└─── support
     └─── bpel_process
          ├─── bpel      <-- BPEL source files
          ├─── META-INF  <-- WSDL catalog files used for deployment
          └─── wsdl      <-- Web Service definition files

Getting Started

The business process we're using in this article is identical to the one used in Part Two, so we won't go through the details on that again here. Be sure you have access to the ActiveBPEL Designer project or BPEL source file.

Implementing the Custom Invoke Handler as an EJB

In Part Two we created an ApproveLoan custom invoke handler, which performs the following steps:

  1. Extract the message data from the service's input message
  2. Extract any extra query string information from the invoke (optional)
  3. Perform the required business logic
  4. Create the service's output message
  5. Return either the service's output message or a particular service fault

We'll be using this same code, but because we want to deploy the handler as an Enterprise JavaBean, we'll need to implement the (home) interface associated with EJB functionality, which includes methods like ejbCreate(), ejbActivate(), etc. We add this functionality with classes LoanApproverInvokeHandlerBean.java and LoanAssessorInvokeHandlerBean.java, each of which extends its respective POJO class from Part Two. This gives us the 'glue' needed to deploy the application as an EJB.

Now that we have the required EJB implementation, we deploy the classes as an application using the Enterprise Application Archive file structure. Construction of this archive is beyond the scope of this article, but you can peruse the Ant build script (build.xml) associated with this sample to see how it's built. To create the archive customInvokeSample.ear in the dist subdirectory for JBoss or WebSphere, run the build script's createEjbEar target with 'ant createEjbEar' . For WebLogic, use 'ant createWebLogicEjbEar'. You can examine the contents of this archive with WinZIP or any equivalent Zip file extraction tool.

To deploy the EAR file, simply copy it to the appropriate server directory (e.g., for JBoss:  %JBOSS_HOME%/server/awf/deploy) or deploy as per your application server's normal procedure.

Process Deployment Considerations for EJB Invocation

Now that our EJB invoke handler is deployed, we need to make some adjustments to the way our client process accesses it at run time. Recall that in Part Two we associated the partnerRole for our Approving partnerLink with an invokeHandler that specified our POJO custom invoke handler. Here we do the same, but with slightly different syntax to specify that our invoke handler is an EJB, specify an optional query string, and tell the engine how to find it.

Begin deployment as we did in Part Two, by creating a Process Deployment Descriptor for the BPEL process. Right-click the loanApproval-cih-part3.bpel process file in the Navigator View and select New / Deployment Descriptor. Select ActiveBPEL Enterprise for the Deployment Platform and click Next. Click Next again to go to the Partner Links page.

Select the Approving Partner Link and in the Partner Role section, select an Invoke Handler of ejb and an Endpoint Type of static. Click the "..." button to the right and the EJB Invoke Handler Properties dialog appears. Enter a Name of ejb/LoanApproverInvokeHandlerBean (e.g., this JNDI name reference is found in ejbsupport/customInvoke/jar/META-INF/jboss.xml) and a Query String of maxLoan=20000.00. Click OK. Select the Underwriting Partner Link and make similar selections, entering a JNDI Name of ejb/LoanAssessorInvokeHandlerBean (no Query String needed here).

Select the LoanProcessing Partner Link and observe that the Service (near the bottom) is set to LoanProcessingService. Click Finish to save the PDD, which should look roughly as follows:

<?xml version="1.0" encoding="UTF-8"?>
<process location="bpel/custom_invoke/support/bpel_process/bpel/loanApproval-cih-part3.bpel" name="bpelns:loanApproval-cih-part2" xmlns="http://schemas.active-endpoints.com/pdd/2005/09/pdd.xsd" xmlns:bpelns="http://docs.active-endpoints.com/activebpel/
  sample/bpel/LoanApproval/2006/09/loanprocess.bpel" xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing">
   <partnerLinks>
      <partnerLink name="Approving">
         <partnerRole endpointReference="static" invokeHandler="ejb:ejb/LoanApproverInvokeHandlerBean?maxLoan=20000.00">
            <wsa:EndpointReference xmlns:s="http://docs.active-endpoints.com/
    activebpel/sample/wsdl/LoanApproval/2006/09/loanapprover_2006-09.wsdl" xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing"> <wsa:Address>http://no.target.address.specified</wsa:Address> <wsa:ServiceName PortName="LoanApproverSOAPBinding">s:LoanApproverService</wsa:ServiceName> </wsa:EndpointReference>
         </partnerRole>
      </partnerLink>
      <partnerLink name="LoanProcessing">
         <myRole allowedRoles="" binding="MSG" service="LoanProcessingService"/>
      </partnerLink>
      <partnerLink name="Underwriting">
         <partnerRole endpointReference="static" invokeHandler="ejb:ejb/LoanAssessorInvokeHandlerBean">
            <wsa:EndpointReference xmlns:s="http://docs.active-endpoints.com/
    activebpel/sample/wsdl/LoanApproval/2006/09/loanassessor_2006-09.wsdl" xmlns:wsa="http://schemas.xmlsoap.org/ws/2003/03/addressing"> <wsa:Address>http://no.target.address.specified</wsa:Address> <wsa:ServiceName PortName="LoanAssessorSOAPBinding">s:LoanAssessorService</wsa:ServiceName> </wsa:EndpointReference>
         </partnerRole>
      </partnerLink>
   </partnerLinks>
   <wsdlReferences>
      <wsdl location="project:/custom_invoke/support/bpel_process/wsdl/loanassessor_2006-09.wsdl" namespace="http://docs.active-endpoints.com/activebpel/
  sample/wsdl/LoanApproval/2006/09/loanassessor_2006-09.wsdl"/>
      <wsdl location="project:/custom_invoke/support/bpel_process/wsdl/loanprocess_2006-09.wsdl" namespace="http://docs.active-endpoints.com/activebpel/
  sample/wsdl/LoanApproval/2006/09/loanprocess_2006-09.wsdl"/>
      <wsdl location="project:/custom_invoke/support/bpel_process/wsdl/loanapprover_2006-09.wsdl" namespace="http://docs.active-endpoints.com/activebpel/
  sample/wsdl/LoanApproval/2006/09/loanapprover_2006-09.wsdl"/>
   </wsdlReferences>
</process>

At this point you can export the PDD as a BPR to your running ActiveBPEL Enterprise. Invoke with the soapUI web service client application using data from the sampleData directory:

    \support\bpel_process\sampleData\applyRequest.xml

Note the optional query string - "?maxLoan=20000.00" - in the invokeHandler definition. This can be set to whatever value you like, and you can use it in conjunction with the request message data (amount) to cause the approval process to succeed or fail and send back a corresponding reply message (i.e., approved = true or false).


Conclusions

With an understanding of these advanced concepts you can create a custom invoke handler binding for almost any type of WSDL defined Web service including WSDL portTypes containing multiple operations and; WSDL Messages which define types that are complex. You also have the ability to return faults as defined in a portType's operation. Finally, you can now develop custom invoke handlers that are deployed as Enterprise JavaBeans.