Sunday, November 4, 2007

Dynamic Partner Links in JBI

I've put together an example of using a dynamic partner link in OpenESB. This example shows the basics of assigning an EndpointReference to a partner link at runtime, and then invoking that partner link.

Below is the tutorial I've put together (really just some high level steps). I've also uploaded the tutorial and NetBeans modules I've created here.

Prerequisites:




Tutorial:

  • Step 1: Create a New BPEL Module


  • Step 2: Create a New SOAP WSDL with one request-response operation, and a simple BPEL process for the backend . We'll invoke this service dynamically later on.


  • Step 3: Add an External WSDL File from http://schemas.xmlsoap.org/ws/2004/08/addressing. The WS-Addressing WSDL defines the EndpointReference element that we'll need.
    • GOTCHA: NetBeans may add a character to the beginning of the wsdl when it imports. Make sure to remove this character. In some cases, this may be a hidden character that will only show up in an editor like VI.



  • Step 4: Create another SOAP WSDL with one request-response operation. This service will provide the dynamic partner link functionality.
    • Add a schema to the wsdl that defines an elment that accepts an EndpointReference and xsd:anyType.
    • Modify the request message accordingly






  • Step 5: Create another BPEL Process. This process should assign the EndpointReference to a PartnerLink and invoke it.





  • Step 6: Clean and Build the BPEL Module.


  • Step 7: Create a Composite Application and add your BPEL Module to it.


  • Step 8: Clean and Build the Composite Application.


  • Step 9: Correct the Composite Application's configuration using the CASA Editor.
    • Generated:


    • Corrected:



  • Step 10: Clean, Build, and Deploy the Composite Application Again


  • Step 11: Create a test case to invoke the service we created in step 2.




  • Step 12: Create another service to invoke, just as in Step 2. Make the BPEL process do something a little different so we will be able to tell which service was invoked.
    • This WSDL must have the same target namespace and operation to invoke as the WSDL in step 2.



  • Step 13: Create a second test case to invoke the new service you've created.





11 comments:

Anonymous said...

This DYNAMIC partnerlink still forces your end points to have the same "operation". This is a serious limitation from the BPEL engine.
How do you implement dynamic partner links -when your end points have different operation names. eg: EndPoint1 has operation called "processOrder" and EndPoint2 has operation called "processData" ?
Pl reply to sanjeev.sondur@oracle.com
Has this limitation been addressed ??

Chad Sturtz said...

Sanjeev,

I'll send this to you in an email as you requested, but I'd like to post my answer here as well.

I am unaware of any way to do what you're asking. In my example, and in every other dynamic partner link example I've seen, the only piece you can make dynamic is the EndpointReference. This is because the partner link is bound to the WSDL when it is created. By changing out the EndpointReference at runtime, all you're doing is pointing to a different concrete implementation of the abstract piece.

Really what you're asking for is the ability to use BPEL without being tied to a partner link or specific service. Or, you could look at it as trying to take a single partner link and at runtime, bind it to any WSDL you want. There are really two problems with this.

1) If you don't bind to the WSDL at process orchestration time, what will you map variables to and from? You have no operations and no message elements to map to.

2) Even if it were possible to bind your partner link to a different WSDL at runtime, you'd have to have this WSDL already imported so that your BPEL process had knowledge of it. And if that were the case, why not just create a partner link for each WSDL, and have some logic built into the BPEL process to decide which partner link to invoke?

If you do end up finding a way to do this, it's definitely something to write about. I have received numerous questions very similar to yours, so there are probably quite a few people out there trying to do the same thing you are.

Anonymous said...

I saw the example and i wanted to know if you can associate a endpointreference received from a WS to an endpoint deployed on the BUS, and if it is possible how can I do it?

Anonymous said...

Hello Chad, that's a nice tuorial. But I've some problems when adding the Service as EJb. I'm using Netbeans 6.5 and OpenESB. After implementing the Business Process, and after adding the JBI Module, I do a clean and Build, also step 8. But the CASA editor can not load the JBI Modules and hanks by reloading. Do you have an advice for me. Do I miss some Library for using dynamic partner links?
thanks in Advance for your reponse.

Anonymous said...

Sorry in the last comment, first sentence, i did mean adding the service module as JBI.

Anonymous said...

Hi.I build our DPL project and create a composite application. Deployed it, when i run test, i get a response :
"Caused by: java.lang.RuntimeException: BPJBI-6019: unable to resolve the service endpoint dynamically for the document fragment "
I use OpenEsb v.2.1 and NetBeans 6.5. Why i get a error?

Anonymous said...

