Dashboard > WSO2 Mashup Server > Home > Generating WSDL
  WSO2 Mashup Server Log in | Register   View a printable version of the current page.  
  Generating WSDL
Added by Jonathan Marsh , last edited by Jonathan Marsh on Jun 15, 2007  (view change) show comment
Labels: 
(None)

Automatically generating WSDL

When a .js file is deployed as a service, the user is able to ask for a WSDL document for that service, using the ?wsdl (WSDL 1.1) and ?wsdl2 (WSDL 2.0) suffixes on the Endpoint address.

The abstract part of a WSDL (interface) is inferred from the .js file itself, making use of metadata specified by the author.  The binding-level details are defaulted to a useful baseline, and configurable on a per-endpoint basis using the UI, which will provide a number of options for generic bindings, and eventually allow one to point to a custom binding written in WSDL (can we get away with supporting WSDL 2 only?).

Prototype

To use this file, change the source to provide the following:

  1. path to the .js file to be used
  2. targetNamepace URI
  3. serviceName
  4. list of function names within the .js file

Run it in Firefox (relies on E4X support) and press the Generate button.  Copy the WSDL out into a file.

Annotations

See Javascript Web Service Annotations

TBDs

  • How to define the targetNamespace.  Defining it on a per-operation basis is wrong.  Do we need a WSGlobal.targetNamespace property?  A global context would give us a place to hang other information.
  • How to define and map a custom schema type into the language.
  • What it means to have a simple type as a return type.
  • How to handle MTOM.  PHP defines mappings between xop:Include identifiers and a file system object.  This probably means we need to have native file support from Ecmascript.
  • The difference between getting the whole blob as a parameter and unwrapping a parameter from an rpc-style operation.  Do we need an "unwrap" property to control this?

Mapping

