[jboss-as7-dev] Detyped API document feedback
Brian Stansberry
brian.stansberry at redhat.com
Tue Jan 4 17:15:22 EST 2011
On 1/4/11 11:02 AM, David M. Lloyd wrote:
> This commentary is in reference to version 2 of the detyped API document
> at: http://community.jboss.org/wiki/AS7DetypedManagementAPI/version/2
>
<snip/>
>
> ========
>
> MetaValues
>
> I agree with some of these types but not others:
>
> * SimpleValue
> + String - yes
> + primitives - some; maybe just boolean/int/long/float/double but
> not byte/short/char for example
OK. These will just clutter the API and bring little value.
> + Date - no, let's use long for now, and revisit once JSR-310 is
> done. Date is basically worthless.
+1
> + BigDecimal/BigInteger - yes
> * CollectionValue/ArrayValue - No, I'd rather see byte[] added to the
> above list and otherwise have a list value type, each element of which
> can be whatever type
Yeah; the current CollectionValue in jboss-meta requires all elements to
be of the same MetaType, which in practice makes the equivalent to
List<Object> or List<Number> impossible. That's annoying. And it kind of
works the opposite of generics -- it doesn't catch any errors at compile
time but will at runtime. So, agreed, a list of any type is better.
> * MapValue - No, we don't need any map key type other than strings
Agreed. I did a fair amount of work with the AS 5 detyped stuff and
can't recall using anything but a string as a key.
> * CompositeValue - too much work, why not just use a simple map of
> Strings to values? By making the type dependent on the key it's
> basically impossible to use without metatype info
The basic question is whether there's any value in shipping complex
metatype information along with a value. I'm starting to think there
really isn't, so I'm with you here. People either know the metatype or
we can provide a separate operation to let them find it.
> * TableMetaValue - too complex
Haha; that one was just in there temporarily to spark discussion in case
someone can *really* justify it. I agree, it needs to go.
>
> I'd rather do something more dynamic where you can start with a node and
> just build up whatever you want from it:
>
> node = new ModelNode();
> node.get("operation").set("change-bind-port"); // string
> node.get("address").add("base, "domain"); // a list
> node.get("address").add("profile", "web");
> node.get("address").add("subsystem", "web");
> node.get("address").add("connector", "ssl");
> node.get("bind-port").set(8433); // int
> result = connection.execute(node); // goes over remoting
> System.out.println("Result is: " + result);
> // nicely formatted, JSON-style (but with more possible types)
>
> I wipped up a demo of this style of API at:
> https://github.com/dmlloyd/jboss-dmr
>
> Notice there's only one public class and one type enum. (The Validation
> class isn't anything, just an experiment.)
>
> The main point to this API is that things like Map and List are
> *completely inadequate* by themselves to define a detyped API. The
> reason that languages like Perl, PHP, Python, Ruby, and JS are so good
> at this kind of thing is because they can take advantage of dynamic
> typing in a way that Java normally can't. So the best solution in my
> view is to layer a simple dynamic-type layer on top of the static types
> we're used to dealing with.
>
> ========
>
> MetaTypes
>
> I gotta be honest, I'm not liking this API. I don't see this as
> something users will consider to be a huge advantage over JMX. I know
> there are notes in here about improving user-friendliness but I do not
> believe this is something that can be added in later; it has to be built
> in from the ground up.
>
> If we want a real differentiator from JMX (i.e. a much lower barrier to
> entry), the first step is making requests easy to build.
>
> I'd consider it a logical progression to use the same dynamic
> representation given above to represent the actual model data. Instead
> of mirroring JMX with management entities combining operations and data,
> we should have a pure-data view of the model itself.
>
> The registry of operations should be external to the model itself; it
> would be a map with a key that corresponds to the operation name plus a
> "path" specification to the applicable node type.
Yes, that's the way it's meant to work.
There are 2 key differences in what I see you describing vs the client
side view of a ManagedResource described on the wiki article:
1) A ModelNode sent from the server to the client (e.g. via your "read"
operation below) would not include any complex metainformation -- no
equivalent to MBeanAttributeInfo, MBeanOperationInfo, etc. Instead, a
user interested in that kind of metainformation would execute a
different operation to get it.
I think that's good.
2) There's no distinction between an "attribute" and another entity
that's in a parent-child relationship. What that means in practical
terms is the "read" operation you describe executed with address
"base=domain" would pull down the whole model, with no simple way to
just pull down the attributes of the parent and not the
separately-addressable children.
Thinking about it though, that's probably ok. People are almost always
going to want to read a single attribute or a whole subtree.
> Some operations (like
> "read") would be generic and would apply to any node path, where some
> (like the example above) would be highly specific.
>
We'll have to have rules for this such that there is no ambiguity about
what operation is meant (i.e. there can't be a "read" operation
associated with some subsystem address.) I think that means a limited
set of operations like "read" that are global to all addresses and whose
names are reserved. Everything else is like your example above.
> Querying a model element amounts to copying a chunk of this data
> verbatim, which is why more generic operations like "read" can work.
>
> This means that we don't need to replicate common operations. To look
> at it from a JMX perspective, we can dynamically build the mbean
> operation sets off of all the operations which can apply to the given
> model node. Thus every mbean could automatically get a "read" method
> which can yield the model data.
>
Yep. That's nice.
> This is also important because the whole set of all operable entities
> encapsulates more than the model in even the simplest scenarios. Thus
> operations have to be able to reach outside of the model to do things
> like query runtime state and so on.
>
Sure. The set of operations was always meant to be separate from the
model data. Really the only tie is the addressing scheme -- for *some*
operations there needs to be a consistent way to walk the data tree to
get the data associated with a particular address. For other operations,
the model data might not be needed at all.
> Of course this bypasses the other half of the problem which is
> describing the model and available the operations. But, by having a
> special value type for representing a value type,
Do you mean "a special value for representing a value type"? What you
describe below looks like an ordinary value with a well-known structure.
> this kind of dynamic
> representation can be fully self-describing:
>
> {
> "operation-name" => "change-bind-port",
> "address" => [
> ("base"=>"domain"),
> ("profile"=>"*"),
> ("subsystem"=>"web"),
> ("connector"=>"*"),
> ],
> "request-properties" => {
> "bind-port" => {
> type => INTEGER,
> required => true,
> min-value => 0,
> max-value => 65535,
> }
> },
> "reply-properties" => {}
> }
>
> Thus we can have an operation whose purpose is itself to describe
> operations. This also enables our domain controller to automatically
> remap server- and host-level operations to the domain level by adding
> address discrimination without having to replicate the code for these
> operations.
>
> This means we can perform validation generically, if we want - even on
> the client side, optionally. This should help reduce the "bogeyman
> effect" that may be associated with dynamic type systems.
>
> ========
>
> In conclusion - I think if you look at the primary use case for this
> API, the thing it will be used for more than anything else is going to
> be custom scripting and special-purpose client programming. A dynamic
> model is perfect for this use case because it has the absolute minimum
> barrier of entry possible for a detyped API. Users already know what is
> valid, they just want to put in the properties and run it.
>
--
Brian Stansberry
Principal Software Engineer
JBoss by Red Hat
More information about the jboss-as7-dev
mailing list