Hi. I knew that, it is working features dinamic partner link. I saw our example on the site Wiki.openesb.org, openesb.org, but it is not working.
I use test and get a error :
com.sun.jbi.engine.bpel.core.bpel.exception.SystemException: BPCOR-7131: A fatal exception has occurred
BPCOR-6129: Line Number is 34
BPCOR-6130: Activity Name is Invoke1
at com.sun.jbi.engine.bpel.core.bpel.engine.impl.BPELInterpreter.createVirtualFaultUnit(BPELInterpreter.java:263)
at com.sun.jbi.engine.bpel.core.bpel.engine.impl.BPELInterpreter.execute(BPELInterpreter.java:218)
at com.sun.jbi.engine.bpel.core.bpel.engine.BusinessProcessInstanceThread.execute(BusinessProcessInstanceThread.java:98)
at com.sun.jbi.engine.bpel.core.bpel.engine.impl.BPELProcessManagerImpl.process(BPELProcessManagerImpl.java:1029)
at com.sun.jbi.engine.bpel.core.bpel.engine.impl.EngineImpl.process(EngineImpl.java:289)
at com.sun.jbi.engine.bpel.core.bpel.engine.impl.EngineImpl.process(EngineImpl.java:1291)
at com.sun.jbi.engine.bpel.BPELSEInOutThread.processRequest(BPELSEInOutThread.java:420)
at com.sun.jbi.engine.bpel.BPELSEInOutThread.processMsgEx(BPELSEInOutThread.java:252)
at com.sun.jbi.engine.bpel.BPELSEInOutThread.run(BPELSEInOutThread.java:183)
Caused by: java.lang.RuntimeException: BPJBI-6019: unable to resolve the service endpoint dynamically for the document fragment ...

at com.sun.jbi.engine.bpel.EngineChannel.invoke(EngineChannel.java:215)
at com.sun.jbi.engine.bpel.core.bpel.engine.impl.BPELProcessManagerImpl.invoke(BPELProcessManagerImpl.java:719)
at com.sun.jbi.engine.bpel.core.bpel.model.runtime.impl.InvokeUnitImpl.invoke(InvokeUnitImpl.java:395)
at com.sun.jbi.engine.bpel.core.bpel.model.runtime.impl.InvokeUnitImpl.doAction(InvokeUnitImpl.java:255)
at com.sun.jbi.engine.bpel.core.bpel.model.runtime.impl.CodeReUseHelper.executeChildActivities(CodeReUseHelper.java:65)
at com.sun.jbi.engine.bpel.core.bpel.model.runtime.impl.StructuredActivityUnitImpl.executeChildActivities(StructuredActivityUnitImpl.java:193)
at com.sun.jbi.engine.bpel.core.bpel.model.runtime.impl.StructuredActivityUnitImpl.doAction(StructuredActivityUnitImpl.java:93)
at com.sun.jbi.engine.bpel.core.bpel.model.runtime.impl.SequenceUnitImpl.doAction(SequenceUnitImpl.java:95)
at com.sun.jbi.engine.bpel.core.bpel.model.runtime.impl.CodeReUseHelper.executeChildActivities(CodeReUseHelper.java:65)
at com.sun.jbi.engine.bpel.core.bpel.model.runtime.impl.StructuredActivityUnitImpl.executeChildActivities(StructuredActivityUnitImpl.java:193)
at com.sun.jbi.engine.bpel.core.bpel.model.runtime.impl.BPELProcessInstanceImpl.doAction(BPELProcessInstanceImpl.java:650)
at com.sun.jbi.engine.bpel.core.bpel.engine.impl.BPELInterpreter.execute(BPELInterpreter.java:162)
... 7 more

I saw our source code, i found class NMRProcessor, what it have metod "ServiceEndpoint resolveEndpointReference(DocumentFragment document)".

it have cyrcle for:
HashMap instances = mPB.getInstances();

for (Iterator i = instances.keySet().iterator(); i.hasNext(); )
{
...

This cyrcle is not working, because the variable "instance" is empty. The variable "instance" get from class EventProcessor, it have initionalization , but it is empty. So variable se of type ServiceEndpoint is null, when caling the method "resolveEndpointReference". I compared revisions 1.6 and 1.5 of class EventProcessor , the version 1.5 have code is putting a variable "instance" and the version 1.6 have not that.

I hope, that you correct that error. When it will correct, write me please.
Thunks.

NN said...

Hi...
i need to learn dynamic partner link from scratch..
can any one give me step by step implementation..
please...

NN said...

hi...
I need to learn dynamic partner link from scratch..
can any one give me step bye step implementation on the same.
thank u

NN said...

hi...
I need to learn dynamic partner link from scratch..
can any one give me step bye step implementation on the same.
thank u

kop said...

Please, can you re-upload examples? The link is dead.