Hello

Oopss. 230 odd lines for my first message to this list it's a bit too
much. Sorry.
I'll add an overview here so that people can skip it if not interested (which
will make it still longer). You never know whether some subscriber might
be bored eading mail in a station or something...


summary

I present an odd use of the REST support in Axis2.

We have coded a client and server with Axis2 like
XML examples -> XSD -> tuned XSD -> WSDL -> Java stub, skeleton and beans
-> app
Steps 1,3 and 4 are automated, steps 2 and 5 are manual.

I refer to a problem with fault detection and REST, might be a bug
or an unssuported use, see JIRA AXIS2-3771

I attach the XSLT 2.0 sheet used for step 3, xsd2wsdl.xslt,
adapted from one by Arjen Poutsma.

Then I ask whether we can use axis2 in case we don't fully know
the content of the xml our client will get, just some of the elements
it will contain, and we can ignore the rest.

end of summary



We had a web application and had to add interoperability with
another application through soap (being a server of some services
and a client of others). So we decided to integrate axis2 in
the web application. While we were at it a new, more urgent
requirement came in to interoperate with yet another server,
through non-SOAP web services.

The documentation for this non-SOAP application explained that
we should send it an http(s) GET with some parameters and it
would return xml content. It included an example, let's imagine
like this:

http://server:8080/app/services/getData?id=123&page=1&itemsperpage=3

=>

<data result="OK">
 <items count="25">
  <item>
     <a>value for a</a>
     <b>value for b</b>
     <c>value for c</c>
  </item>
  <item>
     <a>value for a in the second element</a>
     <b>value for b in the 2nd...</b>
     <c>... c in 2nd...</c>
  </item>
  <item>
     <a>... a in 3rd....</a>
     <b>... b ... 3 ... </b>
     <c>... c 3 ... </c>
  </item>
 <items>
<data>

Then the documentation gave a table with descriptions of the data:

element type      desc
a        string   a-ness of the element
b        string   b attribute of ...
c        string   such and such
d        datetime moment of inspiration for such an element
e        int      cm3 of beer...

(we assumed d and e where optional elements that could appear)

It could also return errors, in two ways:
like this:
<data result="KO">
   <errors>
     <error desc="sorry, boy, but no luck"/>
     <error desc="anyway, we didn't know that id"/>
   <errors>
</data>

or like this:

<error desc="you won't try to make me work today, will you?"/>

In retrospect we should have used an http client and an XML parser and
get done with it, but we thought that we could leverage axis2 since we
have axis2 integrated, and axis2 has some support for REST (or POX,
but I don't want to argue that because in our simple case they might
even be the same).

So what we did was (inspired by this post by Arjen Poutsma
http://blog.springframework.com/arjen/archives/2006/07/27/xslt-that-transforms-from-xsd-to-wsdl/
):

A- use inst2xsd in xmlbeans to produce a preliminar xsd from the xml
samples.  (inst2xsd is a tool in xmlBeans that infers schema from
examples)

B- modify the xsd manually to :

 B.1 - accomodate the documentation (add optional fields, declare the
 data types properly...)

 B.2 - make data have two optional elements "items" and "errors" so
       that we can get either data or the error list.

 B.3 - add an element for the parameters (we won't send the parameters
       by xml, but we pretend we can so that axis2 REST support
       accepts/sends the call using parameters in the url)

 B.4 - add another element which we'll use as an exception for the
       answer with the single "error" element


C- generate an wsdl from the xsd (with Poustma's xslt script, adapted
to handle empty namespaces and include fault declarations for the
elements matching the naming convention, in our case "error", so that
axis throws them as exceptions) I tried to send the changes to Arjen
Poustma, in case he or she is interested but wasn't able to reach him or
her. I'll attach it here in case anyone's interested (but it's not
fully tested). I used orangeVolt eclipseXSLT with Saxon to apply it
because it's XSLT 2.0.

D- generate the data beans corresponding to the xml, a client and a
server with axis2, with WSDL2Java

E- code a simple test server (we don't have access to a server like
the one we have to interoperate with during development, only at
scheduled test visits).  We could have used static test data in xml
files, but we wanted a little diversity so wrote a server that
returned near random data with the characteristics we wanted. This
server was to behave as the documentation described the real server.

