Hi,

   Having a look at how Apache Muse generates a response for a given
request, one can state that it is generating the XML response under
soap:body using org.apache.muse.core.routing.ReflectionMessageHandler.toXML()
(in the standard configuration).

   There, Apache Muse asks the resource for the implementation of the
capability and serializes the response for XML embedding in the  SOAP
response message. Before that, the name of the XML element to embed in the
response is generated using
org.apache.muse.core.routing.AbstractMessageHandler.createResponseName()  :


    private QName createResponseName()
    {
       QName request = getRequestName();
        String uri = request.getNamespaceURI();
        String name = request.getLocalPart();
        String prefix = request.getPrefix();

        return new QName(uri, name + "Response", prefix);
    }

   Here we can see that Apache Muse adds the suffix "Response" to the
LocalPart of the operation requested and so the xml is generated. Here we
have an example, the operation is named "GetArticulos", this is the request:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope";>
    <soap:Header>
        <wsa:To xmlns:wsa="http://www.w3.org/2005/08/addressing";>
http://192.168.200.128:8080/MyService/services/MyService</wsa:To>
        <wsa:Action xmlns:wsa="http://www.w3.org/2005/08/addressing";>
http://test/services/MyService/GetArticulos</wsa:Action>
        <wsa:MessageID xmlns:wsa="http://www.w3.org/2005/08/addressing
">uuid:394f2630-ba3c-14e7-faad-e7c34225deaf</wsa:MessageID>
        <wsa:From xmlns:wsa="http://www.w3.org/2005/08/addressing";>
            <wsa:Address>http://www.w3.org/2005/08/addressing/role/anonymous
</wsa:Address>
        </wsa:From>
    </soap:Header>
    <soap:Body>
        <pfx0:getArticulos xmlns:pfx0="http://test/services/MyService";>
            <pfx0:idArticulo>1</pfx0:idArticulo>
            <pfx0:idProveedor>2</pfx0:idProveedor>
            <pfx0:idProducto>3</pfx0:idProducto>
            <pfx0:nombreArticulo>nombreArticulo</pfx0:nombreArticulo>
            <pfx0:tipoCodificacion>tipoCodificacion</pfx0:tipoCodificacion>

<pfx0:valorCodificacion>valorCodificacion</pfx0:valorCodificacion>
            <pfx0:detalles>true</pfx0:detalles>
        </pfx0:getArticulos>
    </soap:Body>
</soap:Envelope>


And this is the response  (only the tricky part):

<soapenv:Body>
        <muse-op:getArticulosResponse xmlns:muse-op="
http://test/services/MyService"; xmlns:tns="
http://axis2.platform.core.muse.apache.org";>
            <muse-op:Mensaje>
                <soy>
                    <un>
                        <equisemeele/>
                    </un>
                </soy>
            </muse-op:Mensaje>
        </muse-op:getArticulosResponse>
    </soapenv:Body>


Where we can see it's generating "getArticulosResponse" as the root element
of the XML response.


If we generate proxy client code for the same WSDL we can see that it is
generating an array of response names, and here is where the problems begin,
using the XSD element's name from the WSDL operation output message part
instead of following the previous algorithm as can be seen in
org.apache.muse.tools.inspector.ResourceInspector.getOutputName(Operation
op):

private QName getOutputName(Operation op)
    {
        Output output = op.getOutput();
        if (output == null)
            return null;
        Map parts = output.getMessage().getParts();

        if (parts.size() != 1)
        {
            Object[] filler = { op.getName() };
            throw new RuntimeException(_MESSAGES.get("NotDocLiteral",
filler));
        }

        Part docLiteralPart = (Part)parts.values().iterator().next();
        System.err.println("GETOUTPUTNAME: " + docLiteralPart.getElementName
());
        return docLiteralPart.getElementName();
    }

This makes client proxy implementation fail to understand service's response
when the response message's XSD element is not named using the following
convention, as in this case ( here the element representing the response
message is named "RespouestaServicio"):

org.apache.muse.ws.addressing.soap.SoapFault: [ID = 'InvalidProxyResponse']
The
output message returned does not match the one expected; the output message
expe
cted was '{http://test/services/MyService}RespuestaServi
cio', but the actual message was '{http://http://test/services/MyService
}getArticulosResponse'.
        at org.apache.muse.core.proxy.ReflectionProxyHandler.fromXML
(ReflectionP
roxyHandler.java:103)
        at org.apache.muse.core.AbstractResourceClient.invoke
(AbstractResourceCl
ient.java:234)
        at org.apache.muse.core.AbstractResourceClient.invoke
(AbstractResourceCl
ient.java:211)
        at
net.eusa.tlrsoft.services.TransformationService.TransformationService
Proxy.getArticulos(Unknown Source)
        at prueba.main(prueba.java:17)


So, the code always fails when the name of the element that represents the
response to a custom operation in Apache Muse doesn't follow the imposed
name-convention <operation's name> + "Response".

Wouldn't it be easier if Apache Muse uses the same criteria when naming
responses on both sides, the server and the client proxy side?

Giving the fact that Apache Muse's wsdl2java proxy generation has to be
independent of server's code generation, maybe a better approach would be to
use information on the WSDL (wich both generators share) to name the
response on the server side.  This way, the proxy code doesn't depend on
naming issues not imposed on the WSDL specification ( I couldn't find
anywhere in the specification saying that the XSD element that represents an
output message in a WSDL has to have "Response" suffix ).

Greets,

Reply via email to