You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cxf.apache.org by "Nolan, Edell" <Ed...@iona.com> on 2008/02/21 13:50:34 UTC

potential bug with the way DocLiteral matches its params to pick the correct operation.

Hi,

 

I am trying to verify that this is a bug before I create a jira.

 

I have a PortType that has two operations and I have implemented a Soap
binding using Document Literal.

 

String Op1(Type1);

String Op2(Type1, inout Type2)

 

When I try to invoke the first operation -The server side trys to
execute Op2 and not op1. 

 

Basically what appears to be happening is it is trying to match the
first parameter and when it gets that match - it chooses the operation
and continues. It searches through the list of operations and in this
case op2 is first in the list so the first param will match.

 

The code where I see this happening is 

 

It does a call from the DocLiteralInInterceptor.java

 

  if (msgInfo != null && msgInfo.getMessageParts() != null 

                    && msgInfo.getMessageParts().size() > 0) {

                    assert msgInfo.getMessageParts().size() > paramNum;

                    p = msgInfo.getMessageParts().get(paramNum);

                } else {

                    p = findMessagePart(exchange, operations, elName,
client, paramNum);

                }

 

.....

 

In AbstractInDatabindingInterceptor.java

 

  protected MessagePartInfo findMessagePart(Exchange exchange,
Collection<OperationInfo> operations,

                                              QName name, boolean
client, int index) {

        Endpoint ep = exchange.get(Endpoint.class);

        MessagePartInfo lastChoice = null;

        for (Iterator<OperationInfo> itr = operations.iterator();
itr.hasNext();) {

            OperationInfo op = itr.next();

 

            BindingOperationInfo boi =
ep.getEndpointInfo().getBinding().getOperation(op);

            if (boi == null) {

                continue;

            }

            BindingMessageInfo msgInfo = null;

            if (client) {

                msgInfo = boi.getOutput();

            } else {

                msgInfo = boi.getInput();

            }

 

            if (msgInfo == null) {

                itr.remove();

                continue;

            }

            

            Collection bodyParts = msgInfo.getMessageParts();

            if (bodyParts.size() == 0 || bodyParts.size() <= index) {

                itr.remove();

                continue;

            }

 

            MessagePartInfo p =
(MessagePartInfo)msgInfo.getMessageParts().get(index);

            if (name.getNamespaceURI() == null ||
name.getNamespaceURI().length() == 0) {

                // message part has same namespace with the message

                name = new
QName(p.getMessageInfo().getName().getNamespaceURI(),
name.getLocalPart());

            }

            if (name.equals(p.getConcreteName())) {

                exchange.put(BindingOperationInfo.class, boi);

                exchange.put(OperationInfo.class,
boi.getOperationInfo());

                exchange.setOneWay(op.isOneWay());

                return p;

            }

 

            if (XSD_ANY.equals(p.getTypeQName())) {

                lastChoice = p;

            } else {

                itr.remove();

            }

        }

        return lastChoice;

    }    

 

 

Should it also try to match the number of params as well or is this a
requirement 

where all the parameters need to be different ?

 

 

Thanks, Edell.

 

 

 


----------------------------
IONA Technologies PLC (registered in Ireland)
Registered Number: 171387
Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland

Re: potential bug with the way DocLiteral matches its params to pick the correct operation.

Posted by Daniel Kulp <dk...@apache.org>.

I assume you are talking about doc/lit/bare service judging from the code 
path.   In that case, the bug is logged at:

https://issues.apache.org/jira/browse/CXF-1073

That said, it's not really a high priority as such a service would not be 
WSI-BP compliant and you're likely to run into all kinds of 
interopability issues.   WSI-BP mandates one "part" per message in the 
wsdl for doc/lit.   

One reason it's "hard" to support is that it would completely break 
streaming of reading the parts.   We would pretty much need to suck in 
the entire soap message, look at all the top level element names to 
match the parts to the operation, then finally read into the proper 
types.   Preformance would kind of suck.


My suggestion would be to switch it to a default wrapped doc/lit form.

