[jboss-as7-dev] Detyped and REST configuration API
Brian Stansberry
brian.stansberry at redhat.com
Mon Nov 29 18:15:36 EST 2010
Apologies in advance for the long message. I want to kick off a
discussion of the detyped and REST API for domain/host/server
configuration. Much of the following will end up in a wiki, but I wanted
some initial discussion first.
Goals:
A "detyped" Java version of the configuration API. Detyped in the sense
that the entire model can be represented using a few general usage
classes on the client classpath,
a la the jboss-meta project used in AS 5/6.
A REST version of the API. Even less strongly typed, since in the end
clients will fundamentally be consuming the model as text (xml or json).
Concepts:
"Addressable" Model Elements
An "addressable" model element is one that can be uniquely identified
within it's overall model.
It either:
** is the only element of its type under its parent element (i.e.
maxOccurs=1 in its schema)
** or has a single attribute whose value is unique among all elements of
its type under it's parent element
and it is either
** the child of an addressable model element
** or is the root element of the model
An addressable model element can easily be treated as a resource in a
REST interface. A particular element can be represented in a URL path
either via its element name or via a simple combination of its element
name and the single attribute value.
It's also easy to create a simple java object to represent the element's
address for use in the "detyped" Java API. For a draft see:
https://github.com/bstansberry/jboss-as/commit/36763f82e6d82631370adcc154193d02ddf4829c#diff-5
https://github.com/bstansberry/jboss-as/commit/36763f82e6d82631370adcc154193d02ddf4829c#diff-3
We should strive to have the vast majority of elements in the
domain/host/server models be addressable. This makes it easy to have
highly targeted updates; e.g. a REST PUT can specify the values for a
few attributes in a single element rather than needing to describe a
large portion of the model. So far we have largely met this goal.
Updates via differencing:
A model update consists of a client sending a detyped representation of
a part of the model. The update will include all of that portion of the
model; both modified and unmodified properties. The server compares that
detyped representation to the current state of the model and generates
the AbstractModelUpdate objects needed to bring the model up to the
desired state.
See the DetypedModelElement class for a draft detyped representation of
an addressable model element:
https://github.com/bstansberry/jboss-as/commit/36763f82e6d82631370adcc154193d02ddf4829c#diff-2
At this point I used the CompositeValue class from AS 5/6 jboss-meta
library for representing the element's properties. That's certainly open
for discussion.
"Id-Only" Elements
The detyped representation of a part or all of the model can include
"id-only" elements. These represent addressable elements but only
include the information necessary to determine the element address, plus
a flag indicating the element is "id-only". These serve as placeholders
within a representation of a larger portion of the model. The purpose of
an id-only element is to allow the client to avoid dealing with
uninteresting portions of the model state, while still being aware of
their existence. They also allow the server to distinguish an update
that removes an element from one that doesn't modify it at all, without
forcing the client to send the entire state of the unmodified element.
How useful this "id-only" concept will be, I'm not sure. The main use
cases I can see are, for reads, being able to read a client-specified
number of levels of the model without having to consume the whole thing
(imagine a huge domain). For writes the main use case would be an update
that touches a few parts of the model (e.g. add an extension, the
subsystem config for it, a new thread pool for it, a new socket binding
for it) without having to specify all the unrelated stuff in between.
Issues:
Meta-information about Configuration Elements:
Where should this be stored? Basic things like the primitive types of
various properties, plus more complex things like whether changing a
property requires a restart to take effect. The "detyped" Java version
can include a fair amount of meta-information, but this isn't readily
available via REST. Much of this information also can be (and is) stored
in the domain model schemas themselves, but this forces clients to
access and interpret the schemas to obtain the information. Putting
things like whether a property requires restart to take effect in the
various domain model schemas would also create a tighter coupling
between the schemas; i.e. they should all use the same mechanism to
indicate this, which would imply some common included schema that
defines that mechanism.
Obtaining a DetypedModelElement
This seems fairly straightforward. Any AbstractModelElement that is
addressable should be able to expose its state as a DetypedModelElement.
See AbstractAddressableModelElement for an rough implementation of that:
https://github.com/bstansberry/jboss-as/commit/36763f82e6d82631370adcc154193d02ddf4829c#diff-1
Determining differences and generating AbstractModelUpdate objects
If the client passes back a DetypedModelElement to the domain
controller, we need logic to determine the difference between that
detyped representation and the current model and then generate the
needed update objects. A possibility is to have each
AbstractAddressableModelElement be responsible for doing that. A problem
I've seen with that is the class hierarchy for the update classes versus
the model element classes is not clean.
For example, a method like this in AbstractAddressableModelElement won't
work:
protected abstract void addUpdatesToMatchView(DetypedModelElement
updatedView, List<AbstractModelElementUpdate<?>> updates);
It won't work because not all model elements are updated via
AbstractModelElementUpdate; some are done via AbstractDomainModelUpdate,
some via AbstractHostModelUpdate etc.
Marshalling to from XML/JSON
The REST API requires the ability to marshall to/from whatever XML and
JSON formats we use for exchanging data with clients. JSON of course is
going to be different from anything we have right now. We need to think
about the XML format. We could just provide and receive snippets that
follow the same schema we use in the domain/host/standalone.xml
documents themselves. However, there are problems with that. The
"id-only" notion described above is not part of those schemas. Any Atom
links we include in response documents (see Chapter 9 in Bill Burke's
RESTful Java book) will violate the schema as well. As will any metadata
we decide to include. We may be better off with a more generic
representation that more directly maps to something like
DetypedModelElement.
Any and all comments on this are appreciated.
--
Brian Stansberry
Principal Software Engineer
JBoss by Red Hat
More information about the jboss-as7-dev
mailing list