[jboss-as7-dev] Detyped API document feedback
Jason Greene
jason.greene at redhat.com
Tue Jan 4 21:40:46 EST 2011
Comments inline.
On Jan 4, 2011, at 4:16 PM, Brian Stansberry <brian.stansberry at redhat.com> wrote:
> 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.
Same experience here. Custom key types are useless. Primitive key types could be useful for performance reasons; however, I can't think of a management structure where it makes sense to use them.
>
>> * 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.
This kind of thing would add verbosity to the protocol. It should go since it has a simipler substitute.
>
>> * 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.
This is just a list of maps,
>
>>
>> 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
> _______________________________________________
> jboss-as7-dev mailing list
> jboss-as7-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/jboss-as7-dev
More information about the jboss-as7-dev
mailing list