Hi Francesco,
On 23/01/15 14:56, Francesco Chicchiriccò wrote:
On 23/01/2015 13:12, Sergey Beryozkin wrote:
Hi All
Colm found out few weeks back that a Syncope REST service WADL can not
be generated back into the Java code with a CXF wadl-to-java plugin.
Here is the original info Colm helped with:
A ResourceService has two "list" methods:
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
List<ResourceTO> list();
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
List<ResourceTO> list(@NotNull @MatrixParam("connectorId") Long
connInstanceId);
This is represented in WADL like this: (I've removed <doc> and some
other mark up. like extra representations, etc):
<resource path="/resources">
<param name="connectorId" style="matrix" type="xs:long"/>
<method name="GET">
<response>
<representation mediaType="application/xml"
element="syncope1:resources"/>
</response>
</method>
<method name="GET">
<response>
<representation mediaType="application/xml"
element="syncope1:resources"/>
</response>
</method>
</resource>
here is a relevant generated Java code:
@GET
@Produces({"application/xml", "application/json" })
Resources list(@MatrixParam("connectorId") Long connectorId);
@GET
@Produces({"application/xml", "application/json" })
Resources list(@MatrixParam("connectorId") Long connectorId);
which fails to compile.
The issue stems from the fact the 2 original GET methods depend on a
custom selection algorithm (the optional parameters like MatrixParam)
do not affect the JAX-RS selection algorithm process, hence by default
those 2 methods are equal candidates so an extension is used to make
the selection predictable.
next, WADL requires that the path segment parameters (PathParam or
MatrixParam) are represented as the immediate wadl:resource children
as the generated WADL fragment shows.
Thus a WADL to Java generation has no idea that one of the two list
methods needs to have a MatrixParam in its signature, the other does not.
There are two ways to fix it.
1. simply collapse the original two methods into one and check if
MatrixParam is null inside the method:
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
List<ResourceTO> list(@MatrixParam("connectorId") Long
connInstanceId);
The requests with or without this Matrixparam will be routed to
this method. The only side-effect: the client proxies which do list()
would need to do list(null).
2. I've added a new WADLGenerator property in CXF 3.0.3,
"ignoreOverloadedMethods". If it is set then you'd just get:
<resource path="/resources">
<param name="connectorId" style="matrix" type="xs:long"/>
<method name="GET">
<response>
<representation mediaType="application/xml"
element="syncope1:resources"/>
</response>
</method>
</resource>
which is correct. We can tune the generator further to have
<param name="connectorId" style="matrix" type="xs:long"
required="false"/>
but matrix parameters are optional by the definition.
Hi Sergey,
I am not sure I am following everything above, but are you suggesting
that adding ignoreOverloadedMethods="true" (since Syncope is using CXF
3.0.3) would solve the issue?
Yes, this is one of the options
In any case, would you mind to open an issue on JIRA for this? Thanks.
Sure.
Finally, not an issue but a praise for a WADL stylesheet shipped with
Syncope. I saw a recent presentation from Colm, and I thought, wow,
would it be great if CXF WADLGenerator could optionally reference such
a stylesheet via an XML processing instruction. In fact I've even
updated the generator to do it if it is configured with a reference to
a class path resource.
We've done in CXF some work for the optional Swagger integration and
Andriy Redko even did a demo. I think one of the reasons Swagger is so
popular because people can get UI auto-generated out of it.
Would it possible to get this style-sheet shipped in a self-contained
module? CXF users who need would add it to a classpath and then
configure CXF WADLGenerator with a class path reference to it...
Nice that you like our old-fashioned-technology XSLT :-)
When I built that I've also taken a look at Swagger, liked it but had to
drop it out because of some heavy dependency (the Scala compiler).
I think WADL is very capable. I think Swagger is flying because it is
uses a JSON format (it is just more popular as opposed to more capable
than XML), has the option to add the extensions, and + UI.
WADL is more capable in describing REST services IMHO, the extensions
can be easily added, UI can be there. I'm not trying to say people have
to use WADL if they like Swagger :-), but WADL does deserve a bit more
'justice' I'd say, it was a very well designed spec from M.Hadley
If you want, and also provide some details and guidance about how to fit
into there, I can contribute the XSL to a new CXF module and we can have
also Syncope to depend on that. WDYT?
I'll try to create a CXF test with some basic copy/transform template
and then I'll share a link and we can discuss what might be done next
Thanks, Sergey
Regards.
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com