Hi Andy,

I think what I have described is exactly what you want. In fact I am convinced of it.

This line:

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

Refers to an _optional _part of the process which you only need to do if you want to limit what your clients send in to in request objects.

Let me explain. Adding the config to the type mapping registry as shown will cause ALL complex objects in your WSDL doc to allow extra elements and attributes, which is exactly what you want because then when your clients build using axis against that WSDL the classes that Axis generates will include the extra buckets for "unrecognised" content. If that's all you want to do then stop there and it should work for you as intended.

I complicated matters by trying to explain how we went a step further. The issue we saw was that with ALL complex objects in the WSDL allowing extra elements/attributes, as well as protecting our clients from future upgrades we were in essence also allowing them to send in to us (in the request structures) extra data that we might not recognise. The extra step is just designed to turn off the extra data allowed for request structures only. That won't be a problem for your clients. You can still upgrade your request objects in the future, as long as you only add new optional elements, but those upgrades won't be apparent to your clients unless they download the latest WSDL. However, they can still send in older style request structures without those new optional elements and your web service will allow them and potentially return new style response structures with extra elements in that the client doesn't know about but will happily accept anyway because all their response structures allow extra elements.

I hope that clarifies it. I realise I still may not be explaining it that well.

Cheers,

Adam

Andy Gelfond wrote:
Hi Adam,

Sorry to bother you again. After reviewing more carefully, our problem is the reverse - "This will supress the extra elements being added to the WSDL schema and prevent clients sending in anything they like."

We need to protect our clients from us returning objects to them that have added fields without requiring them to recompile against a new WSDL. We continually add extra fields to our return objects based on client needs.

The problem is that .NET handles the extra fields, Axis does not - it is a known bug. I was hoping to use WSDL versioning (single WSDL file), or as a backup, multiple WSDL's, and we would choose the WSDL based on what WSDL the client has. The question is - can we force xfire to stream XML back to our clients based on a given WSDL instead of using runtime type information ?

Thanks,
Andy


On Oct 16, 2007, at 10:16 AM, Adam Chesney wrote:

No problemo - glad to be of assistence.

Adam.

Andy Gelfond wrote:
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] <mailto:[EMAIL PROTECTED]>>
*Date: *October 16, 2007 7:28:09 AM EDT
*To: [EMAIL PROTECTED] <mailto:[email protected]>
*Subject: **Re: [xfire-user] really simple versioning ?*
*Reply-To: [EMAIL PROTECTED] <mailto:[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