You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ode.apache.org by Milinda Pathirage <mi...@gmail.com> on 2009/02/19 15:29:24 UTC

SOAP Header handling issue in ODE 1.X branch - Axis2 Integration

When handling SOAP Header parts in WSDL message, following methods are used
from SoapMessageConverter.java.

public void createSoapHeaders(SOAPEnvelope soapEnv, List<SOAPHeader>
headerDefs, Message msgdef, Map<String,Node> headers) throws AxisFault

private void handleSoapHeaderDef(SOAPEnvelope soapEnv, SOAPHeader headerdef,
Message msgdef, Map<String, Node> headers) throws AxisFault

Due to some issue with org.apache.ode.bpel.iapi.Message logic getHeaderParts
method returns a empty map. So even though there header parts in your WSDL,
ODE will not send requests to external services with header and not send
SOAP headers in response message.

Even though there are no value in headers map, there is header parts
corresponding to headerDefs inside bpel Message. I have experienced that
when there header parts in input and output messages of WSDL operations.

We get the DOM Element for those headerDefs by using message.getPart method.
I think it's better to pass bpel.iapi.Message to createSoapHeaders, and
handleSoapHeaderDef methods and implement those method as follows.

 public void createSoapHeaders(SOAPEnvelope soapEnv, List<SOAPHeader>
headerDefs, Message msgdef, org.apache.ode.bpel.iapi.Message message) throws
AxisFault {
        for (SOAPHeader sh : headerDefs) handleSoapHeaderDef(soapEnv, sh,
msgdef, message);

        org.apache.axiom.soap.SOAPHeader soaphdr = soapEnv.getHeader();
        if (soaphdr == null) soaphdr =
_soapFactory.createSOAPHeader(soapEnv);

        SOAPHeaderBlock soapHeaderBlock = null;
        for (Element headerElmt : message.getHeaderParts().values()) {
            if (soaphdr.getFirstChildWithName(new
QName(headerElmt.getNamespaceURI(), headerElmt.getLocalName())) == null) {
                OMElement omElement = OMUtils.toOM(headerElmt,
_soapFactory);
                soapHeaderBlock =
_soapFactory.createSOAPHeaderBlock(omElement.getQName().getLocalPart(),
omElement.getNamespace());
                for (Iterator iter = omElement.getChildren();
iter.hasNext();) {
                    soapHeaderBlock.addChild((OMNode) iter.next());
                }
                soaphdr.addChild(soapHeaderBlock);
            }
        }

    }

    @SuppressWarnings("unchecked")
    private void handleSoapHeaderDef(SOAPEnvelope soapEnv, SOAPHeader
headerdef, Message msgdef, org.apache.ode.bpel.iapi.Message message) throws
AxisFault {
        boolean payloadMessageHeader = headerdef.getMessage() == null ||
headerdef.getMessage().equals(msgdef.getQName());

        if (headerdef.getPart() == null) return;

        if (payloadMessageHeader && msgdef.getPart(headerdef.getPart()) ==
null)
            throw new
OdeFault(__msgs.msgSoapHeaderReferencesUnkownPart(headerdef.getPart()));

        Element srcPartEl = null;
        if (message.getHeaderParts().size() > 0)
            if (payloadMessageHeader)
                srcPartEl =
message.getHeaderParts().get(headerdef.getPart());

        // We don't complain about missing header data unless they are part
of the message payload. This is
        // because AXIS may be providing these headers.
        if (srcPartEl == null && payloadMessageHeader){
            if(message.getPart(headerdef.getPart()) != null){
                srcPartEl = message.getPart(headerdef.getPart());
            }else{
                throw new
OdeFault(__msgs.msgOdeMessageMissingRequiredPart(headerdef.getPart()));
            }
        }

        if (srcPartEl == null) return;

        org.apache.axiom.soap.SOAPHeader soaphdr = soapEnv.getHeader();
        if (soaphdr == null) {
            soaphdr = _soapFactory.createSOAPHeader(soapEnv);
        }

        OMElement omPart = OMUtils.toOM(srcPartEl, _soapFactory);
        for (Iterator<OMNode> i = omPart.getChildren(); i.hasNext();)
            soaphdr.addChild(i.next());
    }

I have tested above code with SOAP headers in BPEL messagesand without SOAP
headers. If you guys are ok with this fix I can commit ot both trunk and 1.X
branch.

Also there is a typo in createSoapResponse method.

