Leveraging ESB to Virtualize Services Endpoints for BPEL Processes
by Clemens Utschig , Oracle SOA Suite Product Management
Published November
2006
Background
After Oracle released the Enterprise Service Bus (ESB) as part of the SOA Suite, a lot of people asked what the added value of the ESB would be, and when it should be used—compared to a complete, self-contained implementation only within Oracle BPEL Process Manager.
One of many advantages is the possibility of virtualizing a service transparently to its consumer, providing transformation from its native format into a canonical one, as well as reliable routing. |
This technical note demonstrates how to adopt a BPEL process to leverage the ESB for virtualizing legacy services in two guided steps by reusing existing artifacts, and what measurable value is gained by doing so.
Setup
Let's start with the process, which you will adopt for best practices with BPEL and ESB. We have created an asynchronous process that uses a common schema, which represents a canonical customer; here's an excerpt:
[...]
<element name="CustomerUpdateProcessProcessRequest">
<complexType>
<sequence>
<element name="customerName" type="string"/>
<element name="ccard" type="string"/>
<element name="ccardNr" type="string"/>
<element name="email" type="string"/>
<element name="pw" type="string"/>
</sequence>
</complexType>
</element>
[..]
The canonical customer request (CustomerUpdateProcessProcessRequest) contains a name (customerName), a credit card type (ccard), a credit card number (ccardNr), as well as an email address (email) and a password (pw).
The sample process, discussed in this note, updates a legacy system (in this case a database) that will be eventually replaced later on with a different data structure, as shown below.
<xs:complexType name="Customer">
<xs:sequence>
<xs:element name="custid">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="40"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="fname" minOccurs="0" nillable="true">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="40"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="lname" minOccurs="0" nillable="true">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="40"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="creditC" minOccurs="0" nillable="true">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:maxLength value="40"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
The process uses an assign activity (Transform_Input2ProtocolSchema) between the outbound partnerlink (UpdateCustomerService) and the input variable to transform the canonical structure into the legacy one.
The transformation leverages XSL (XML Stylesheet Transformation) that can be reused across systems later on. An excerpt is shown below.
<xsl:template match="/">
<ns2:CustomerCollection>
<ns2:Customer>
<ns2:custid>
<xsl:text disable-output-escaping="no">10</xsl:text>
</ns2:custid>
<ns2:fname>
<xsl:value-of select="substring-before
(/ns1:CustomerUpdateProcessProcessRequest/ns1:customerName,' ')"/>
</ns2:fname>
<ns2:lname>
<xsl:value-of select="substring-after
(/ns1:CustomerUpdateProcessProcessRequest/ns1:customerName,' ')"/>
</ns2:lname>
</ns2:Customer>
</ns2:CustomerCollection>
[...]
</xsl:template>
Step 1: Moving Legacy Service Invocation into the ESB Without Modifying Process Source
Now that the process is in place and the stage set, the first goal is to virtualize the real service behind an ESB system, and to make the invocation transparent to the BPEL process.
Applying this pattern, the process gets loosely, but reliably coupled to its infrastructure services, without knowing them. This makes a change of a service possible without causing disruption and change of the whole.
As the artifacts created within a BPEL process are highly reusable, you can use them within any ESB system without a change.
To start off, after creating a new ESB project, all partnerlink-related artifacts need to be referencable from ESB project. In a production environment the architect would store them on a centralized schema server or in a registry, to make sure only one copy of these artifacts exist. For the sake of simplicity, you will copy them.
In the case of the Database Adapter, which is used in this sample, the files to copy are
- DBAdapterOutboundHeader.wsdl (the header description)
- UpdateCustomer.wsdl (the service definition for the partnerlink)
- UpdateCustomer_toplink_mappings.xml (the TopLink mapping)
- UpdateCustomer_table.xsd (the data definition)
After doing so, these artifacts are ready to be reused within the newly created ESB system. The first step is to create a new service (UpdateCustomerService), and base it on the UpdateCustomer.wsdl (as shown below).
The outcome of this is a perfect clone of the partnerlink that is in the process, which exposes two operations, merge and write. The ESB can determine the type of the service, once all needed artifacts are reachable:
The next step is to create a Routing Service that uses the same definition (WSDL), to expose, merge/write operation to the outside world. It's named PlainExposed, and contains two routing rules, just forwarding the request to the appropriate operations exposed by the Database Adapter.
After applying the changes in the ESB System diagram, it's represented in the fashion shown below.
After creating this system, and registering it with the Enterprise Service Bus, it's time to have the BPEL Process consuming it—for now, only at runtime.
Oracle BPEL Process Manager provides a flag on the partnerlink level to specify a runtime location for the service definition (WSDL), which is to be used for invocation as opposed to a location for type validation when compiling. The flag is named wsdlRuntimeLocation, and if set, must point to a concrete WSDL, which contains a binding. In this sample case it points to the definition of the PlainExposed routing service, which can be found from the ESB Console. At runtime, the BPEL Process will bind as late as possible, by fetching the bound WSDL only while running, and not when loaded.
Within the BPEL process, this property can be added visually by double-clicking on a partnerlink, as shown below.
Once your process is redeployed and another time executed, the instance can be found in the ESB Console.
Concerning performance and the impact of adding the ESB into the picture, it's worth to mention that BPEL and ESB communicate, if possible, in a native, in memory fashion. Only if distributed, they will use SOAP over HTTP for calls. In addition, this in-memory optimization between components makes a seamless, traceable approach to SOA possible.
Step 2: Reusing the Canonical Model and Transformation Within the ESB System to Achieve "Separation of Concerns"
Applying this pattern, the BPEL process gains homogeneity, focusing on business problems rather than protocol transformations, and works entirely based on a canonical model.
The goal for the second step is to reuse the transformation artifact, as well as the canonical customer model from the BPEL process—to expose a canonical representation of the customer request to the outside service consumer world.
The first step needed to reuse two more artifacts of the BPEL process is to reference them. In the sample's case, one is called CustomerUpdateProcess.xsd and contains the customer model as described in the introduction part.
Second, the transformation artifact, called Transformation_Cannonical2Protocol.xsl, which provides the functionality of transforming the canonical representation into the legacy one.
After doing so, both artifacts are ready to be used. Within the ESB System diagram, create a new Routing Service (UpdateCustomerCanonical) and add a new asynchronous operation called "execute". This new operation will take as parameter the CustomerUpdateProcessProcessRequest element from the CustomerUpdateProcess.xsd schema.
Next, connect this Routing Service to the Database Service (UpdateCustomerService) by creating a new routing rule, which can be seen at the bottom of the above screenshot.
As the input of the Routing Service is different to the parameter of the Database one, it's time to reuse the transformation (Transformation_Cannonical2Protocol.xsl).
The final ESB System in Oracle JDeveloper should look like the one below, containing two Routing Services: one canonical (UpdateCustomerCanonical) and one with the legacy format (PlainExposed) and its exposed operations (merge/write).
After reregistering the system within Enterprise Service Bus, it's time to add logic to the BPEL process to invoke it.
Within the BPEL process a new partnerlink was created that points to the abstract definition (WSDL) of the UpdateCustomerCanonical Routing Service. The concrete, bound definition was added again as wsdlRuntimeLocation flag. Therefore the only thing left is a simple assign, as shown below.
The assign rule (Assign_ToInput) maps the process' input variable one to one into the input variable of CanCustomerServiceESB.
Once the BPEL process is redeployed and executed, the instance can be found in the ESB Console and should look like the screenshot below.
Taking a look into the BPEL Console, even though the partnerlink was changed, the traceability features of the whole system did improve, and with a click, the user can follow the instance from BPEL to ESB and vice versa.
>
Conclusion
While before the adoption, the BPEL process needed to know the legacy database service as well as its format, and did transformation between, now the legacy service is completely transparent to the process. It can be replaced without any distraction to the process orchestration itself.
What was gained through applying these patterns and best practices? The business orchestration is entirely based on a canonical model – business, not protocol driven. Bringing ESB into the picture brought the added value of reliability, combined with its sophisticated error hospital, that lets you react to failures in real time, change routings at any time, as well as retry failed invocations.
Discuss this technical note in the SOA Suite Discussion Forum
Clemens Utschig [blog] works within the Oracle SOA Product Management Team responsible for security aspects and cross-product integration. Aside from technology, Clemens' focus is on project management and consulting aspects coming along with SOA implementations. As a native Austrian, Clemens' Oracle career started in Europe at the local consulting services branch—working with customers on J2EE and SOA projects, where he also founded the local Java community. He is a frequent speaker at conferences evangelizing either on technology or the human factor—two key aspects when introducing new concepts and shifts in corporate IT strategy.
|