Ashwini Kumar Jeksani wrote:
Hi,

I'm trying to create a BPEL for asynchronous web service call. A snippet of it 
is shown below:

<!-Receive request from client -->
<receive createInstance="yes" operation="initiate " partnerLink="ApprovalProcessClient" 
portType="ns1:approvalProcessPT" variable="approvalProcessRequestMessage"/>

<!-Asynchronous Web Service Invoke -->
<invoke inputVariable="asyncApprovalRequest" operation="submitForApproval" 
partnerLink="AsyncApprovalPartner" portType="ns2:asyncApprovalServicePT">
         <correlations>
            <correlation initiate="yes" pattern="request" set="CS1"/>
         </correlations>
</invoke>
<!-Receive Response from Asynchronous Web Service invoked above -- >
<receive operation="onResult" partnerLink=" AsyncApprovalPartner " 
portType="ns1:asyncApprovalCallbackPT" variable="asyncApprovalResponse">
         <correlations>
            <correlation initiate="no" set="CS1"/>
         </correlations>
</receive>

The first receive in the above BPEL snippet is called by a client and therefore 
I have declared it as a 'service' in componentType file.
The invoke is for invoking an asynchronous web service operation. The portType 
of that I have declared as 'reference' in the componentType file.
The second receive in the above BPEL snippet acts as a callback to receive 
response from an asynchronous web service. Where and How do I specify that this 
is a callback? Is there way of specifying callbacks in componentType file.?

Thanks & Regards
Ashwini Kumar Jeksani

Ashwini,

** WARNING - Long Post **

You're certainly going in the right direction here.

One way of specifying that a callback interface is in use is to declare it in the SCDL files - in particular in the componentType file, using something like this:

<interface.java interface="services.invoicing.ComputePrice"                     
   
                callbackInterface="services.invoicing.InvoiceCallback"/>

This isn't the only way of specifying the callback, at least for Java interfaces, since it is possible to use annotations within the interface files, such as:

@Remotable
@Callback(MyServiceCallback.class)
public interface MyService {

    @OneWay
    void someMethod(String arg);
}

...and...

@Remotable
public interface MyServiceCallback {

    void receiveResult(String result);
}

Note the @Callback annotation in the forward call interface, which points at the callback interface.

However, there is nothing like this available in WSDL.

Instead, a WSDL file can contain multiple service definitions (ie PortTypes) - and so a single WSDL can hold both the forward and callback interfaces, which might look something like this:

....

    <wsdl:portType name="MyService">
        <wsdl:operation name="someMethod">
            <wsdl:input message="tns:someMethodRequest"
                        name="someMethodRequest"/>
        </wsdl:operation>
    </wsdl:portType>

    <wsdl:portType name="MyServiceCallback">
        <wsdl:operation name="receiveResult">
            <wsdl:input message="tns:receiveResultRequest"
                        name="receiveResultRequest"/>
            <wsdl:output message="tns:receiveResultResponse"
                         name="receiveResultResponse"/>
        </wsdl:operation>
    </wsdl:portType>

....

In the SCDL which references a WSDL like this, in the component type and in any relevant composite file, then it would look like this:

<interface.wsdl
interface="http://simplecallback#wsdl.interface(MyService)" callbackInterface="http://simplecallback#wsdl.interface(MyServiceCallback)" />

When you set up a component which uses Web services the SCDL will look something like this:

<component name="MyServiceComponent">
  <implementation.java class="simplecallback.MyServiceImpl" />
  <service name="MyService">
    <interface.wsdl
interface="http://simplecallback#wsdl.interface(MyService)"
callbackInterface="http://simplecallback#wsdl.interface(MyServiceCallback)"/>
<binding.ws wsdlElement="http://simplecallback#wsdl.port(MyServiceSoapService/MyServiceSoapPort)"/>
<callback>
<binding.ws wsdlElement="http://simplecallback#wsdl.port(MyServiceCallbackSoapService/MyServiceCallbackSoapPort)"/>
</callback>
</service>
</component>

Excuse the formatting - it does not fit well into the width limits.

Of course, the WSDL that you produce will also have to have the BPEL PartnerLinkType elements pointing to the appropriate PortType elements.

I think that's it...

...you can see an example of this in the simple-callback-ws sample in Tuscany.

BTW, what I am working on right now is the code to eliminate the need to build the componentType file. The BPELDocumentProcessor code is bing modified to read the BPEL process file and also to follow the links to the WSDL files and to resolve the PartnerLink -> PartnerLinkType -> PortType chains. This will result in the generation of the component type interface definition as above, with a reference to the PortType for forward and callback interfaces.

I should post some code in the next couple of days.


Yours,  Mike.






Reply via email to