if (message.getHeaderParts().size() > 0 || getSOAPHeaders(bo).size() > 0)
            createSoapHeaders(soapEnv, getSOAPHeaders(bo),
op.getInput().getMessage(), message.getHeaderParts());

the above must change to

if (message.getHeaderParts().size() > 0 || getSOAPHeaders(bo).size() > 0)
            createSoapHeaders(soapEnv, getSOAPHeaders(bo),
op.getOutput().getMessage(), message);



Thanks,
Milinda

-- 
http://mpathirage.com
http://wso2.org "Oxygen for Web Service Developers"
http://wsaxc.blogspot.com "Web Services With Axis2/C"

Re: SOAP Header handling issue in ODE 1.X branch - Axis2 Integration

Posted by Milinda Pathirage <mi...@gmail.com>.
I can't run the existing tests in my machine due to some problem. I have
attached two patch files(One for 1.x and one for trunk) for SOAP header
issue. Can you please check whether there are existing functionality break
due to these patches.

Test issues 1.X branch:

Couldn't find resource on the class path: testng.css
The following tests failed:
org.apache.ode.axis2.management.InstanceManagementTest
rake aborted!
Tests failed!

trunk:

===============================================
ode:axis2-war
Total tests run: 5, Failures: 0, Skips: 0
===============================================

The following tests failed:
org.apache.ode.axis2.management.DeploymentTest
org.apache.ode.axis2.management.InstanceManagementTest
[Failed] Your build failed with an error: /home/milinda/Apache/ode_trunk:
Tests failed!
buildr aborted!
Tests failed!


Thanks,
Milinda

On Thu, Feb 19, 2009 at 8:05 PM, Alex Boisvert <bo...@intalio.com> wrote:

