POC: Operation scheduling over the REST api

Heiko W.Rupp hrupp at redhat.com
Thu Dec 1 17:27:42 UTC 2011


Hi Alan,

thanks for going over this and giving feedback.

> My first question is if there's a specific use case in mind defining the return content or if you're simply exposing existing functionality/domain models. 

I have two things in mind currently - this operations POC is the 2nd item on the list

1) expose data that we have in the server in a (programming) language independent way so that people that do not speak
java can still use the data in their favorite language to e.g. create über-dashboards that display metrics in the way they
want. Or easily obtain availability of resources and so on. 
Many admins speak scripting languages fluently, but not Java. The D3 examples show ways to interpret the existing data
with the help of JavaScript in order to explore new ways of displaying. I think RHQ needs to allow this freedom, as we
can never know in advance what the user will want. I've also talked about that last monday at the London JBUG and the
general opinion was that this freedom is needed.

2) Try to model a workflow to things we have like scheduling an operation or defining an alert definition or ... in a generic
way that follows the HATEOAS principle of REST. Meaning that the individual REST-resource defines the next possible 
steps by the links it exposes.
I have written a generic tool in Ruby that makes use of this and which does not know about the specific REST-resources; of course
a client needs to know the meaning of the fields, But in general this allows to create generic wizards in languages like
Ruby, Python etc. and the exchange of data with other tools. I think Dave Webster wrote earlier in this mailing list, that this is
what they are already trying to achieve[1].

> If the latter, it didn't work out too well for what I was trying to do and I had to build my own facades before this was efficiently usable. 

This is very possible. I did want to show what I have done so far in order to collect feedback on what can be improved.
It is also obvious that doing all this via curl calls is tedious, but it shows what is sent and received in a relatively direct manner.

> 
> Some questions below. 
> 
>> # Getting the platforms
>> $ curl --user rhqadmin:rhqadmin http://localhost:7080/rest/1/resource/platforms -HContent-Type:application/json
>> [{"typeName":"Mac OS X",
> 
> Why does the return content differ from that below? 

I omitted the links to make it more clear what is sent, but obviously missed the point and made it more obscure this way.

> 
> 
>> # Getting one resource
>> $ curl --user rhqadmin:rhqadmin http://localhost:7080/rest/1/resource/10001 -HContent-Type:application/json
>> {"typeName":"Mac OS X",
>> "resourceName":"snert",
>> "parentId":0,
>> "pluginName":"Platforms",
>> "resourceId":"10001",
>> "links":[
>>   {"rel":"operationDefinitions",
>>    "href":"http://localhost:7080/rest/1/operation/definitions?resourceId=10001"},
>>  {"rel":"self",
>>    "href":"http://localhost:7080/rest/1/resource/10001"},
>>  {"rel":"schedules",
>>    "href":"http://localhost:7080/rest/1/resource/10001/schedules"},
>>  {"rel":"children",
>>    "href":"http://localhost:7080/rest/1/resource/10001/children"}
>> ],
>> "typeId":10020}
> 
> I assume the 'links' construct is a vestige from xhtml/xml/html?  It's awkward accessing this via javascript - this isn't just a stylistic concern.

Well, the links follow the AtomPub format (at least their XML representation)[2]. AtomPub defines that a link has <link rel="x" href="x"> and
is a pretty common standard for links in resources. But yes, the AtomPub protocol seems to take them from html.

> 
> 
> for (var i = 0; i < this.links.length) {
> if (this.links[i]['rel'] == 'children')
> 

I see the issue here.

> I found something like this much more accessible.  
> 
> {
[..]
> 
> children: [ 'http://foo/N', 'http://foo/N+1', … ]
> operations: "http://localhost:7080/rest/1/operation/definitions?resourceId=10001"
> }

Still you can not assume in a more generic way that a key 'children' or 'operations' is there.
The check is still needed.

With the current setup you can do 

for (int i = 0 ; < links.length ; i++ ) {
 var btn =  ' <a class='button' href="' + links[i].href + '">' + rel + '</a>';
 display(btn);
}
to render the options the user has in a way that is not dependent on the rest-resource

But I have been trying to do what you suggest and this currently fails in RESTeasy, as for a Java-ResourceWithType
that has a List<Link> embedded, RE is basically taking the RWT object and throws it at JAXB which serializes
it into XML. The user/developer has no way to influence how the embedded java types are rendered.
It may be possible to hack the JacksonProvider in some way to get it that way.

> If you're querying a resource it seems reasonable that just the immediate children be made available (vs. the entire tree). Also - it seems likely you'll be accessing one of them next so putting the immediate children in cache is beneficial to affinity.

Yes. Server-side caching is hard to get right with our Security setup (not impossible)

> So overall, the 1st level (/platforms) contains very little information. I didn't find it terribly useful as is - not enough information to do anything other than more queries;

Platforms give you a single entry point into the system (for the resources, there also exist such for groups and alerts and so on). This follows the
principle of the discoverability in REST. As I said above, I omitted the links in my mail, which obviously was a mistake.


> the 2nd level (/resource/N) contains more but was cumbersome to work with javascript.   What I found really missing was a detailed get - a single query that pulled a resource + resource operations + resource alerts (plus other information when that's implemented). I assume that would be a pretty common use-case and without it someone needs to make several trips to the server to display a single resource. 

If this is a use case that people want, I am all for implementing it, as more coarse grained (and thus less frequent) access is better for performance
and scalability. Also here we need to be careful to e.g. only include operation definitions and alert definitions, as these are much more stable and can
thus be much better cached by the client. Individual alerts or operation histories should not be in that object as 

> I wasn't able to spend more time looking at anything else but did find it nicely accessible; simple to get started with.  It looks like a good start. I'll try to keep up with the updates in your branch.

Thanks. I meanwhile updated the code to also display the operations history and to make it possible to 
pass (simple) parameters to operations.
I've also updated the d3 examples to match the latest REST code.
I will showcase the Ruby tool soon. 

Thanks again for your feedback

  Heiko


[1] https://fedorahosted.org/pipermail/rhq-devel/2011-September/001226.html
[2] http://bitworking.org/projects/atom/rfc5023.html#listing-collections

  



More information about the rhq-devel mailing list