[ovirt-devel] Some ideas on oVirt Java SDK

Vojtech Szocs vszocs at redhat.com
Mon Dec 1 15:13:52 UTC 2014



----- Original Message -----
> From: "Juan Hernández" <jhernand at redhat.com>
> To: "Michael Pasternak" <mishka8520 at yahoo.com>, "Vojtech Szocs" <vszocs at redhat.com>, devel at ovirt.org
> Sent: Monday, December 1, 2014 9:54:51 AM
> Subject: Re: [ovirt-devel] Some ideas on oVirt Java SDK
> 
> On 11/30/2014 12:26 PM, Michael Pasternak wrote:
> > Hey Vojtech,
> > 
> > How are you?, please see my reply inline.
> > 
> > 
> > 
> >     On Friday, November 28, 2014 5:26 PM, Vojtech Szocs
> >     <vszocs at redhat.com <mailto:vszocs at redhat.com>> wrote:
> > 
> > 
> >     Hi guys,
> > 
> >     since the initial (small, working & well-tested) version of oVirtJS
> >     JavaScript SDK is finished [*], I've started working on GWT wrapper
> >     for oVirtJS.
> > 
> >     While analyzing/reverse-engineering oVirt Java SDK, some thoughts
> >     came to my mind, and I wanted to share them with you.
> > 
> >     [*] TODO(vszocs) upload new patchset with all recent changes
> > 
> >     First, the way XJC (JAXB binding compiler that generates Java beans
> >     out of REST XSD schema) is invoked looks a bit weird to me, as Java
> >     SDK's XsdCodegen does this:
> > 
> >       Runtime.getRuntime().exec(command)
> > 
> >     Why not simply use existing Maven plugins to invoke XJC?
> >     - either: https://github.com/highsource/maven-jaxb2-plugin
> >     <https://github.com/highsource/maven-jaxb2-plugin>
> > 
> > 
> > [MP] sdk was using jaxb to begin with, it was replaced with XJC just
> > recently,
> > btw Juan, what was the motivation behind this?
> 
> This didn't change, the use of "xjc" is there since commit 95a25a4, Nov
> 12 2012.
> 
> Note that using Maven for this isn't as simple as it may look. The
> development model of the SDK is that the maven build does *not* generate
> any code, it just builds what has been manually generated previously.

To clarify, my question was meant for "ovirt-engine-sdk-java-codegen"
project and its org.ovirt.engine.sdk.codegen.Main class that produces
Java classes out of XSD as part of XsdCodegen.generate() method.

But if XsdCodegen invokes XJC programatically, what is the purpose of:

  org.jvnet.jaxb2.maven2:maven-jaxb22-plugin:generate

in "ovirt-engine-sdk-java-codegen" project's pom.xml?

Is it related to what XsdCodegen is doing?