{let serviceName be this.serviceName if it exists, otherwise the name of the .js file, omitting the ".js" extension.}
{let baseNamespace be this.targetNamespace if present, otherwise "http://services.mashup.wso2.org/" + serviceName}
{let schemaTargetNamespace be this.schemaTargetNamespace if present, otherwise baseNamespace + "?xsd"}
<wsdl:description targetNamespace={baseNamespace}>
  {if this.documentation}
    <wsdl:documentation>{this.documentation}</wsdl:documentation>
  {endif}
  <wsdl:types>
    <xs:schema targetNamespace={schemaTargetNamespace} elementFormDefault="unqualified">
      {if this.schemaLocation}
      {for each function without functionName.visible=false and functionName.inputType != "#any"}
        {let operationName be functionName.operationName, if present, otherwise functionName}
        <xs:element name={operationName} >
          <xs:complexType>
            <xs:sequence>
              {for each parameter in function}
                <xs:element name={parameterName}
                  type={if functionName.inputType[parameterName] is present, functionName.inputType[parameterName], otherwise "xs:anyType"}/>
               {end for each}
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        {if functionName.outputType is present, and has any value but "xs:anyType"}
          <xs:element name={operationName + "Response"} >
            <xs:complexType>
              <xs:sequence>
                {for each parameter in function}
                  <xs:element name="return" type={functionName.outputType}/>
                 {end for each}
              </xs:sequence>
            </xs:complexType>
          </xs:element>
        {end if}
      {end for each}
    </xs:schema>
  </wsdl:types>
  <wsdl:interface name={serviceName + "Service"}>
   {for each function without functionName.visible=false}
      {let operationName be functionName.operationName, if present, otherwise functionName}
      <wsdl:operation name={operationName}
          pattern="http://www.w3.org/ns/wsdl/in-out"
          style="http://www.w3.org/ns/wsdl/style/rpc"
          wsdlx:safe={true if functionName.safe = true}
          wrpc:signature={
            {for each parameter in function}prefix representing schemaTargetNamespace + ":" + parameterName + " #in"{end for each}
            + " return #out"
          }>
          {if this.documentation}
            <wsdl:documentation>{functionName.documentation}</wsdl:documentation>
          {endif}
        <wsdl:input element={"#none" if no parameters, "#any" if functionName.inputType="#any", otherwise {prefix representing schemaTargetNamespace + ":" + operationName}/>
        <wsdl:output element={"#any" if functionName.outputType = "#any", otherwise {prefix representing schemaTargetNamespace + ":" + operationName + "Response"}/>
      </wsdl:operation>
   {end for each}
  </wsdl:interface>
  <wsdl:binding name={serviceName + "SOAP12Binding"} interface={prefix representing baseNamespace + ":" + serviceName + "Service"}
      type="http://www.w3.org/ns/wsdl/soap" wsoap:version="1.2" wsoap:underlyingProtocol="the soap 1.2 http binding url">
   {for each function without functionName.visible=false}
    {let operationName be functionName.operationName, if present, otherwise functionName}
    <wsdl:operation ref={prefix representing baseNamespace + ":" + operationName}
      wsoap:action={baseNamespace + "\" + operationName}/>
   {end for each}
  </wsdl:binding>
  <wsdl:binding name={serviceName + "SOAP11Binding"} interface={prefix representing baseNamespace + ":" + serviceName + "Service"}
    type="http://www.w3.org/ns/wsdl/soap" wsoap:version="1.1" wsoap:underlyingProtocol="the soap 1.1 http binding url">
    {for each function without functionName.visible=false}
      {let operationName be functionName.operationName, if present, otherwise functionName}
      <wsdl:operation ref={prefix representing baseNamespace + ":" + operationName}
        wsoap:action={baseNamespace + "\" + operationName}/>
   {end for each}
  </wsdl:binding>
  <wsdl:binding name={serviceName + "HTTPBinding"} interface={prefix representing baseNamespace + ":" + serviceName + "Service"}
    type="http://www.w3.org/ns/wsdl/http" >
    {for each function without functionName.visible=false}
      {let operationName be functionName.operationName, if present, otherwise functionName}
      <wsdl:operation ref={prefix representing baseNamespace + ":" + operationName}
          whttp:location={operationName}/>
    {end for each}
  </wsdl:binding>
  <wsdl:service name={serviceName}>
    {if SOAP 1.2 Binding is enabled in the config screen}
      <wsdl:endpoint name={serviceName + "SOAP12Endpoint"} 
        binding={prefix representing baseNamespace + ":" + serviceName + "SOAP12Binding"}
        address={endpoint address from Mashup Server}/>
    {end if}
    {if SOAP 1.1 Binding is enabled in the config screen}
      <wsdl:endpoint name={serviceName + "SOAP11Endpoint"} 
        binding={prefix representing baseNamespace + ":" + serviceName + "SOAP11Binding"}
        address={endpoint address from Mashup Server}/>
    {end if}
    {if HTTP Binding is enabled in the config screen}
      <wsdl:endpoint name={serviceName + "HTTPEndpoint"} 
        binding={prefix representing baseNamespace + ":" + serviceName + "HTTPBinding"}
        address={endpoint address from Mashup Server}/>
    {end if}
  </wsdl:service>
</wsdl:description>

Limitations:

  • Mixing user-defined schema types with undefined types (including simple types that require a wrapper.)
  • Arrays unsupported

Notes:

  • Need to add a "this.schemaLocation" property?  Or can this information be gotten from somewhere else?
  • Need to add "#any" as a value for an inputType or outputType.
  • Assumes parameters aren't namespaced (elementFormDefault="unqualified").  This makes them much easier to access in E4X.  But if we improve our unwrapping that rationale won't be very compelling any more.  Is "qualified" better for other reasons? (Other than aesthetics?)

Powered by a free Atlassian Confluence Open Source Project License granted to WSO2 Inc.. Evaluate Confluence today.
Powered by Atlassian Confluence 2.7.1, the Enterprise Wiki. Bug/feature request - Atlassian news - Contact administrators