[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