This patch is a first attempt at a CIMI model layer. Such a layer is needed to deal with deserialization (and possibly serialization) of CIMI model objects from (to) XML/JSON, and to give us a place to stash business logic connected to model classes.
This patch is solely for discussion, it most definitely will not work; at a minimum there are various 'require' that are missing. There's two things that make such a model layer interesting: * The need to deal with differences between the JSON and XML representation; I believe they are all mechanical, though the CIMI draft does not set out any explicit rules. The main rule is that an array of things in JSON is represented as { 'things': [ .. array .. ] } whereas the XML uses a sequence of <thing/> elements * The desire to keep the metadata that has to be written for each model class minimal Since we need to capture some of the metadata in the model classes anyway (at a bare minimum we need to know which attributes are arrays, so that we can handle JSON and XML differently), I think it will also be possible to do serializiation of model classes programmatically, rather than through templates. The intended use of the model classes is something like (of course, in reality, this code will be scattered through various places like server.rb and the drivers) templ = nil if input_is_xml(input) templ = MachineTemplate.from_xml(input) else templ = MachineTemplate.from_json(input) end machine = Machine.new machine.name = templ.name machine.volumes = templ.volumes.dup templ.volume_templates.each do |vt| machine.volumes << setup_volume_from_template(vt) end # Do more stuff with templ, adding to machine respond_to do |fmt| fmt.xml { machine.to_xml } fmt.json { machine.to_json } end Besides getting the code to actually be syntactically correct, there are a few more additions that seem useful: * make sure we strip out unneeded arrays from XmlSimple (i.e., some scalars are returned as '[ v ]', but we should only use 'v' * add a way to the DSL to indicate whether an attribute is mandatory or optional, i.e. something like ref :uri, :mandatory => true With that, we could do some rudimentary validation on model objects * see if we can really have a Base.to_xml; the two big issues to settle are (1) indicate which attributes go into XML attributes and which ones go into elements, e.g. ref :foo, :xml_attr => true (2) for attributes that are not scalars, do (1) recursively; in particular, allow associating a class with the members of an array array :things, :class => Thing where Thing itself is a subclass of Base * some type specific validation (a 'ref' should look like a URI, we could add types to 'scalar' and make sure integers look like integers etc.) * a unit test or two Another sidenote: since the CIMI API isn't terribly HTML friendly (e.g., POST's all have XML or JSON bodies), I wonder if the HTML frontend shouldn't be a JS app that communicates with the server via JSON only. David