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"

Reply via email to