> +1 to fixing this and adding appropriate test cases.
>
> alex
>
>
> On Thu, Feb 19, 2009 at 6:29 AM, Milinda Pathirage <
> milinda.pathirage@gmail.com> wrote:
>
> > When handling SOAP Header parts in WSDL message, following methods are
> used
> > from SoapMessageConverter.java.
> >
> > public void createSoapHeaders(SOAPEnvelope soapEnv, List<SOAPHeader>
> > headerDefs, Message msgdef, Map<String,Node> headers) throws AxisFault
> >
> > private void handleSoapHeaderDef(SOAPEnvelope soapEnv, SOAPHeader
> > headerdef,
> > Message msgdef, Map<String, Node> headers) throws AxisFault
> >
> > Due to some issue with org.apache.ode.bpel.iapi.Message logic
> > getHeaderParts
> > method returns a empty map. So even though there header parts in your
> WSDL,
> > ODE will not send requests to external services with header and not send
> > SOAP headers in response message.
> >
> > Even though there are no value in headers map, there is header parts
> > corresponding to headerDefs inside bpel Message. I have experienced that
> > when there header parts in input and output messages of WSDL operations.
> >
> > We get the DOM Element for those headerDefs by using message.getPart
> > method.
> > I think it's better to pass bpel.iapi.Message to createSoapHeaders, and
> > handleSoapHeaderDef methods and implement those method as follows.
> >
> >  public void createSoapHeaders(SOAPEnvelope soapEnv, List<SOAPHeader>
> > headerDefs, Message msgdef, org.apache.ode.bpel.iapi.Message message)
> > throws
> > AxisFault {
> >        for (SOAPHeader sh : headerDefs) handleSoapHeaderDef(soapEnv, sh,
> > msgdef, message);
> >
> >        org.apache.axiom.soap.SOAPHeader soaphdr = soapEnv.getHeader();
> >        if (soaphdr == null) soaphdr =
> > _soapFactory.createSOAPHeader(soapEnv);
> >
> >        SOAPHeaderBlock soapHeaderBlock = null;
> >        for (Element headerElmt : message.getHeaderParts().values()) {
> >            if (soaphdr.getFirstChildWithName(new
> > QName(headerElmt.getNamespaceURI(), headerElmt.getLocalName())) == null)
> {
> >                OMElement omElement = OMUtils.toOM(headerElmt,
> > _soapFactory);
> >                soapHeaderBlock =
> > _soapFactory.createSOAPHeaderBlock(omElement.getQName().getLocalPart(),
> > omElement.getNamespace());
> >                for (Iterator iter = omElement.getChildren();
> > iter.hasNext();) {
> >                    soapHeaderBlock.addChild((OMNode) iter.next());
> >                }
> >                soaphdr.addChild(soapHeaderBlock);
> >            }
> >        }
> >
> >    }
> >
> >    @SuppressWarnings("unchecked")
> >    private void handleSoapHeaderDef(SOAPEnvelope soapEnv, SOAPHeader
> > headerdef, Message msgdef, org.apache.ode.bpel.iapi.Message message)
> throws
> > AxisFault {
> >        boolean payloadMessageHeader = headerdef.getMessage() == null ||
> > headerdef.getMessage().equals(msgdef.getQName());
> >
> >        if (headerdef.getPart() == null) return;
> >
> >        if (payloadMessageHeader && msgdef.getPart(headerdef.getPart()) ==
> > null)
> >            throw new
> > OdeFault(__msgs.msgSoapHeaderReferencesUnkownPart(headerdef.getPart()));
> >
> >        Element srcPartEl = null;
> >        if (message.getHeaderParts().size() > 0)
> >            if (payloadMessageHeader)
> >                srcPartEl =
> > message.getHeaderParts().get(headerdef.getPart());
> >
> >        // We don't complain about missing header data unless they are
> part
> > of the message payload. This is
> >        // because AXIS may be providing these headers.
> >        if (srcPartEl == null && payloadMessageHeader){
> >            if(message.getPart(headerdef.getPart()) != null){
> >                srcPartEl = message.getPart(headerdef.getPart());
> >            }else{
> >                throw new
> > OdeFault(__msgs.msgOdeMessageMissingRequiredPart(headerdef.getPart()));
> >            }
> >        }
> >
> >        if (srcPartEl == null) return;
> >
> >        org.apache.axiom.soap.SOAPHeader soaphdr = soapEnv.getHeader();
> >        if (soaphdr == null) {
> >            soaphdr = _soapFactory.createSOAPHeader(soapEnv);
> >        }
> >
> >        OMElement omPart = OMUtils.toOM(srcPartEl, _soapFactory);
> >        for (Iterator<OMNode> i = omPart.getChildren(); i.hasNext();)
> >            soaphdr.addChild(i.next());
> >    }
> >
> > I have tested above code with SOAP headers in BPEL messagesand without
> SOAP
> > headers. If you guys are ok with this fix I can commit ot both trunk and
> > 1.X
> > branch.
> >
> > Also there is a typo in createSoapResponse method.
> >
> > if (message.getHeaderParts().size() > 0 || getSOAPHeaders(bo).size() > 0)
> >            createSoapHeaders(soapEnv, getSOAPHeaders(bo),
> > op.getInput().getMessage(), message.getHeaderParts());
> >
> > the above must change to
> >
> > if (message.getHeaderParts().size() > 0 || getSOAPHeaders(bo).size() > 0)
> >            createSoapHeaders(soapEnv, getSOAPHeaders(bo),
> > op.getOutput().getMessage(), message);
> >
> >
> >
> > Thanks,
> > Milinda
> >
> > --
> > http://mpathirage.com
> > http://wso2.org "Oxygen for Web Service Developers"
> > http://wsaxc.blogspot.com "Web Services With Axis2/C"
> >
>



-- 
http://mpathirage.com
http://wso2.org "Oxygen for Web Service Developers"
http://wsaxc.blogspot.com "Web Services With Axis2/C"

Re: SOAP Header handling issue in ODE 1.X branch - Axis2 Integration

Posted by Alex Boisvert <bo...@intalio.com>.
+1 to fixing this and adding appropriate test cases.

alex


On Thu, Feb 19, 2009 at 6:29 AM, Milinda Pathirage <
milinda.pathirage@gmail.com> wrote:

