[jboss-as7-dev] Detyped and REST configuration API
Brian Stansberry
brian.stansberry at redhat.com
Tue Nov 30 12:24:17 EST 2010
Continuing my reply from last night...
On 11/29/10 10:18 PM, David M. Lloyd wrote:
<snip/> of part already replied to...
>
>> 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.
>
> For updates at least, there is a logical "place" for it: whatever
> registers the ability to handle a specific kind of update could also be
> required to specify the exact description for the operation (which could
> possibly even be used for validation purposes, though past experience
> demonstrates that it is unlikely that we'd be able to provide a truly
> comprehensive description language for validation). In my earlier vein,
> non-CRUD updates could easily contain info about whether it requires an
> update. CRUD is trickier. I'm not sure we can say, "changing this
> field requires a restart", especially if a field cannot be independently
> changed without changes to an adjacent related field. And we can't
> really say "changing _any_ field on this element requires a restart",
> because that's just lame if only one field really does require a restart
> when changed.
>
This basically means much of the metadata is duplicated -- it's in the
xsd, and in whatever code provides it as part of this registration
process. I think that's the way to go though; the detyped API really
needs to make this information available to clients (i.e. no forcing
them to interpret xsd), plus a lot of the information (e.g. metrics and
management operations) isn't rightly part of the xsd.
If we're slick we can generate our xsd from whatever Java code registers
this description to the runtime. I believe Infinispan has done that. I
believe they use annotations though; if we did something similar we'd
need to be sure we had a fast mechanism for a subsystem to register this
information with the runtime.
> For model elements, I think there's two parts to this.
>
> The first part is a sort of implicit contract for common fields. For
> example, if we have a common field called "name", we should always treat
> that field similarly regardless of where it appears as a matter of
> convention. In this way, if there is no description available for a
> given model element and all you have is its data, then you can still do
> something reasonably intelligent with the field contents.
>
I agree with the gist of what you are saying, but who is "we" here? "We"
as writers of consoles and CLIs that consume this API?
Ok, I gotcha, we as model designers need to make sure a "name" has
consistent semantics in all parts of the model (e.g. is an immutable key.)
> Secondly, we're really dealing with two "kinds" of model elements. The
> first "kind" is a model element which is inherent in the core structure
> of the model, be it host, domain, or server. The model description for
> these things should also be inherent in the bootstrap code somehow, i.e.
> not dynamic.
>
> The second "kind" is subsystem configuration. It would be reasonable to
> require the model description to be registered at the time the subsystem
> is initialized.
>
We need that to be fast and lightweight though. E.g. no scanning of
subsystem classes for @ManagedProperty. :-)
>> 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:
>
> I see your addressable model element and raise you... to the base class.
> All elements should be addressable.
>
> Take the next logical step though: what reason is there to even have a
> typed model element class? The only thing you'd ever use it for is
> getting a detyped representation of it. So why have so much duplication
> of code and data spread all over the place. You could represent each
> model in a single class of logic plus a detyped element data blob just
> as effectively, and save the headache of conversion when someone
> requests a hunk of it.
>
Assuming the underlying model data were all contained in a detyped data
structure, the model element classes would really be doing two things:
1) Type conversion for readers.
2) Encapsulation; controlling write access to the detyped data structure.
The former is pretty minor. The latter is pretty important.
We could put all that logic in a single model class (plus one per
subsystem, since the core model is clueless about subsystems) but that
will be one monster class.
Ok, concerns duly noted, now I'll think harder about what you are
saying. :-)
What would this single class do (in the case of writes)? It gets some
detyped representation of the write, which would include:
1) the address being updated
2) some identifier of the operation being performed
3) detyped representation of the parameters
So the model class finds the registered handler for the
address+operation and passes it the affected DetypedModelElement and the
parameters?
>> 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.
>
> Make it all go away. I think the detyped system should be the core of
> our model representation and update handling. Let's keep the *concepts*
> we've established, but save ourselves the torture of trying to port the
> actual code of the Old Way on to the New Way like we've done multiple
> times in the past with sweeping update changes.
>
>> 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.
>
> Again by using a single class of logic plus a detyped blob for each
> model, we make the [un]marshalling problem a lot simpler. Also let me
> make sure that my stance on replacing chunks of the model is clear: I'm
> against. Too much hidden complexity.
>
--
Brian Stansberry
Principal Software Engineer
JBoss by Red Hat
More information about the jboss-as7-dev
mailing list