<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Oct 27, 2015 at 10:47 AM, Juan Hernández <span dir="ltr">&lt;<a href="mailto:jhernand@redhat.com" target="_blank">jhernand@redhat.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">On 10/27/2015 10:16 AM, Roman Mohr wrote:<br>
&gt;<br>
&gt;<br>
&gt; On Mon, Oct 26, 2015 at 5:32 PM, Juan Hernández &lt;<a href="mailto:jhernand@redhat.com">jhernand@redhat.com</a><br>
</span><div><div class="h5">&gt; &lt;mailto:<a href="mailto:jhernand@redhat.com">jhernand@redhat.com</a>&gt;&gt; wrote:<br>
&gt;<br>
&gt;     On 10/26/2015 04:56 PM, Roman Mohr wrote:<br>
&gt;     &gt; Hi Juan,<br>
&gt;     &gt;<br>
&gt;     &gt; The way to specify the contract look pretty clean and nice.<br>
&gt;     &gt; I would love to read a few words about the big picture. What is the<br>
&gt;     &gt; final scenario?<br>
&gt;     &gt;<br>
&gt;<br>
&gt;     The motivation for this change is that currently we don&#39;t have a central<br>
&gt;     place where the RESTAPI is specified, rather we have several different<br>
&gt;     places, using several different technologies:<br>
&gt;<br>
&gt;     * XML schema for the data model.<br>
&gt;     * JAX-RS for part of the operational model (without the parameters).<br>
&gt;     * rsdl_metadata.yaml for the parameters of the operational model.<br>
&gt;<br>
&gt;     This makes it difficult to infer information about the model. For<br>
&gt;     example, the generators of the SDKs have to download the XML schema, and<br>
&gt;     the RSDL (which is generated from the JAX-RS interfaces using reflection<br>
&gt;     and combining it with the information from the rsdl_metadata.yaml file)<br>
&gt;     and then they have to do their own computations to extract what they<br>
&gt;     need.<br>
&gt;<br>
&gt;     Same happens with the CLI: it has to extract the information it needs<br>
&gt;     from the Python code generated for the Python SDK, yet another level of<br>
&gt;     indirection.<br>
&gt;<br>
&gt;<br>
&gt; You are right, that definitely needs to be cleaned up. I just want to<br>
&gt; discuss a few points below with you.<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;     We are also lacking a comprehensive reference documentation of the<br>
&gt;     RESTAPI. What we currently have has been written by hand, and gets out<br>
&gt;     of sync very quickly, and we don&#39;t even notice.<br>
&gt;<br>
&gt;<br>
&gt; Did you also consider swagger? It is made for exactly that purpose.<br>
&gt; I created a demo in [1] which uses resteasy, weld, hibernate-validator<br>
&gt; and swagger to demonstrate how to do DRY with jaxrs.<br>
&gt; Would be great to hear you thoughts on that.<br>
&gt;<br>
&gt; And there is the great swagger-ui [8] to display the documentation in a<br>
&gt; more human readable way.<br>
&gt;<br>
<br>
</div></div>Yes, I considered Swagger, and rejected it because it is JSON centric,<br>
and I think JSON isn&#39;t as good as Java to represent the contracts of our<br>
RESTAPI.<br></blockquote><br></div><div class="gmail_quote">You just write plain jax-rs, swagger just creates a description out of it. So  the source defining the contract is pure java (jax-rs with some swagger annotations for description, etc.).<br></div><div class="gmail_quote">Or am I missing the point here?<br></div><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
In addition we need to do these changes in a smooth way, without causing<br>
big changes in the middle. For example, in the first step we need to<br>
preserve the JAX-RS interfaces as they are today, to avoid massive<br>
changes to all the resource implementations. This could be done with<br></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Swagger, but would require custom code generators. With less effort we<br>
can do our own.<br></blockquote><div><br></div><div>This is of course generally a difficult task. But I do not know why it would be more difficult to write a custom swagger reader (if we even have to, it can read the interfaces as well) .<br></div><div>They are pretty streight forward. Just look at [9], this contains the wole jax-rs specific code to generate the swagger documentation.<br><br></div><div>But yes, I don&#39;t know every detail here of the engine and can&#39;t clearly say that integrating that would just streight forward (my feeling tells me that it would not be too hard). I am just under the impression that we would benefit from that. Just reduces custom magic to a minimum.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Swagger UI is certainly great. I did test it and it is really good. We<br>
may be able to copy some concepts.<br>
<div><div class="h5"><br>
&gt;<br>
&gt;<br>
&gt;     To solve these issues I intend to have the specification of the RESTAPI<br>
&gt;     only in one place, and using only one technology. I decided to use Java<br>
&gt;     interfaces for that. Note however that they are just the support for the<br>
&gt;     information, like paper is the support for ink. I decided to use Java<br>
&gt;     because it is easy to create, modify and re-factor using tools familiar<br>
&gt;     to most of us.<br>
&gt;<br>
&gt;     These source of these interfaces is analysed (using QDox, currently) and<br>
&gt;     a &quot;model&quot; of the RESTAPI is generated in memory. This model is<br>
&gt;     independent of the supporting Java source, and easy to consume. For<br>
&gt;     example, imagine that you want to list all the types available in the<br>
&gt;     model and for each one display its documentation:<br>
&gt;<br>
&gt;       Model model = ...;<br>
&gt;       for (Type type : model.getTypes()) {<br>
&gt;         Name name = type.getName();<br>
&gt;         String doc = type.getDoc();<br>
&gt;         System.out.println(name + &quot;: &quot; + doc);<br>
&gt;       }<br>
&gt;<br>
&gt;     Something like this, but more elaborate, will be part of a web<br>
&gt;     application that provides comprehensive reference documentation,<br>
&gt;     assuming that we dedicate the time to write documentation comments in<br>
&gt;     the specification.<br>
&gt;<br>
&gt;     I intend to use this model also to do simplify the generators of the<br>
&gt;     SDKs and the CLI.<br>
&gt;<br>
&gt;     In addition these are some of the things that I would like to change in<br>
&gt;     the near future (for 4.0):<br>
&gt;<br>
&gt;     * Move the specification of the parameters of operations out of the<br>
&gt;     rsdl_metadata.yaml file and into the model. For example:<br>
&gt;<br>
&gt;       @Service<br>
&gt;       public VmService {<br>
&gt;         /**<br>
&gt;          * The operation to add a virtual machine.<br>
&gt;          */<br>
&gt;         interface Add {<br>
&gt;           /**<br>
&gt;            * The representation of the virtual machine is received<br>
&gt;            * as parameter, and the representation of the created<br>
&gt;            * virtual machine is returned as result.<br>
&gt;            */<br>
&gt;            @In @Out Vm vm();<br>
&gt;<br>
&gt;            /**<br>
&gt;             * In the future, we will be able to specify other<br>
&gt;             * parameters here.<br>
&gt;             */<br>
&gt;            @In Boolean force();<br>
&gt;<br>
&gt;            /**<br>
&gt;             * Even with default values.<br>
&gt;             */<br>
&gt;            @In default Boolean force() { return true; }<br>
&gt;<br>
&gt;            /**<br>
&gt;             * And we will be able to specify constraints, which<br>
&gt;             * will replace the rsdl_metadata.yaml file.<br>
&gt;             */<br>
&gt;            @Constraint<br>
&gt;            default boolean vmNameMustNotBeNull() {<br>
&gt;              return vm().name() != null;<br>
&gt;            }<br>
&gt;          }<br>
&gt;       }<br>
&gt;<br>
&gt;     * Enforce the constraints automatically. If the constraints are in the<br>
&gt;     model, then we can just check them and reject requests before delivering<br>
&gt;     them to the application. Currently we do this manually (and often<br>
&gt;     forget) with calls to &quot;validate(...)&quot; methods.<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; Did you consider just annotating the DTOs with JSR-303 annotations and<br>
&gt; integrate a validator with jax-rs?<br>
&gt; See [2] for an example.<br>
&gt;<br>
<br>
</div></div>This is a great way to implement a system, but the goal here isn&#39;t to<br>
implement it, rather to specify it. Using annotations in this way won&#39;t<br>
help the generators of the SDKs, for example, to figure out what<br>
parameters are required, mandatory, etc.<br>
<span class=""><br></span></blockquote><div><br></div><div>Swagger understands them. From my example project, swagger created that<br><br>     description:<br>        type: &quot;string&quot;<br>        minLength: 10<br>        maxLength: 100<br> <br></div><div>out of <br><br></div><div>     @Size(min=10, max=100) # jsr-303<br></div><div>     private String description;<br></div><div><br></div><div>and so does swagger-codegen which can generate clients in java, python, ...<br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
&gt;<br>
&gt;<br>
&gt;     * Generate the Java classes directly from the model. Instead of Model -&gt;<br>
&gt;     XML Schema -&gt; Java, we can do Model -&gt; Java. This will allow us to solve<br>
&gt;     some of the XJC compiler limitations, like the horrible way we handle<br>
&gt;     arrays today.<br>
&gt;<br>
&gt;<br>
&gt; Swagger [3] is a rest documentation specification. There is also a maven<br>
&gt; plugin [4] and you can create clients for example with [5].<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt;     * Replace JAX-RS with a simpler infrastructure that supports better<br>
&gt;     streaming and CDI injection.<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; With resteasy-cdi you have pretty good injection support for resteasy.<br>
&gt; Run the demo in [1] to see it in action and look at the file at [6].<br>
&gt;<br>
<br>
</span>Resteasy-CDI isn&#39;t standard, it only works with Resteasy. If we rely on<br>
it then we re tied to Resteasy for ever.<br>
<span class=""><br></span></blockquote><div><br></div><div>Even jersey has support for that (I think it is called jeryse-gf-cdi), but why would we want switch? I don&#39;t think that jboss will drop resteasy and it also works fine outside of full blown containers. I don&#39;t think that this is an argument.<br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
&gt;<br>
&gt;<br>
&gt;     * Add support for multiple versions of the API, using the &quot;Version&quot;<br>
&gt;     header, and generating different Java classes for entities and services.<br>
&gt;     For example, if we have versions 4 and 5 of the model as separate<br>
&gt;     artifacts, then we can generate &quot;V4Vm&quot; and &quot;V5Vm&quot; entity classes, and<br>
&gt;     &quot;V4VmService&quot; and &quot;V5VmService&quot; service classes. These can be used<br>
&gt;     simultaneously in the server, so we can have in the same engine<br>
&gt;     implementations for multiple versions.<br>
&gt;<br>
&gt;<br>
&gt; There are also many ways to do that. Here [7] is a pretty clean way to<br>
&gt; do it with jax-rs and you will have everything related in one resource.<br>
&gt;<br>
<br>
</span>Yes, there are many ways. In my opinion it is better to use the HTTP<br>
&quot;Version&quot; header, and to forward requests to different resource<br>
implementations without requiring different URLs or different content types.<br>
<span class=""><br></span></blockquote><div>Have no strong opinion there, just seemed to be a good choice regarding to versioning limitations in jax-rs and our use of jax-rs subresources.<br> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="">
&gt;<br>
&gt;<br>
&gt;     The final picture isn&#39;t completely defined yet.<br>
&gt;<br>
&gt;     Regards,<br>
&gt;     Juan Hernandez<br>
&gt;<br>
&gt;     &gt; On Mon, Oct 26, 2015 at 4:03 PM, Juan Hernández &lt;<a href="mailto:jhernand@redhat.com">jhernand@redhat.com</a> &lt;mailto:<a href="mailto:jhernand@redhat.com">jhernand@redhat.com</a>&gt;<br>
</span><div><div class="h5">&gt;     &gt; &lt;mailto:<a href="mailto:jhernand@redhat.com">jhernand@redhat.com</a> &lt;mailto:<a href="mailto:jhernand@redhat.com">jhernand@redhat.com</a>&gt;&gt;&gt; wrote:<br>
&gt;     &gt;<br>
&gt;     &gt;     Hello,<br>
&gt;     &gt;<br>
&gt;     &gt;     I will soon merge the following patches that introduce a new<br>
&gt;     way to<br>
&gt;     &gt;     specify the contracts of the RESTAPI:<br>
&gt;     &gt;<br>
&gt;     &gt;       restapi: Introduce metamodel<br>
&gt;     &gt;       <a href="https://gerrit.ovirt.org/45852" rel="noreferrer" target="_blank">https://gerrit.ovirt.org/45852</a><br>
&gt;     &gt;<br>
&gt;     &gt;       restapi: Use metamodel<br>
&gt;     &gt;       <a href="https://gerrit.ovirt.org/46478" rel="noreferrer" target="_blank">https://gerrit.ovirt.org/46478</a><br>
&gt;     &gt;<br>
&gt;     &gt;       restapi: Generate JAX-RS interfaces from model<br>
&gt;     &gt;       <a href="https://gerrit.ovirt.org/47337" rel="noreferrer" target="_blank">https://gerrit.ovirt.org/47337</a><br>
&gt;     &gt;<br>
&gt;     &gt;<br>
&gt;<br>
&gt;     &gt; Looks pretty much like we are replacing one way of annotating things<br>
&gt;     &gt; with another way of specifying things.<br>
&gt;     &gt; Could you elaborate what the benefit of that way of description is?<br>
&gt;     &gt;<br>
&gt;     &gt; How would I customize endpoints with e.g. @Gzip annotations? Would<br>
&gt;     I at<br>
&gt;     &gt; the end still have my JAX-RS annotates resource classes?<br>
&gt;     &gt;<br>
&gt;     &gt;<br>
&gt;     &gt;     These patches introduce a new &quot;metamodel&quot; concept, and move<br>
&gt;     the current<br>
&gt;     &gt;     specification of the RESTAPI based on XML schema and JAX-RS<br>
&gt;     interfaces<br>
&gt;     &gt;     to a new &quot;model&quot; built on the new metamodel.<br>
&gt;     &gt;<br>
&gt;     &gt;<br>
&gt;     &gt;     What does this mean for you in practical terms? Currently when<br>
&gt;     you want<br>
&gt;     &gt;     to introduce or modify one of the data types used by the<br>
&gt;     RESTAPI you<br>
&gt;     &gt;     start by modifying the XML schema. Once the patches are merged<br>
&gt;     the XML<br>
&gt;     &gt;     schema will never be touched, as it will be automatically<br>
&gt;     generated from<br>
&gt;     &gt;     the &quot;model&quot;. For example, imagine that you need to add a new<br>
&gt;     &quot;color&quot;<br>
&gt;     &gt;     attribute to the &quot;VM&quot; entity. To do so with the new model you<br>
&gt;     will have<br>
&gt;     &gt;     to modify the following file, which is the specification of<br>
&gt;     the &quot;Vm&quot;<br>
&gt;     &gt;     entity, written as a Java interface:<br>
&gt;     &gt;<br>
&gt;     &gt;<br>
&gt;     &gt;<br>
&gt;      <a href="https://gerrit.ovirt.org/#/c/46478/16/backend/manager/modules/restapi/model/src/main/java/types/Vm.java" rel="noreferrer" target="_blank">https://gerrit.ovirt.org/#/c/46478/16/backend/manager/modules/restapi/model/src/main/java/types/Vm.java</a><br>
&gt;     &gt;<br>
&gt;     &gt;     In that interface you will have to add a line like this:<br>
&gt;     &gt;<br>
&gt;     &gt;       String color();<br>
&gt;     &gt;<br>
&gt;     &gt;     Note that this Java interface is just the specification of the<br>
&gt;     entity,<br>
&gt;     &gt;     it won&#39;t be used at all during runtime. Instead of that the<br>
&gt;     XML schema<br>
&gt;     &gt;     will be generated from it, and then Java will be generated<br>
&gt;     from the XML<br>
&gt;     &gt;     schema, as we do today (this will change in the future, but<br>
&gt;     not yet).<br>
&gt;     &gt;<br>
&gt;     &gt;     Same for the services. If you want to add a new &quot;paint&quot; action<br>
&gt;     to the<br>
&gt;     &gt;     &quot;Vm&quot; resource then you won&#39;t modify the JAX-RS interfaces,<br>
&gt;     instead of<br>
&gt;     &gt;     that you will modify the following file, which is the<br>
&gt;     specification of<br>
&gt;     &gt;     the &quot;Vm&quot; service, written as a Java interface:<br>
&gt;     &gt;<br>
&gt;     &gt;<br>
&gt;     &gt;<br>
&gt;      <a href="https://gerrit.ovirt.org/#/c/47337/6/backend/manager/modules/restapi/model/src/main/java/services/VmService.java" rel="noreferrer" target="_blank">https://gerrit.ovirt.org/#/c/47337/6/backend/manager/modules/restapi/model/src/main/java/services/VmService.java</a><br>
&gt;     &gt;<br>
&gt;     &gt;     In that interface you will need to add a sub-interface<br>
&gt;     representing the<br>
&gt;     &gt;     action:<br>
&gt;     &gt;<br>
&gt;     &gt;       interface Paint {<br>
&gt;     &gt;       }<br>
&gt;     &gt;<br>
&gt;     &gt;     The JAX-RS interface will be generated from that. Currently these<br>
&gt;     &gt;     sub-interfaces are empty. In the future they will contain the<br>
&gt;     &gt;     specifications of the parameters (currently in the<br>
&gt;     rsdl_metadata.yml<br>
&gt;     &gt;     file).<br>
&gt;     &gt;<br>
&gt;     &gt;<br>
&gt;     &gt;<br>
&gt;     &gt;     These changes will currently affect only the specification of the<br>
&gt;     &gt;     RESTAPI, not the implementation, so in in the<br>
&gt;     &quot;Backend*Resource&quot; classes<br>
&gt;     &gt;     things won&#39;t change yet.<br>
&gt;     &gt;<br>
&gt;     &gt;<br>
&gt;     &gt; Currently I do not really understand where we are going here. Are we<br>
&gt;     &gt; trying to get rid of rdsl?<br>
&gt;     &gt;<br>
&gt;     &gt; So basically two questions:<br>
&gt;     &gt;<br>
&gt;     &gt; 1) What is the final goal?<br>
&gt;     &gt; 2) What speaks agains using Hibernate validator on Daos in combination<br>
&gt;     &gt; with JAX-RS annotated resources (and just removing all interfaces, as<br>
&gt;     &gt; far as I can see we only have one implementation per endpoint) and<br>
&gt;     &gt; creating all schemas and clients through SWAGGER tooling?<br>
&gt;     &gt;<br>
&gt;     &gt;<br>
&gt;     &gt;     If you have doubts, please let me know.<br>
&gt;     &gt;<br>
&gt;     &gt;     Regards,<br>
&gt;     &gt;     Juan Hernandez<br>
&gt;     &gt;<br>
&gt;     &gt;     --<br>
&gt;     &gt;     Dirección Comercial: C/Jose Bardasano Baos, 9, Edif. Gorbea 3,<br>
&gt;     planta<br>
&gt;     &gt;     3ºD, 28016 Madrid, Spain<br>
&gt;     &gt;     Inscrita en el Reg. Mercantil de Madrid – C.I.F. B82657941 -<br>
&gt;     Red Hat<br>
&gt;     &gt;     S.L.<br>
&gt;     &gt;     _______________________________________________<br>
&gt;     &gt;     Devel mailing list<br>
&gt;     &gt;     <a href="mailto:Devel@ovirt.org">Devel@ovirt.org</a> &lt;mailto:<a href="mailto:Devel@ovirt.org">Devel@ovirt.org</a>&gt;<br>
</div></div>&gt;     &lt;mailto:<a href="mailto:Devel@ovirt.org">Devel@ovirt.org</a> &lt;mailto:<a href="mailto:Devel@ovirt.org">Devel@ovirt.org</a>&gt;&gt;<br>
<div class=""><div class="h5">&gt;     &gt;     <a href="http://lists.ovirt.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.ovirt.org/mailman/listinfo/devel</a><br>
&gt;     &gt;<br>
&gt;     &gt;<br>
&gt;     &gt; Thanks,<br>
&gt;     &gt;<br>
&gt;     &gt; Roman<br>
&gt;<br>
&gt;<br>
&gt;     --<br>
&gt;     Dirección Comercial: C/Jose Bardasano Baos, 9, Edif. Gorbea 3, planta<br>
&gt;     3ºD, 28016 Madrid, Spain<br>
&gt;     Inscrita en el Reg. Mercantil de Madrid – C.I.F. B82657941 - Red Hat<br>
&gt;     S.L.<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; I don&#39;t know if it is the right thing to do to invent something new<br>
&gt; here. I personally would prefer to thread a path which is very common on<br>
&gt; the java community.<br>
&gt; I would love follow the DRY principle regarding to the stack and the<br>
&gt; code and would just use the great community projects there.<br>
&gt;<br>
&gt; It would also completely eliminate any custom magic. The JAX-RS and CDI<br>
&gt; magic is pretty standard and easy to understand.<br>
&gt; From my perspective, real JAX-RS resoures have the advantage of<br>
&gt;<br>
&gt;  * being very easy to understand (there is magic, but the connection to<br>
&gt; the real endpoint is pretty clear)<br>
&gt;  * being easy to customize suff, like adding @GZip to an annotation<br>
&gt;  * describing pretty clearly the connection between the generated rest<br>
&gt; interface and the internal services<br>
&gt;<br>
&gt; Finally writing hand crafted tests is also much easier.<br>
&gt;<br>
&gt; What are your thoughts about that?<br>
&gt;<br>
&gt; Best Regards,<br>
&gt; Roman<br>
&gt;<br>
&gt;<br>
&gt; [1] <a href="https://github.com/rmohr/jetty-maven-cdi-demo" rel="noreferrer" target="_blank">https://github.com/rmohr/jetty-maven-cdi-demo</a><br>
&gt; [2]<br>
&gt; <a href="https://github.com/rmohr/jetty-maven-cdi-demo/blob/master/src/main/java/rmohr/examples/cdi/MyDto.java" rel="noreferrer" target="_blank">https://github.com/rmohr/jetty-maven-cdi-demo/blob/master/src/main/java/rmohr/examples/cdi/MyDto.java</a><br>
&gt; [3] <a href="http://swagger.io/" rel="noreferrer" target="_blank">http://swagger.io/</a><br>
&gt; [4] <a href="https://github.com/kongchen/swagger-maven-plugin" rel="noreferrer" target="_blank">https://github.com/kongchen/swagger-maven-plugin</a><br>
&gt; [5] <a href="https://github.com/swagger-api/swagger-codegen" rel="noreferrer" target="_blank">https://github.com/swagger-api/swagger-codegen</a><br>
&gt; [6]<br>
&gt; <a href="https://github.com/rmohr/jetty-maven-cdi-demo/blob/master/src/main/java/rmohr/examples/cdi/RestSubResource.java" rel="noreferrer" target="_blank">https://github.com/rmohr/jetty-maven-cdi-demo/blob/master/src/main/java/rmohr/examples/cdi/RestSubResource.java</a><br>
&gt; [7]<br>
&gt; <a href="http://maxenglander.com/2013/04/23/basic-restful-api-versioning-in-jersey.html" rel="noreferrer" target="_blank">http://maxenglander.com/2013/04/23/basic-restful-api-versioning-in-jersey.html</a><br>
&gt; [8] <a href="https://github.com/swagger-api/swagger-ui" rel="noreferrer" target="_blank">https://github.com/swagger-api/swagger-ui</a><br>
&gt;<br></div></div></blockquote><div>[9] <a href="https://github.com/swagger-api/swagger-core/blob/master/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java">https://github.com/swagger-api/swagger-core/blob/master/modules/swagger-jaxrs/src/main/java/io/swagger/jaxrs/Reader.java</a> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class=""><div class="h5">
<br>
<br>
<br>
</div></div><div class=""><div class="h5">--<br>
Dirección Comercial: C/Jose Bardasano Baos, 9, Edif. Gorbea 3, planta<br>
3ºD, 28016 Madrid, Spain<br>
Inscrita en el Reg. Mercantil de Madrid – C.I.F. B82657941 - Red Hat S.L.<br>
</div></div></blockquote></div><br></div></div>