F- configure axis2 to accept REST invocation for this test server,
don't use namespaces, etc.

G- code our client for our web application, configuring the stub to
use REST

It's really more complex to explain it than to do it, and the tools
take care of all the tedious coding, leaving us only the business
logic, as it should be. I miss an eclipse plugin that integrates all
these tools for this kind of tasks (and couldn't use axis2 plugin for
task D because I wanted the generated classes in a package even
without namespaces, but the command line or ant task worked fine).

We got the test server to behave as we thought the real server would.
We got the client to behave almost right, except that when the server
sent the fault <error desc="foobar"/> the Axis2 stub wouldn't throw
the generated exception, but an IllegalArgumentException (I filed
https://issues.apache.org/jira/browse/AXIS2-3771
in case it is a bug)



We finally went to test life with the real server and we found the
answer we got was more like

<data result="OK">
 <items count="25">
  <item>
     <stuff>bla</stuff>

     <a>value for a</a>

     <foo>foo value for 1</foo>

     <c>value for c</c>

     <b>value for b</b>
     <d>2008-05-10T12:00:00.123Z/d>
     <e>500</e>
     <some>
        <more>stuff</more>
     </some>
     <and>
        <so> ... </so>
        <on> ... </on>
        <on> ... </on>
        <on> ... </on>
     </and>

  </item>
  <item>
     <stuff>bla</stuff>
     <a>value for a in the second element</a>
     <foo>foo value for 1</foo>
     <c>... c in 2nd...</c>

    <b>value for b in the 2nd...</b>
     <d>2008-05-10T12:00:00.123Z/d>
     <e>500</e>
     <and>
        <so> ... </so>
        <on> ... </on>
     </and>

  </item>
 <items>
<data>


That is: the elements we expected were there in a different order
and there were new unexpected elements before, after and between them.
Not all of the new elements were always present, so at least some were
optional, and we only got two examples, there might be optional elements
missing in both that could appear one day in production.

Ok, we regenerated xsd, wsdl and java classes from the examples we got
from the live server, putting minOccurs="0" in all the new elements,
and made it work so that we could perform some other tests that run
after that one. So it then would work with the examples in the
documentation and the one we had seen from the server. But we don't
know what can happen with more examples from the real server. So we
told our customer we couldn't guarantee interoperability yet and they
put us in touch with the provider of that server. So we wrote them to
ask for more details on what the server can return.

Their answer so far has been that the documentation says all we need to know
(it didn't say there were no more possible elements, it just described some),
that any other elements are optional and any may come and that the order
of elements is not important in xml, that's why there are different tags
to mark data.

Well of course you can define xml uses where order of elements is not
important and you can almost parse an xml with just the information of
some of the elements you're going to find (you just need to ask the
extra requirement that none of the added elements repeats the name of
any of the elements you know, so as not to have to choose between two
identically named elements for the single value you need).  But in any
case this adds unnecessary complexity and can be avoided, and it is
not typical xml usage. We're still trying to get the complete
information to make this simpler.

But the question is (in fact more out of curiosity than because I
would think it's any worthwhile use case): is there any way you can
declare in your wsdl that messages can contain almost anything and
axis2 should parse them and extract just a few known elements ? (any
one of each name, if there'd be more). I tried using xsd:any in
several places and didn't try xsd:choose because I thought that
wouldn't work when generating code, but maybe I'm missing something
obvious. I think xsd:any won't cut it because you don't know how many
elements can come between interesting elements and you don't have a
way to restrict xsd:any to any element with a name not belonging to a
given set.  If I could express it in wsdl at least I would be a formal
specification in case someone else wants to talk to our client in the
future (not too likely).

Or if as I suspect there is no way to do that through wsdl, is there a
hook in axis2 where I can easily plug custom code to modify the input
the client gets and extract the interesting elements off it. Maybe
using xslt on the input would be too expensive (is it?) but supplying a
custom SAX parser that just fills some beans would be efficient and
easy enough to code ?


I repeat I don't pretend that using axis2 for such a task would
be the ideal solution, I believe it must have been thought for more
precisely specified services, but I wonder whether it can be used,
and I guess trying it's a way to learn a little about axis2, xsd and wsdl.

Thanks to anyone who have the patience to reach till here.



Attachment: xsd2wsdl.xslt
Description: XML document

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to