> 
> > (REST api uses jaxb as well so we used to have 1x1 mappings)
> >  
> > 
> >     - or: http://mojo.codehaus.org/jaxb2-maven-plugin/
> >     <http://mojo.codehaus.org/jaxb2-maven-plugin/>
> > 
> > 
> > [MP] same.
> > 
> > 
> >     Second, and most importantly, what's the point of having "group"
> >     entities? I'll give an example - api.xsd contains this:
> > 
> >       <xs:complexType name="DataCenters">
> >         <xs:complexContent>
> >           <xs:extension base="BaseResources">
> >             <xs:sequence>
> >               <xs:annotation>
> >                 <xs:appinfo>
> >                     <jaxb:property name="DataCenters"/>
> >                 </xs:appinfo>
> >               </xs:annotation>
> >               <xs:element ref="data_center" minOccurs="0"
> >     maxOccurs="unbounded"/>
> >             </xs:sequence>
> >           </xs:extension>
> >         </xs:complexContent>
> >       </xs:complexType>
> > 
> >     (Same as above for Hosts, Clusters, VMs, etc.)
> > 
> >     This results in following (IMHO rather meaningless) Java class
> >     being generated by XJC:
> > 
> >     public class DataCenters extends BaseResources {
> > 
> >         @XmlElement(name = "data_center")
> >         protected List<DataCenter> dataCenters;
> > 
> >         public List<DataCenter> getDataCenters() {
> >             if (dataCenters == null) {
> >                 dataCenters = new ArrayList<DataCenter>();
> >             }
> >             return this.dataCenters;
> >         }
> > 
> >         public boolean isSetDataCenters() {
> >             return ((this.dataCenters!=
> >     null)&&(!this.dataCenters.isEmpty()));
> >         }
> > 
> >         public void unsetDataCenters() {
> >             this.dataCenters = null;
> >         }
> > 
> >     }
> > 
> >     Instead, we could use @XmlElementWrapper as described in [1]
> >     to avoid generating "group" entities altogether.
> > 
> >     [1] https://github.com/dmak/jaxb-xew-plugin
> >     <https://github.com/dmak/jaxb-xew-plugin>
> > 
> >     The fact that Java SDK provides decorator for each specific
> >     resource collection (like DataCenters), instead of having ONE
> >     resource collection type, greatly complicates overall design
> >     and code-gen aspect.
> > 
> > 
> > [MP] Well, i guess now is speaking JS constraints ghost, am i right?,
> > in any case, the reasons for having decorator per collection are:
> > 
> > 1. compliance with REST API (all SDKs and REST api are sharing same well
> > know architecture)
> > 2. "decorator" is a well known and commonly used java design pattern
> > 3. having one resource type serving all collections would create a
> > bottleneck
> > (well it might depend on how you implementing it, but still in my view
> > it's less convenient/readable
> > than dedicated collection with own context, verbs and behavior),
> > 
> > after all the purpose of sdk is being java client serving application in
> > "Java" way
> > (i.e type-safe + well bounded interface), while JS use-cases & paradigms
> > are totally
> > different, just consider:
> > 
> > [1] java-sdk stile
> > 
> > Disk snapshotDisk =
> > api.getVms().get('my-vm').getSnapshots().get('my-snapshot').getDisks().get('my-disk')
> > 
> > [2] JS style you propose
> > 
> > Disk snapshotDisk = getCollections().get(new Params[] { Disk.class,
> > 'my-vm', 'my-snapshot', 'my-disk'})
> > 
> > notice:
> > =====
> > 
> > in [2] you have a bunch of parameters disconnected form any context
> > where order
> > is *important* (other way you heuristic guesses what user meaning by
> > these params won't work),
> > obviously it's fragile and error prone,
> > 
> > while [1] is readable, well bounded, defending it's consumers from
> > potentials errors
> > (exactly what SDK should look like),
> > 
> > hope it helps.
> > 
> > 
> > 
> > 
> > 
> > 
> > On Friday, November 28, 2014 5:26 PM, Vojtech Szocs <vszocs at redhat.com>
> > wrote:
> > 
> > 
> > Hi guys,
> > 
> > since the initial (small, working & well-tested) version of oVirtJS
> > JavaScript SDK is finished [*], I've started working on GWT wrapper
> > for oVirtJS.
> > 
> > While analyzing/reverse-engineering oVirt Java SDK, some thoughts
> > came to my mind, and I wanted to share them with you.
> > 
> > [*] TODO(vszocs) upload new patchset with all recent changes
> > 
> > First, the way XJC (JAXB binding compiler that generates Java beans
> > out of REST XSD schema) is invoked looks a bit weird to me, as Java
> > SDK's XsdCodegen does this:
> > 
> >   Runtime.getRuntime().exec(command)
> > 
> > Why not simply use existing Maven plugins to invoke XJC?
> > - either: https://github.com/highsource/maven-jaxb2-plugin
> > - or: http://mojo.codehaus.org/jaxb2-maven-plugin/
> > 
> > Second, and most importantly, what's the point of having "group"
> > entities? I'll give an example - api.xsd contains this:
> > 
> >   <xs:complexType name="DataCenters">
> >     <xs:complexContent>
> >       <xs:extension base="BaseResources">
> >         <xs:sequence>
> >           <xs:annotation>
> >             <xs:appinfo>
> >                 <jaxb:property name="DataCenters"/>
> >             </xs:appinfo>
> >           </xs:annotation>
> >           <xs:element ref="data_center" minOccurs="0"
> > maxOccurs="unbounded"/>
> >         </xs:sequence>
> >       </xs:extension>
> >     </xs:complexContent>
> >   </xs:complexType>
> > 
> > (Same as above for Hosts, Clusters, VMs, etc.)
> > 
> > This results in following (IMHO rather meaningless) Java class
> > being generated by XJC:
> > 
> > public class DataCenters extends BaseResources {
> > 
> >     @XmlElement(name = "data_center")
> >     protected List<DataCenter> dataCenters;
> > 
> >     public List<DataCenter> getDataCenters() {
> >         if (dataCenters == null) {
> >             dataCenters = new ArrayList<DataCenter>();
> >         }
> >         return this.dataCenters;
> >     }
> > 
> >     public boolean isSetDataCenters() {
> >         return ((this.dataCenters!= null)&&(!this.dataCenters.isEmpty()));
> >     }
> > 
> >     public void unsetDataCenters() {
> >         this.dataCenters = null;
> >     }
> > 
> > }
> > 
> > Instead, we could use @XmlElementWrapper as described in [1]
> > to avoid generating "group" entities altogether.
> > 
> > [1] https://github.com/dmak/jaxb-xew-plugin
> > 
> > The fact that Java SDK provides decorator for each specific
> > resource collection (like DataCenters), instead of having ONE
> > resource collection type, greatly complicates overall design
> > and code-gen aspect.
> > 
> > In oVirtJS GWT wrapper, we'll avoid above complication through
> > single resource collection type (having common methods like
> > get(id), list() etc) for all resources.
> > 
> > Regards,
> > Vojtech
> > _______________________________________________
> > Devel mailing list
> > Devel at ovirt.org <mailto:Devel at ovirt.org>
> > http://lists.ovirt.org/mailman/listinfo/devel
> > 
> > 
> 
> 
> --
> Dirección Comercial: C/Jose Bardasano Baos, 9, Edif. Gorbea 3, planta
> 3ºD, 28016 Madrid, Spain
> Inscrita en el Reg. Mercantil de Madrid – C.I.F. B82657941 - Red Hat S.L.
> 



More information about the Devel mailing list