Spring Web Services
  1. Spring Web Services
  2. SWS-281

add support for imported xsd in static wsdl as well as xsd's that import other xsd's

    Details

    • Type: New Feature New Feature
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 1.5.1
    • Component/s: Core
    • Labels:
      None
    • Environment:
      Spring WS 1.0.2

      Description

      Currently, Spring WS does not seem to have support for serving up xsd's that are imported into static wsdl. There is also no support for xsd's that import other xsd's. Both situations are considered best practices by schema and wsdl designers.

      The schemaLocation attribute should be transformed in the same way that the location attribute is transformed for wsdl's today to include the request specific server info depending on where the application is deployed.

      Usage Examples:

      wsdl (with imported xsd)
      request
      http://localhost:7001/Services/8.02/Example?wsdl

      response (partial)
      <wsdl:definitions name="Example" targetNamespace="http://services">
      <wsdl:types>
      <xs:schema>
      <xs:import namespace="http://customer/types" schemaLocation="http://localhost:7001/Services/8.02/Example?Customer.xsd"/>
      </xs:schema>
      </wsdl:types>

      xsd (with imported xsd)
      request
      http://localhost:7001/Services/8.02/Example?Customer.xsd

      response (partial)
      <xs:schema targetNamespace="http://customer/types">
      <xs:import namespace="http://order/types" schemaLocation="http://localhost:7001/Services/8.02/Example?Order.xsd"/>

        Issue Links

          Activity

          Hide
          Arjen Poutsma added a comment -

          I'd really like to put this in 1.5, but I'm seeing some issues, and time is running out. I might have to postpone this to a later release.

          @Mark

          I am looking into the XsdDefinitionHandlerAdapter: is there any particular reason why you used a different algorithm in the transformSchemaLocation() method than the existing one in WsdlDefinitionHandlerAdapter#transformLocation() ?

          I mean, using your example in the readme, can't we just expose Customer.xsd as http://localhost:7001/Services/8.02/Customer.xsd rather than http://localhost:7001/Services/8.02/Example?Customer.xsd ? This seems more consistent with the WSDL approach that we already have.

          @Erik-Berndt
          I am not sure how Axis2' solution works, but I do know that imports/includes get tricky, especially when considering circular references. Using your example: what if http://some.url/appcontext/services/myservice?xsd=xsd0 imported xsd1, which imports xsd0? Where would those schemas be made available?

          I'd rather have more explicit approach, with individual SimpleXsdSchema bean definitions such as Mark proposed, rather than to try to figure out things automagically .

          Show
          Arjen Poutsma added a comment - I'd really like to put this in 1.5, but I'm seeing some issues, and time is running out. I might have to postpone this to a later release. @Mark I am looking into the XsdDefinitionHandlerAdapter: is there any particular reason why you used a different algorithm in the transformSchemaLocation() method than the existing one in WsdlDefinitionHandlerAdapter#transformLocation() ? I mean, using your example in the readme, can't we just expose Customer.xsd as http://localhost:7001/Services/8.02/Customer.xsd rather than http://localhost:7001/Services/8.02/Example?Customer.xsd ? This seems more consistent with the WSDL approach that we already have. @Erik-Berndt I am not sure how Axis2' solution works, but I do know that imports/includes get tricky, especially when considering circular references. Using your example: what if http://some.url/appcontext/services/myservice?xsd=xsd0 imported xsd1, which imports xsd0? Where would those schemas be made available? I'd rather have more explicit approach, with individual SimpleXsdSchema bean definitions such as Mark proposed, rather than to try to figure out things automagically .
          Hide
          Erik-Berndt Scheper added a comment -

          When I read your comments, I realized that the Axis2 implementation is indeed not appropriate here, because there is no concept of a service but only of endpoints and wsdl definitions. I can think of two solutions that are more in line with the current SimpleWsdl11Definition implementation, which is actually quite nice.

          First of all, the idea is to add an optional property xsdLocator to the SimpleWsdl11Definition, which can be used to link the xsd's to a statically defined wsdl.

          The default implementation of this XsdLocator, let's say the SimpleXsdLocator, should have two properties, xsdLocation and xsdLocations of type Resource and Resource[], so that it is possible to locate multiple xsd's using constructs like 'classpath:/resources/xsd/*/.xsd'

          Then we need a way to publish them so that the xsd's can be loaded from a URL. This could be achieved in two ways:
          1. Add an extra servlet mapping to web.xml (*.xsd) and publish them in a similar way to the SimpleWsdl1Definition already does. But this leads to a complication: the static wsdl and (possibly) xsd's need to be modified so that each xsd can recursively be resolved correctly. The most simple way seems to skip all path prefixes and therefore require each xsd name to be unique.
          This would lead to the following published wsdl and xsd's
          http://some.url/appcontext/myservice.wsdl returning the wsdl definition (resolved by the SimpleWsdl11Definition)
          http://some.url/appcontext/xsdA.xsd returning an xsd (resolved by the SimpleXsdLocator)
          http://some.url/appcontext/xsdB.xsd returning an xsd (resolved by the SimpleXsdLocator)

          2. But if this uniqueness of xsd names is required then it might be much easier to resolve the xsd's using the servlet mapping that is already in place (that of the SimpleWsdl11Definition), and let the SimpleWsdl11Definition publish them instead. This would lead to the following published wsdl and xsd's
          http://some.url/appcontext//myservice.wsdl returning the wsdl definition
          http://some.url/appcontext//myservice.wsdl?xsd=xsdA.xsd returning an xsd resolved using delegation to the SimpleXsdLocator
          http://some.url/appcontext//myservice.wsdl?xsd=xsdB.xsd returning another xsd also resolved by delegating to the SimpleXsdLocator

          The advantage of this alternative is that the user does not need an extra servlet mapping (for *.xsd) and (maybe) that there is a direct link to xsd's used by a specific wsdl.

          Show
          Erik-Berndt Scheper added a comment - When I read your comments, I realized that the Axis2 implementation is indeed not appropriate here, because there is no concept of a service but only of endpoints and wsdl definitions. I can think of two solutions that are more in line with the current SimpleWsdl11Definition implementation, which is actually quite nice. First of all, the idea is to add an optional property xsdLocator to the SimpleWsdl11Definition, which can be used to link the xsd's to a statically defined wsdl. The default implementation of this XsdLocator, let's say the SimpleXsdLocator, should have two properties, xsdLocation and xsdLocations of type Resource and Resource[], so that it is possible to locate multiple xsd's using constructs like 'classpath:/resources/xsd/* / .xsd' Then we need a way to publish them so that the xsd's can be loaded from a URL. This could be achieved in two ways: 1. Add an extra servlet mapping to web.xml (*.xsd) and publish them in a similar way to the SimpleWsdl1Definition already does. But this leads to a complication: the static wsdl and (possibly) xsd's need to be modified so that each xsd can recursively be resolved correctly. The most simple way seems to skip all path prefixes and therefore require each xsd name to be unique. This would lead to the following published wsdl and xsd's http://some.url/appcontext/myservice.wsdl returning the wsdl definition (resolved by the SimpleWsdl11Definition) http://some.url/appcontext/xsdA.xsd returning an xsd (resolved by the SimpleXsdLocator) http://some.url/appcontext/xsdB.xsd returning an xsd (resolved by the SimpleXsdLocator) 2. But if this uniqueness of xsd names is required then it might be much easier to resolve the xsd's using the servlet mapping that is already in place (that of the SimpleWsdl11Definition), and let the SimpleWsdl11Definition publish them instead. This would lead to the following published wsdl and xsd's http://some.url/appcontext//myservice.wsdl returning the wsdl definition http://some.url/appcontext//myservice.wsdl?xsd=xsdA.xsd returning an xsd resolved using delegation to the SimpleXsdLocator http://some.url/appcontext//myservice.wsdl?xsd=xsdB.xsd returning another xsd also resolved by delegating to the SimpleXsdLocator The advantage of this alternative is that the user does not need an extra servlet mapping (for *.xsd) and (maybe) that there is a direct link to xsd's used by a specific wsdl.
          Hide
          Arjen Poutsma added a comment -

          Pushing this past 1.5.0 as we need some input from Mark.

          Show
          Arjen Poutsma added a comment - Pushing this past 1.5.0 as we need some input from Mark.
          Hide
          Ray Harrison added a comment -

          Hi Arjen,
          We can work for a future release. Mark is buried in getting some releases out and hasn't had much time to devote to this particular item. We will probably always keep our own addition to allow for the ability to use the query parameter for referencing the WSDL. Comcast has a rather large and complex organizational structure and we need to be able to play nicely with how other teams expect to interact with our web services.

          That said, exposing the XSD via the standard Spring-WS as you suggest is perfectly workable from my perspective.

          Thanks,
          Ray

          Show
          Ray Harrison added a comment - Hi Arjen, We can work for a future release. Mark is buried in getting some releases out and hasn't had much time to devote to this particular item. We will probably always keep our own addition to allow for the ability to use the query parameter for referencing the WSDL. Comcast has a rather large and complex organizational structure and we need to be able to play nicely with how other teams expect to interact with our web services. That said, exposing the XSD via the standard Spring-WS as you suggest is perfectly workable from my perspective. Thanks, Ray
          Hide
          Arjen Poutsma added a comment -

          Closing this, as the work is at least partially done. I've created a separate issue (SWS-346) for the handler adapter, which you can vote for if you need it.

          Show
          Arjen Poutsma added a comment - Closing this, as the work is at least partially done. I've created a separate issue ( SWS-346 ) for the handler adapter, which you can vote for if you need it.

            People

            • Assignee:
              Arjen Poutsma
              Reporter:
              Mark LaFond
            • Votes:
              8 Vote for this issue
              Watchers:
              11 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: