We often come across challenges where we need to invoke different services based on certain conditions. These conditions may or may not be readily available during code implementation but are provided as input only at runtime. In such a scenario where all services need to be invoked in particular sequence, we need the ability to orchestrate the flow dynamically.
In this post, we will go through how this problem was solved using IBM BPM Advanced using a BPEL process flow.
Use Case: For one of our clients at Prolifics, we had a scenario where there were multiple services to be invoked in the process application. The challenge was that this list of services to be executed and the sequence in which they should be invoked was required to be kept configurable and was decided based on certain business parameters. This list of services and their sequences had to be kept modifiable at runtime and had to take effect as soon as the changes were made.
Solution: The process application was developed as a long-running BPEL process flow using IBM BPM Advanced version 8.5.6. Find the screenshot of the Assembly and Implementation diagram below:
The BPEL flow is exposed as a web service by WebService binding.
ComServiceImpl implementation diagram:
The list of services and their sequences was maintained in the IBM ODM server, which provides the configuration scope and the required robustness.
Let’s go through each of the important steps in a bit more detail.
Step 1: Receive input
This step accepts the input provided to the process application. In this case, the input is a business object called “CustomerOrderBO.”
Step 2: Invoke Rules Engine/IBM ODM service
Pass “CustomerOrderBO” as the input to the ODM server, as shown below.
This Rules Engine/ODM server service invocation returns a business object which contains details about all the services and the sequence numbers in which those services should be invoked in the following steps.
Step 3: Iterate for the list of services to be invoked using “ForEach” component, using sequence number as the iterator
Iterate the “ForEach” loop for the sequence numbers from 1 to N, and pass the service name to be invoked as the input.
Step 4: Create endpoint URL for service invocation based on the output from the previous step
This is the “Invoke” activity named “InvokeDynamicService.” Here we create the endpoint URL based on the service name that was passed as the input.
This is implemented as a SCA component, which contains a mediation module to dynamically generate the endpoint URL. Once the URL is built, we use SCAImport (we can have different bindings as needed) to invoke the services using the URL.
A deeper look into the “ServiceIntegrationImpl” mediation module is shown below. Here the “BOMapper1” primitive takes care of generating the SCA endpoint URL based on inputs passed.
Refer the diagram below.
Refer the BO mapping implementation used in BOMapper1 to achieve the objective.
Here the “scaEndPoint” field from the input business object contains the name of the service that needs to be invoked in the current iteration. We use custom mapping in this case, with the code shown below used to formulate the target endpoint address that needs to be called under the “address” field of the output SMO in the SMOHeader section.
// The specific type of variable ServiceMessageObject_body_commonServiceCall_customerOrder_scaEndPoint is java.lang.String // The specific type of variable ServiceMessageObject_1_headers_SMOHeader_Target_address is java.lang.String //String targetUrl = "sca://BCRISServiceMed/BCRISServiceMedExport"; String targetUrl = "sca://"+ServiceMessageObject_body_commonServiceCall_customerOrder_scaEndPoint+"ServiceMed/" + ServiceMessageObject_body_commonServiceCall_customerOrder_scaEndPoint+"ServiceMedExport"; ServiceMessageObject_1_headers_SMOHeader_Target_address = targetUrl;
These lines of code above will build the endpoint URLs as seen below.
List of dynamically formed URLs:
sca://ActivationServiceMed/ActivationServiceMedExport sca://AMSSNM1ServiceMed/AMSSNM1ServiceMedExport sca://BCRISServiceMed/BCRISServiceMedExport sca://CCNSServiceMed/CCNSServiceMedExport sca://WFASServiceMed/WFASServiceMedExport
After this, the Service Invoke mediation primitive consumes this SMO to dynamically and iteratively invoke the desired service for all the services.
This SCA invocation goes to a different independent mode where the actual Service Invoke takes place. Here we can have the provision to invoke the downstream system in any protocol as needed (HTTP, JMS, SOAP WS, etc.). So if a new service is introduced after the application is deployed and running, we simply need to include the sequence number and name of this new service/system in the ODM response. The “ForEach” and the endpoint URL will also be formed automatically. For our objective, we just need to create a new SCA module like “BCRISServiceMed” or “WFASServiceMed” listed above, and simply invoke the actual downstream system in the mediation module.
Thus our objective of dynamic orchestration is achieved without changing any code in the main process flow just by adjusting the configuration.
Associate Technical Lead
Shivashankar Reddy is a Technical Professional in Integration Technologies with six years of experience in development, architecture, design, solutioning and sustenance covering all aspects of SDLC. His additional skills include the analysis, configuration and implementation of Node.js applications, Java, and AngularJS.