With most BPEL processes, partner links are static in that they reference a single instance of web service specified by the developer at design time (though typically configured at deployment).
In the majority of cases, this approach is fine. However, in this recipe we will consider a scenario in which a standard service contract might be implemented by multiple providers, the selection of which we want to dynamically configure at runtime.
An example of this, is the order aggregation process of our online bookstore, where at the point of placing an order with the publisher, we will need to invoke the appropriate service in order to route our book order to the correct publisher.
For this scenario, the BPEL language supports the concept of dynamic partner links, which enables the BPEL process to specify at runtime the endpoint of the web service being invoked and bind to it dynamically.
In this recipe, we will build on the order aggregation process of our online bookstore in order to route our book orders to the appropriate publisher.
In order to use this design pattern, you will need to define a standard WSDL to be implemented by each of your routing destinations (publishers, in our example).
For our purposes, we have defined the WSDL Publisher_Service_1.0.wsdl
, which defines the operation submitBookOrder
.
We have provided three basic implementations of this service, as defined in the following table:
Publisher |
Endpoint |
---|---|
ACME |
|
Packt |
|
Skynet |
|
These implementations are defined in the PublisherApp application, which is included in the sample for the book. You will need to open this sample in JDeveloper and deploy to your instance of the SOA Suite.
For the purpose of this recipe, we will extend the Message aggregation within a composite recipe to place the aggregated order, so you will either need to follow this sample recipe or open the sample solution with JDeveloper.
In addition, we are going to create a variable of type Endpoint Reference
, defined in the schema ws-addressing.xsd
. This is already defined and deployed to MDS. So, to reference this from within our BPEL process, we will need to create a file-based MDS connection in JDeveloper.
Instructions on how to do this are defined in the Creating a file-based MDS repository for JDeveloper recipe in Chapter 2, Using the Metadata Service to Share XML Artifacts.
Message Aggregation
composite and drag a web service onto the External Reference swimlane. This will open the Create Web Service window. Give it the name PublisherService
, and then browse to the PublisherService_1.0.wsdl
WSDL included with the samples and select it.When prompted to localize files, ensure that the option Maintain original directory structure for imported files is selected, but deselect the option Rename duplicate files.
Next, wire the WarehouseService
service to the PublisherService
service.
while
loop).Open the Edit Invoke window, give it the name submitPublisherOrder
, specify PublisherService
as the Partner Link, and ensure submitBookOrder is selected as the operation.
Create an input variable with the name publisherBookOrder
and an output variable with the name publisherBookOrderResponse
.
publisherBookOrder
variable. Drag an Assign activity on to the BPEL process just before the Invoke activity submitPublisherOrder
.Map the content of inputVariable/payload/ns1:submitBookOrder
to publisherBookOrder/payload/ns4:submitBookOrder
.
This will open the Type Chooser window. Click on Import Schema File…. This will launch the Import Schema File window. Click on the Browse Resources… icon to open the SOA Resource Browser window.
IDE Connections > SOA-MDS > File Based MDS > soa > shared > common
Select the schema ws-addressing.xsd as shown in the following screenshot:
In the Type Chooser window, select Endpoint Reference, as shown in the following screenshot:
publisherEndpoint
to contain the endpoint of the appropriate publisher service that we wish to invoke.To populate the Address
element, use a transformation activity rather than an Assign activity. We have used a concat
function, as shown in the following screenshot, to create the endpoint based on the publisher name and map that to the Address
element within the EndpointReference
variable:
In the Type Chooser window, select Import Schema File…. Browse the filesystem and select the file ws-bpel_serviceref.xsd
, included with the samples for the Getting ready section for this recipe. In the Import Schema File, uncheck Copy to Project, and click on OK.
In the Type Chooser window, select service-ref.
setPublisherServiceRef
.Map publisherEndpoint
to publisherServiceRef/ns6:service-ref/xsd:any
.
JDeveloper will prompt you with the following warning:
$publisherServiceRef/ns5:EndpointReference
.$publisherServiceRef
to the PublisherService
partner link, as shown in the following screenshot:WarehouseService
composite to the Oracle SOA Suite and use Enterprise Manager to submit multiple submitBookOrder
messages.Ensure that you specify either ACME, Packt, or Skynet as the publisher , you should see that orders are dynamically routed by the Warehouse Service to the appropriate publisher service.
BPEL 2.0 provides support for dynamic partner links. This allows a BPEL 2.0 process to override the endpoint specified at design time for a partner link, with a value determined at runtime.
While we can override the endpoint for a partner link, all other attributes of our service definition remain fixed. So, to use this approach, we must define a common WSDL interface that all of our services will implement.
To dynamically invoke the appropriate endpoint at runtime, we need to update the endpoint reference of the partner link before invoking the service. To do this, we need to create a variable of type Service-Ref
(as defined by ws-bpel_serviceref
) and populate it with a variable of type EndPointReference
(as defined by WS-Addressing
) containing just an <Address>
element populated with the endpoint of the publisher service that we wish to invoke.
This is important, since if we create an EndpointReference
containing any of the other optional elements, the BPEL engine will throw a fault when we try and invoke the partner link.
To do this, we used a transformation activity rather than an Assign activity, since Assign will create all optional elements as well (we could still use an Assign, but we would need to add a remove
rule for each of these elements). Once done, we inserted this into the Service-Ref
variable.
Once we have created the Service-Ref
variable, we just map it to the partner link before invoking the service, and BPEL will dynamically route the request to the updated endpoint.
Oracle Service Bus also enables the dynamic routing of web service invocations at runtime.
If you are implementing a solution where OSB provides a virtualization layer on top of all your external services, we would recommend that as the appropriate place to implement dynamic routing.
However, if you are only using the core Oracle SOA Suite (minus the OSB), this isn't an option. In addition, there are occasions where you may want to dynamically assemble SCA composites to build a dynamic end-to-end business process. In this scenario, dynamic partner links can prove extremely useful.