> When handling SOAP Header parts in WSDL message, following methods are used
> from SoapMessageConverter.java.
>
> public void createSoapHeaders(SOAPEnvelope soapEnv, List<SOAPHeader>
> headerDefs, Message msgdef, Map<String,Node> headers) throws AxisFault
>
> private void handleSoapHeaderDef(SOAPEnvelope soapEnv, SOAPHeader
> headerdef,
> Message msgdef, Map<String, Node> headers) throws AxisFault
>
> Due to some issue with org.apache.ode.bpel.iapi.Message logic
> getHeaderParts
> method returns a empty map. So even though there header parts in your WSDL,
> ODE will not send requests to external services with header and not send
> SOAP headers in response message.
>
> Even though there are no value in headers map, there is header parts
> corresponding to headerDefs inside bpel Message. I have experienced that
> when there header parts in input and output messages of WSDL operations.
>
> We get the DOM Element for those headerDefs by using message.getPart
> method.
> I think it's better to pass bpel.iapi.Message to createSoapHeaders, and
> handleSoapHeaderDef methods and implement those method as follows.
>
>  public void createSoapHeaders(SOAPEnvelope soapEnv, List<SOAPHeader>
> headerDefs, Message msgdef, org.apache.ode.bpel.iapi.Message message)
> throws
> AxisFault {
>        for (SOAPHeader sh : headerDefs) handleSoapHeaderDef(soapEnv, sh,
> msgdef, message);
>
>        org.apache.axiom.soap.SOAPHeader soaphdr = soapEnv.getHeader();
>        if (soaphdr == null) soaphdr =
> _soapFactory.createSOAPHeader(soapEnv);
>
>        SOAPHeaderBlock soapHeaderBlock = null;
>        for (Element headerElmt : message.getHeaderParts().values()) {
>            if (soaphdr.getFirstChildWithName(new
> QName(headerElmt.getNamespaceURI(), headerElmt.getLocalName())) == null) {
>                OMElement omElement = OMUtils.toOM(headerElmt,
> _soapFactory);
>                soapHeaderBlock =
> _soapFactory.createSOAPHeaderBlock(omElement.getQName().getLocalPart(),
> omElement.getNamespace());
>                for (Iterator iter = omElement.getChildren();
> iter.hasNext();) {
>                    soapHeaderBlock.addChild((OMNode) iter.next());
>                }
>                soaphdr.addChild(soapHeaderBlock);
>            }
>        }
>
>    }
>
>    @SuppressWarnings("unchecked")
>    private void handleSoapHeaderDef(SOAPEnvelope soapEnv, SOAPHeader
> headerdef, Message msgdef, org.apache.ode.bpel.iapi.Message message) throws
> AxisFault {
>        boolean payloadMessageHeader = headerdef.getMessage() == null ||
> headerdef.getMessage().equals(msgdef.getQName());
>
>        if (headerdef.getPart() == null) return;
>
>        if (payloadMessageHeader && msgdef.getPart(headerdef.getPart()) ==
> null)
>            throw new
> OdeFault(__msgs.msgSoapHeaderReferencesUnkownPart(headerdef.getPart()));
>
>        Element srcPartEl = null;
>        if (message.getHeaderParts().size() > 0)
>            if (payloadMessageHeader)
>                srcPartEl =
> message.getHeaderParts().get(headerdef.getPart());
>
>        // We don't complain about missing header data unless they are part
> of the message payload. This is
>        // because AXIS may be providing these headers.
>        if (srcPartEl == null && payloadMessageHeader){
>            if(message.getPart(headerdef.getPart()) != null){
>                srcPartEl = message.getPart(headerdef.getPart());
>            }else{
>                throw new
> OdeFault(__msgs.msgOdeMessageMissingRequiredPart(headerdef.getPart()));
>            }
>        }
>
>        if (srcPartEl == null) return;
>
>        org.apache.axiom.soap.SOAPHeader soaphdr = soapEnv.getHeader();
>        if (soaphdr == null) {
>            soaphdr = _soapFactory.createSOAPHeader(soapEnv);
>        }
>
>        OMElement omPart = OMUtils.toOM(srcPartEl, _soapFactory);
>        for (Iterator<OMNode> i = omPart.getChildren(); i.hasNext();)
>            soaphdr.addChild(i.next());
>    }
>
> I have tested above code with SOAP headers in BPEL messagesand without SOAP
> headers. If you guys are ok with this fix I can commit ot both trunk and
> 1.X
> branch.
>
> Also there is a typo in createSoapResponse method.
>
> if (message.getHeaderParts().size() > 0 || getSOAPHeaders(bo).size() > 0)
>            createSoapHeaders(soapEnv, getSOAPHeaders(bo),
> op.getInput().getMessage(), message.getHeaderParts());
>
> the above must change to
>
> if (message.getHeaderParts().size() > 0 || getSOAPHeaders(bo).size() > 0)
>            createSoapHeaders(soapEnv, getSOAPHeaders(bo),
> op.getOutput().getMessage(), message);
>
>
>
> Thanks,
> Milinda
>
> --
> http://mpathirage.com
> http://wso2.org "Oxygen for Web Service Developers"
> http://wsaxc.blogspot.com "Web Services With Axis2/C"
>