You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tuscany.apache.org by Simon Laws <si...@googlemail.com> on 2009/02/10 13:09:25 UTC

[1.x] WSDL generation strangeness

I'm trying to get a handle on a policy problem where I get a NPE in the Axis
runtime. The NPE is caused because Axis is failing to find a named
operation. It's looking for an operation of the form

{http://helloworld}getGreetings

but failing as the operation is registered in the binding inside the Axis
service model with the name

{
http://helloworld/HelloWorldServiceComponent/$promoted$HelloWorldService}getGreetings

This seems to come back to how we generate WSDL. The generated WSDL inside
the WS Binding in this case imports the real WSDL that was specified in an
interface.wsdl statement. The generated WSDL [1] is given the target
namespace {
http://helloworld/HelloWorldServiceComponent/$promoted$HelloWorldService}
while the original WSDL retains the target namespace {http://helloworld}.
Axis is getting confused when it pulls binding and porty type information
from different parts of the WSDL definition. In this case, for example,
there is an operation defined in the binding

{
http://helloworld/HelloWorldServiceComponent/$promoted$HelloWorldService}getGreetings

Which has a different QName to that defined in the original port type

{http://helloworld}getGreetings

Anyone know why we generate a targetNamespace for this wrapper WSDL which
takes the original namespace and adds the service name to the end of it?

Simon

[1]

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions
name="HelloWorldServiceComponent.$promoted$HelloWorldService"
targetNamespace="http://helloworld/HelloWorldServiceComponent/$promoted$HelloWorldService"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://helloworld/HelloWorldServiceComponent/$promoted$HelloWorldService"
xmlns:ns0="http://helloworld"
xmlns:SOAP11="http://schemas.xmlsoap.org/wsdl/soap/">
  <wsdl:import namespace="http://helloworld"
location="/HelloWorldService?wsdl=wsdl/helloworld.wsdl">
    </wsdl:import>
  <wsdl:binding name="HelloWorldBinding" type="ns0:HelloWorld">
    <SOAP11:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="getGreetings">
      <SOAP11:operation soapAction="urn:getGreetings"/>
      <wsdl:input name="getGreetingsRequest">
        <SOAP11:body use="literal"/>

      </wsdl:input>
      <wsdl:output name="getGreetingsResponse">
        <SOAP11:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="HelloWorldService">
    <wsdl:port name="HelloWorldPort" binding="tns:HelloWorldBinding">
      <SOAP11:address location="http://192.168.247.1:8085/HelloWorldService"/>

    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>

Re: [1.x] WSDL generation strangeness

Posted by Simon Nash <na...@apache.org>.
Simon Laws wrote:
> 
> 
> On Tue, Feb 10, 2009 at 3:04 PM, Simon Nash <nash@apache.org 
> <ma...@apache.org>> wrote:
> 
>     Simon Laws wrote:
> 
>            So it affects the namespace of the
>            binding definition, but it shouldn't affect the namespace of the
>            global elements used by message parts within the portType
>            referenced by the binding (i.e., what goes on the wire).
>            In this example the portType is "ns0:HelloWorld" which refers to
>            global elements in the correct namespace "http:/helloworld"
> 
>            So this looks to me like an Axis bug with namespaces for imported
>            portTypes not being handled correctly.  It seems the binding's
>            namespace is being used to register these operations instead of
>            the correct namespace as specified in the portType.
> 
>            Where in Axis is this registration happening?  Which version
>            of Axis is being used?  With this information I could dig around
>            a bit in the Axis code.
> 
> 
>         How, with this generated target namespace, do we intend that the
>         binding operation name is matched with the port type operation name?
> 
>         Simon
> 
>      >
>     The binding references the port type:
> 
>      <wsdl:binding name="HelloWorldBinding" type="ns0:HelloWorld">
> 
>     The "ns0:" in this QName provides the cross-namespace linkage.
> 
>     You've got me wondering now whether the operation names in
>     the binding will match those in the portType if the binding
>     and portType come from different namespaces.  The operation
>     names are NCNames so I would expect them to match.  I'll take
>     a look at the WSDL spec and try to confirm this.
> 
>      Simon
> 
> Ok, so that's what I overlooked. The names in question in the WSDL are 
> not QNames.
> 
> In the class org.apache.axis2.description.AxisOperation.getName() 
> returns a QName. With this insight I'll look again and see if I'm 
> interpreting what I see correctly.
> 
> There is a line in 
> org.apache.axis2.description.AxisOperation.AxisDescription
> 
>                             AxisBindingOperation axisBindingOperation = 
> (AxisBindingOperation) axisBinding
>                                     .getChild(axisOperation.getName());
> 
> That returns null in my particular scenario.
> 
> I'm on Axis2 1.4.1
> 
> Simon
 >

In line 1282 of WSDL11ToAxisServiceBuilder, there is the following line:
   QName opName = new QName(dif.getTargetNamespace(), wsdl4jOperation.getName());
This uses the namespace of the portType definition to name the
operation children of the portType.

In line 641 of WSDL11ToAxisServiceBuilder, there is the following line:
   axisBindingOperation.setName(new QName(bindingWSDL.getTargetNamespace(), wsdl4jBindingOperation.getName()));
This uses the namespace of the binding definition to name the binding
operation children of the binding.  Each binding operation object has
a reference to its corresponding operation object.

The code you mentioned (at line 556 of AxisDescription) is incompatible
with the above scheme, because it uses an operation name to make a direct
lookup of a binding operation child of the binding.  It needs to be
changed to iterate through all the binding operation children of the
binding, comparing the operation name belonging to each binding operation
object against the operation name it is looking for.  When it finds a
match, it should select the binding operation that gave the match.

   Simon



Re: [1.x] WSDL generation strangeness

Posted by Simon Laws <si...@googlemail.com>.
There is a line in
org.apache.axis2.description.AxisOperation.AxisDescription

should have read

There is a line in
org.apache.axis2.description.AxisOperation.AxisDescription.getApplicablePolicy()

Simon

Re: [1.x] WSDL generation strangeness

Posted by Simon Laws <si...@googlemail.com>.
On Tue, Feb 10, 2009 at 3:04 PM, Simon Nash <na...@apache.org> wrote:

> Simon Laws wrote:
>
>>    So it affects the namespace of the
>>    binding definition, but it shouldn't affect the namespace of the
>>    global elements used by message parts within the portType
>>    referenced by the binding (i.e., what goes on the wire).
>>    In this example the portType is "ns0:HelloWorld" which refers to
>>    global elements in the correct namespace "http:/helloworld"
>>
>>    So this looks to me like an Axis bug with namespaces for imported
>>    portTypes not being handled correctly.  It seems the binding's
>>    namespace is being used to register these operations instead of
>>    the correct namespace as specified in the portType.
>>
>>    Where in Axis is this registration happening?  Which version
>>    of Axis is being used?  With this information I could dig around
>>    a bit in the Axis code.
>>
>>
>> How, with this generated target namespace, do we intend that the binding
>> operation name is matched with the port type operation name?
>>
>> Simon
>>
> >
> The binding references the port type:
>  <wsdl:binding name="HelloWorldBinding" type="ns0:HelloWorld">
>
> The "ns0:" in this QName provides the cross-namespace linkage.
>
> You've got me wondering now whether the operation names in
> the binding will match those in the portType if the binding
> and portType come from different namespaces.  The operation
> names are NCNames so I would expect them to match.  I'll take
> a look at the WSDL spec and try to confirm this.
>
>  Simon
>
> Ok, so that's what I overlooked. The names in question in the WSDL are not
QNames.

In the class org.apache.axis2.description.AxisOperation.getName() returns a
QName. With this insight I'll look again and see if I'm interpreting what I
see correctly.

There is a line in
org.apache.axis2.description.AxisOperation.AxisDescription

                            AxisBindingOperation axisBindingOperation =
(AxisBindingOperation) axisBinding
                                    .getChild(axisOperation.getName());

That returns null in my particular scenario.

I'm on Axis2 1.4.1

Simon

Re: [1.x] WSDL generation strangeness

Posted by Simon Nash <na...@apache.org>.
Simon Laws wrote:
>     So it affects the namespace of the
>     binding definition, but it shouldn't affect the namespace of the
>     global elements used by message parts within the portType
>     referenced by the binding (i.e., what goes on the wire).
>     In this example the portType is "ns0:HelloWorld" which refers to
>     global elements in the correct namespace "http:/helloworld"
> 
>     So this looks to me like an Axis bug with namespaces for imported
>     portTypes not being handled correctly.  It seems the binding's
>     namespace is being used to register these operations instead of
>     the correct namespace as specified in the portType.
> 
>     Where in Axis is this registration happening?  Which version
>     of Axis is being used?  With this information I could dig around
>     a bit in the Axis code.
> 
> 
> How, with this generated target namespace, do we intend that the binding 
> operation name is matched with the port type operation name?
> 
> Simon
 >
The binding references the port type:
   <wsdl:binding name="HelloWorldBinding" type="ns0:HelloWorld">

The "ns0:" in this QName provides the cross-namespace linkage.

You've got me wondering now whether the operation names in
the binding will match those in the portType if the binding
and portType come from different namespaces.  The operation
names are NCNames so I would expect them to match.  I'll take
a look at the WSDL spec and try to confirm this.

   Simon


Re: [1.x] WSDL generation strangeness

Posted by Simon Laws <si...@googlemail.com>.
>
> So it affects the namespace of the
> binding definition, but it shouldn't affect the namespace of the
> global elements used by message parts within the portType
> referenced by the binding (i.e., what goes on the wire).
> In this example the portType is "ns0:HelloWorld" which refers to
> global elements in the correct namespace "http:/helloworld"
>
> So this looks to me like an Axis bug with namespaces for imported
> portTypes not being handled correctly.  It seems the binding's
> namespace is being used to register these operations instead of
> the correct namespace as specified in the portType.
>
> Where in Axis is this registration happening?  Which version
> of Axis is being used?  With this information I could dig around
> a bit in the Axis code.
>

How, with this generated target namespace, do we intend that the binding
operation name is matched with the port type operation name?

Simon

Re: [1.x] WSDL generation strangeness

Posted by Simon Nash <na...@apache.org>.
Simon Laws wrote:
> I'm trying to get a handle on a policy problem where I get a NPE in the 
> Axis runtime. The NPE is caused because Axis is failing to find a named 
> operation. It's looking for an operation of the form
> 
> {http://helloworld}getGreetings
> 
> but failing as the operation is registered in the binding inside the 
> Axis service model with the name
> 
> {http://helloworld/HelloWorldServiceComponent/$promoted$HelloWorldService}getGreetings
> 
> This seems to come back to how we generate WSDL. The generated WSDL 
> inside the WS Binding in this case imports the real WSDL that was 
> specified in an interface.wsdl statement. The generated WSDL [1] is 
> given the target namespace 
> {http://helloworld/HelloWorldServiceComponent/$promoted$HelloWorldService} 
> while the original WSDL retains the target namespace 
> {http://helloworld}. Axis is getting confused when it pulls binding and 
> porty type information from different parts of the WSDL definition. In 
> this case, for example, there is an operation defined in the binding
> 
> {http://helloworld/HelloWorldServiceComponent/$promoted$HelloWorldService}getGreetings
> 
> Which has a different QName to that defined in the original port type
> 
> {http://helloworld}getGreetings
> 
> Anyone know why we generate a targetNamespace for this wrapper WSDL 
> which takes the original namespace and adds the service name to the end 
> of it?
>
The SCA 1.0 Bindings spec says the namespace for the generated
binding elements is
   HTTP base URI / Component Name / Service Name

The rather convoluted target namespace that you see in this
generated file is a result of following this algorithm, with a
bit of $promoted$ noise thrown is.  (The "base URI" portion is
debatable, as this term isn't clearly defined by the spec.)

This namespace only applies to the elements defined within
the generated WSDL file.  So it affects the namespace of the
binding definition, but it shouldn't affect the namespace of the
global elements used by message parts within the portType
referenced by the binding (i.e., what goes on the wire).
In this example the portType is "ns0:HelloWorld" which refers to
global elements in the correct namespace "http:/helloworld"

So this looks to me like an Axis bug with namespaces for imported
portTypes not being handled correctly.  It seems the binding's
namespace is being used to register these operations instead of
the correct namespace as specified in the portType.

Where in Axis is this registration happening?  Which version
of Axis is being used?  With this information I could dig around
a bit in the Axis code.

   Simon

> Simon
> 
> [1]
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <wsdl:definitions name="HelloWorldServiceComponent.$promoted$HelloWorldService" targetNamespace="http://helloworld/HelloWorldServiceComponent/$promoted$HelloWorldService" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://helloworld/HelloWorldServiceComponent/$promoted$HelloWorldService" xmlns:ns0="http://helloworld" xmlns:SOAP11="http://schemas.xmlsoap.org/wsdl/soap/">
> 
>   <wsdl:import namespace="http://helloworld" location="/HelloWorldService?wsdl=wsdl/helloworld.wsdl">
> 
>     </wsdl:import>
>   <wsdl:binding name="HelloWorldBinding" type="ns0:HelloWorld">
> 
>     <SOAP11:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
> 
>     <wsdl:operation name="getGreetings">
>       <SOAP11:operation soapAction="urn:getGreetings"/>
> 
>       <wsdl:input name="getGreetingsRequest">
>         <SOAP11:body use="literal"/>
> 
>       </wsdl:input>
>       <wsdl:output name="getGreetingsResponse">
> 
>         <SOAP11:body use="literal"/>
>       </wsdl:output>
> 
>     </wsdl:operation>
>   </wsdl:binding>
>   <wsdl:service name="HelloWorldService">
> 
>     <wsdl:port name="HelloWorldPort" binding="tns:HelloWorldBinding">
> 
>       <SOAP11:address location="http://192.168.247.1:8085/HelloWorldService"/>
> 
>     </wsdl:port>
>   </wsdl:service>
> </wsdl:definitions>
> 
>