Adam - thank you very much !

On Oct 16, 2007, at 9:57 AM, Adam Chesney wrote:

Hi Andy,

To clarify - yes your clients would need to compile once against the new WSDL (with the extra elements in). But once they had done that, then you are then free to add elements and attributes in the future without them having to compile against a new version of the WSDL. In otherwords, this won't really help you right now, but it will future proof your clients so that they don't run into this issue again sometime down the road. I would hope that it would be okay to say to your clients - ok we have a new version of the WSDL that you really need to upgrade to just this once and we promise not to force you to do it again ;-). As long as you give them a decent window of time to make the upgrade, I think that's fair enough.

I thought about maintaining multiple versions of WSDL's etc but I never found a way to overcome the maintenence nightmares. So I solved this problem with the additions to XFire described below. It works very well for us.

Cheers,

Adam

Andy Gelfond wrote:
Thanks Adam -

Just to make sure - our problem is that our clients do not necessarily rebuild their client, and are compiled against an older WSDL. When we add a new field to our WSDL, their client still uses the older WSDL and breaks. I am not sure how this would help - won't the client need to compile against the newer WSDL with the maxOccurs/minOccurs ?

Can we do what we want with either WSDL versioning, or as a second resort, use multiple WSDL's and select the proper one on our side to use based on a version number supplied to us by the client ? In order to do the latter, we would need to force xfire to use different WSDL's against a single code base -

Thanks,
Andy


On Oct 16, 2007, at 7:36 AM, Adam Chesney wrote:

just in case u didn't see this on the list

From: Adam Chesney <[EMAIL PROTECTED]>
Date: October 16, 2007 7:28:09 AM EDT
To: [email protected]
Subject: Re: [xfire-user] really simple versioning ?
Reply-To: [email protected]


Hi Andy,

This is the way we do it using Aegis.

1) setup our Type Mapping Registry and add a Configuration to it like this:

    <bean id="webAnnotations"
class="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations" / >
    <bean id="handlerMapping"
class="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping"
        autowire="no">
        <property name="typeMappingRegistry">
            <ref bean="typeMappingRegistry" />
        </property>
        <property name="xfire">
            <ref bean="xfire" />
        </property>
        <property name="webAnnotations">
            <ref bean="webAnnotations" />
        </property>
    </bean>
    <bean id="typeConfig"
        class="org.codehaus.xfire.aegis.type.Configuration">
        <property name="defaultExtensibleElements" value="true" />
        <property name="defaultExtensibleAttributes" value="true" />
        <property name="defaultNillable" value="false" />
        <property name="defaultMinOccurs" value="1" />
    </bean>
    <bean id="typeMappingRegistry"
class="com.xmltravel.fab.core.types.aegis.FABTypeMappingRegistry">
        <property name="configuration">
            <ref bean="typeConfig" />
        </property>
    </bean>

FABTypeMappingRegistry just inherits from org.codehaus.xfire.aegis.type.DefaultTypeMappingRegistry and adds a few custom types for dateTime handling.

The key here is:

        <property name="defaultExtensibleElements" value="true" />
        <property name="defaultExtensibleAttributes" value="true" />

Which will mean that your resulting WSDL will contain complex types like this:

<xsd:complexType name="ResponseHeader">
    <xsd:sequence>
        <xsd:element name="target" type="ns2:Target"/>
        <xsd:element name="timingInfo" type="ns7:TimingInfo"/>
        <xsd:element name="trackingInfo" type="ns7:TrackingInfo"/>
        <xsd:element name="userInfo" type="ns7:UserInfo"/>
        <xsd:any maxOccurs="unbounded" minOccurs="0"/>
    </xsd:sequence>
    <xsd:anyAttribute/>
</xsd:complexType>

which include extra tags <xsd:any maxOccurs="unbounded" minOccurs="0"/> and <xsd:anyAttribute/> which means that any extra content will also not break the schema. When Axis build against this then it will accept things it doesn't recognise and store them in extra data structures.

2) As this will effect ALL classes converted via Aegis we also want to lock down what users can send in. So we add the following annotations to all request only classes (i.e. Classes that only ever occur within request structures and can't possibly be returned to the clients):

@XmlType(extensibleAttributes=false, extensibleElements=false)
public class TrackingInfo extends com.xmltravel.fab.core.response.TrackingInfo
{
// blah
}

This will supress the extra elements being added to the WSDL schema and prevent clients sending in anything they like.

I hope this helps you out.

Cheers,

Adam Chesney

Lead Architect
Multicom Products Ltd


Andy Gelfond wrote:
We use xfire to provide a service to a number of clients. We have found that by simply adding a new field to an object, some of our clients break.

Clients who do not recompile their code based on the new wsdl will break if they are using axis:
http://www.ncbi.nlm.nih.gov/entrez/query/static/esoap_help.html

We generate our wsdl based on our code, and it seems we generate our return datastream based on the code also.
Is there a simple workaround using xfire ?

Thanks in advance,
Andy


Reply via email to