That said, another workaround would be to add a unique soap action to 
each operation.   The SOAPActionInInterceptor can then determine the 
operation ahead of time.    Again, it's out of WSI-BP spec so you may 
run into issues with other toolkits.

Dan



On Thursday 21 February 2008, Nolan, Edell wrote:
> Hi,
>
>
>
> I am trying to verify that this is a bug before I create a jira.
>
>
>
> I have a PortType that has two operations and I have implemented a
> Soap binding using Document Literal.
>
>
>
> String Op1(Type1);
>
> String Op2(Type1, inout Type2)
>
>
>
> When I try to invoke the first operation -The server side trys to
> execute Op2 and not op1.
>
>
>
> Basically what appears to be happening is it is trying to match the
> first parameter and when it gets that match - it chooses the operation
> and continues. It searches through the list of operations and in this
> case op2 is first in the list so the first param will match.
>
>
>
> The code where I see this happening is
>
>
>
> It does a call from the DocLiteralInInterceptor.java
>
>
>
>   if (msgInfo != null && msgInfo.getMessageParts() != null
>
>                     && msgInfo.getMessageParts().size() > 0) {
>
>                     assert msgInfo.getMessageParts().size() >
> paramNum;
>
>                     p = msgInfo.getMessageParts().get(paramNum);
>
>                 } else {
>
>                     p = findMessagePart(exchange, operations, elName,
> client, paramNum);
>
>                 }
>
>
>
> .....
>
>
>
> In AbstractInDatabindingInterceptor.java
>
>
>
>   protected MessagePartInfo findMessagePart(Exchange exchange,
> Collection<OperationInfo> operations,
>
>                                               QName name, boolean
> client, int index) {
>
>         Endpoint ep = exchange.get(Endpoint.class);
>
>         MessagePartInfo lastChoice = null;
>
>         for (Iterator<OperationInfo> itr = operations.iterator();
> itr.hasNext();) {
>
>             OperationInfo op = itr.next();
>
>
>
>             BindingOperationInfo boi =
> ep.getEndpointInfo().getBinding().getOperation(op);
>
>             if (boi == null) {
>
>                 continue;
>
>             }
>
>             BindingMessageInfo msgInfo = null;
>
>             if (client) {
>
>                 msgInfo = boi.getOutput();
>
>             } else {
>
>                 msgInfo = boi.getInput();
>
>             }
>
>
>
>             if (msgInfo == null) {
>
>                 itr.remove();
>
>                 continue;
>
>             }
>
>
>
>             Collection bodyParts = msgInfo.getMessageParts();
>
>             if (bodyParts.size() == 0 || bodyParts.size() <= index) {
>
>                 itr.remove();
>
>                 continue;
>
>             }
>
>
>
>             MessagePartInfo p =
> (MessagePartInfo)msgInfo.getMessageParts().get(index);
>
>             if (name.getNamespaceURI() == null ||
> name.getNamespaceURI().length() == 0) {
>
>                 // message part has same namespace with the message
>
>                 name = new
> QName(p.getMessageInfo().getName().getNamespaceURI(),
> name.getLocalPart());
>
>             }
>
>             if (name.equals(p.getConcreteName())) {
>
>                 exchange.put(BindingOperationInfo.class, boi);
>
>                 exchange.put(OperationInfo.class,
> boi.getOperationInfo());
>
>                 exchange.setOneWay(op.isOneWay());
>
>                 return p;
>
>             }
>
>
>
>             if (XSD_ANY.equals(p.getTypeQName())) {
>
>                 lastChoice = p;
>
>             } else {
>
>                 itr.remove();
>
>             }
>
>         }
>
>         return lastChoice;
>
>     }
>
>
>
>
>
> Should it also try to match the number of params as well or is this a
> requirement
>
> where all the parameters need to be different ?
>
>
>
>
>
> Thanks, Edell.
>
>
>
>
>
>
>
>
> ----------------------------
> IONA Technologies PLC (registered in Ireland)
> Registered Number: 171387
> Registered Address: The IONA Building, Shelbourne Road, Dublin 4,
> Ireland



-- 
J. Daniel Kulp
Principal Engineer, IONA
dkulp@apache.org
http://www.dankulp.com/blog