History | Log In     View a printable version of the current page.  
Issue Details (XML | Word | Printable)

Key: XFIRE-511
Type: Improvement Improvement
Status: Closed Closed
Resolution: Fixed
Priority: Minor Minor
Assignee: Dan Diephouse
Reporter: Ciaran Jessup
Votes: 0
Watchers: 2
Operations

If you were logged in you would be able to see more operations.
XFire

Possible approach to extensible WSDL generation

Created: 02/Jul/06 06:06 AM   Updated: 20/Jul/06 01:06 PM
Component/s: Core
Affects Version/s: 1.1.2
Fix Version/s: 1.2-RC

Time Tracking:
Not Specified

File Attachments: 1. Zip Archive xfire patch.zip (6 kb)



 Description  « Hide
A possible approach to the problem of wanting to extend the WSDL generation in generic ways, such as adding in new elements to the WSDL or manipulating the WSDL i.e. replacing <xs:include with inlined schemas

The approach is to modify the write method of WSDLBuilder to implement a Template pattern, then use a Strategy pattern to inject into this method the behaviours one wants to do, I've provided an interface WSDLBuilderExtension that implements the template, an adapter to allow quick anonymous overrides and nesting of multiple [decorated] WSDLBuilderExtensions, and a WSDLBuilderFactory that transparently decorates existing factories with the desired WSDLBuilderExtension(s).... hope this makes sense <g>

Included in the ZIP file is a patch against SVN HEAD (r 1737) And some example code showing how it may be used to add BPEL partner links to WSDL files on the fly.

One thing to note is that the Extension class instances are re-used where-as the WSDLBuilder instances aren't so there may be some thread-safety issues to consider around here, also this code is not properly commented, I'm submitting it purely for consideration of the approach



 All   Comments   Work Log   Change History      Sort Order: Ascending order - Click to sort in descending order
Christoph Sturm - 02/Jul/06 09:36 AM
scheduling this for 1.2 because 1.1.3 is bugfix only, and this is a new feature. If time permits it can be rescheduled for 1.2rc

Dan Diephouse - 12/Jul/06 10:25 AM
Hiya,

Taking a lok at this now. A couple questions/thoughts:

  • Did you think about making the WSDLBuilder take a list of WSDLExtensions? It might be handy if you want to have more than one extension
  • Why would you need to add something before the portType or binding is created? (i.e. why would someone use beforeConcreteInterface)
  • Did you think about a visitor patter at all? i.e. after the wsdl is created we could visit each part of the wsdl. See this class:

http://svn.xfire.codehaus.org/browse/xfire/trunk/xfire/xfire-core/src/main/org/codehaus/xfire/wsdl11/WSDLVisitor.java?r=833

Looks good for the most part though! I'm interested in your feedback to those questions before we commit something.


Ciaran Jessup - 13/Jul/06 02:49 AM
Hi Dan, thanks for getting back to me on this;
  • Did you think about making the WSDLBuilder take a list of WSDLExtensions? It might be handy if you want to have more than one extension
    • Yes, in fact that was my first thought as that would be a similar approach to the approach taken with the In+Out Handlers. However I couldn't see a neat way to inject the list into the WSDLBuilder instances as currently it is Factories that are injected not WSDLBuilders, so I then went off down the root of injecting a list of Extensions by creating a special factory. At this point I realised there was little point forcing the WSDLBuilder to take on the semantics of iterating over a list of extensions when this could be done implicitly by using the decorator pattern to nest repeated instances, so the order that WSDBUilderExtensions were wrapped implicitly defined the list, I also thought you might want to do something around a change made by some other extension so by wrapping them you had the option of maintaining the state before and after. However I don't feel particularly strongly one way or t'other I created the code to foster a discussion because I feel being able to manipulate the generated WSDL is something that will be very useful to many people <g>
  • Why would you need to add something before the portType or binding is created? (i.e. why would someone use beforeConcreteInterface)
    • Good question, it's quite obviously redundant, I left it in so that a WSDLExtension implementor could have a better understanding of exactly what point in the process they were injecting their new behaviour, but perhaps a better name for 'afterCreateAbstractInterface' and 'beforeCreateConcreteInterface' could be in order.
  • Did you think about a visitor patter at all? i.e. after the wsdl is created we could visit each part of the wsdl. See this class:
    • I did yes, however I've never been a particular fan of the visitor pattern, normally because it exposes the internal interface, but in this case we're doing it anyway. I guess on the one hand it is an elegant solution so multiple visitors could be used, but on the other hand it could be quite inefficient because the majority case is likely to be adding a element(s) to the wsdl:definition. So perhaps the Visitor pattern is quite a bit of an overkill, in that each visitor specified would be called-back to for every part of the document, and also [and I'd need to check the specific semantics of that visitor pattern], if you add new sections to the WSDL, say partner-links etc, to be true visitor you'd want to pass back those nodes to the visitor's visit method(s), which you won't know until run-time, so you'd have a default elements pass-back, but then why bother with the visitor ?

As I said before, I have no strong feelings on implementation details, my design ideals would be something that promotes (in order of care) :
i) Re-use of extensions
ii) Easy configuration via Spring/Services.xml
iii) Looser coupling i.e. less dependence on Inheritance hierarchies, and more on interface injection.

Cheers

  • ciaran

Dan Diephouse - 19/Jul/06 04:17 PM
OK, I integrated something like this in SVN. I called the class WSDLExtension and it just has one method:

void extend(Definition d, WSDLBuilder builder)

Let me know if that works for you!


Ciaran Jessup - 20/Jul/06 02:36 AM
Looks good, only concern is now I have to infer which porttype I'm working with, from the definition? Is this correct ?

Dan Diephouse - 20/Jul/06 01:06 PM
You should be able to get the name of the service from builder.getService().getName() and work backwards from there. Does that work?