Friday, September 14, 2012

SOAP envelope/body/header manipulation in BPEL 11g

We had some stringent requirement for one of the SOAP based web service, e.g.
  • custom soap header element needed to have mustUnderstand flag. 
  • In soap body we had some xsd:any with no namespace, and it is very hard to work with XSD any in BPEL 
So here is the approach which worked like a charm, and probably can be used where we need to have full control over SOAP envelope. Basically, use HTTP binding. Steps:

  • Created HTTP Binding as following



  •  Assigned entire soap envelope as I wanted to envelope variable using oraext:parseEscapedXML
oraext:parseEscapedXML('

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:prov="http://xmlns.oracle.com/OIM/provisioning">
   <soapenv:Header>
      <wsa1:OIMUser soapenv:mustUnderstand="0" xmlns:wsa1="http://xmlns.oracle.com/OIM/provisioning">
         <wsa1:OIMUserId>**</wsa1:OIMUserId>
         <wsa1:OIMUserPassword>**</wsa1:OIMUserPassword>
      </wsa1:OIMUser>
   </soapenv:Header>
   <soapenv:Body>
      <m:processRequest xmlns:m="http://xmlns.oracle.com/OIM/provisioning">
         <sOAPElement>
            <addRequest returnData="everything" xmlns="urn:oasis:names:tc:SPML:2:0" xmlns:dsml="urn:oasis:names:tc:DSML:2:0:core">
             </data>
            </addRequest>
         </sOAPElement>
      </m:processRequest>
   </soapenv:Body>
</soapenv:Envelope>

')

  •  Upon return we can directly get Body or entire Envelope using
ora:getContentAsString($envelope/ns1:Body)

Code Download

7 comments:

yael said...

Hello Chintan,
I'm trying to do it with bpel 10g.
is it possible?

yael

Chintan Shah said...

I haven't tried but I believe so, but have to do quite a bit of hand coding.

If you use HTTP binding 10g with POST method and create SOAP envelope using the same method, it should work.

alexproisdg said...
This comment has been removed by the author.
alexproisdg said...

Hello, Chintan.

I downloaded your code and tried execute it, but i have faced some problems.

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsa="http://www.w3.org/2005/08/addressing">
<env:Header></env:Header>
<env:Body>
<env:Envelope xmlns:prov="http://xmlns.oracle.com/OIM/provisioning"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<wsa1:OIMUser xmlns:wsa1="http://xmlns.oracle.com/OIM/provisioning"
soapenv:mustUnderstand="0">
<wsa1:OIMUserId>IDM_Admin</wsa1:OIMUserId>
<wsa1:OIMUserPassword>P@ssw0rd</wsa1:OIMUserPassword>
</wsa1:OIMUser>
</soapenv:Header>
<soapenv:Body>
<m:processRequest xmlns:m="http://xmlns.oracle.com/OIM/provisioning">
<sOAPElement>
<addRequest xmlns="urn:oasis:names:tc:SPML:2:0"
xmlns:dsml="urn:oasis:names:tc:DSML:2:0:core"
returnData="everything">
<data>
<dsml:attr name="objectclass">
<dsml:value>Users</dsml:value>
</dsml:attr>
<dsml:attr name="Users.User ID">
...
...

Request was generated like this. soap:Envelope was generated two times. Can you give me any advise or solution to solve this problem. Thanks for any help.

Chintan Shah said...

That's strange. I checked the code, it is assigning envlope to envelop. If you assign envelope to body, that might be issue. Are you using the downloaded code or your own code? Is it WS binding or HTTP binding?

alexproisdg said...

It's very strange. I only download your example and deploy it.

Chintan Shah said...

umm, I think this is what is going on. In my example (OID service) takes entire SOAP envelope payload inside the payload probably that might be causing the problem.

But I am very sure I had it working the way it is for OID service.

Let me know if you can call your service with HTTP binding or I can try to come up with example which calls HelloWorld SOAP service and integrate it with current example.