Coming Up for Air

GlassFish REST Interface, a Client-side Perspective

As I’ve covered here before, GlassFish sports (and has for a while now), a pretty comprehensive set of management and monitoring REST endpoints. While this goes a long way toward opening up GlassFish management to various scripting solutions, the client side is still pretty manual. One my goals in GlassFish 4.0 is to fix that. In this article, I’m going to give you a sneak peak into what we on the REST team have planned for the GlassFish RESTful administration interface.

So, What’s New?

Currently, interacting with the REST interface means JSON or XML. Lots and lots of it. We do ship some utility methods to help with that (though I won’t discuss them here, as they’re not technically public APIs at this point) and I’ve heard of GlassFish users doing the same. What would be nice, though, is to avoid that as much as possible. What we plan to deliver, then, is a set of Java classes that wrap all the complexities of JSON/XML, the Jersey client, etc. We can generate these stubs (see note below) by using this command:

1
asadmin generate-rest-client --outputdir client/

Currently, this will create 3 files in the directory client/: pom.xml, rest-client-4.0.jar, and rest-client-sources-4.0.jar. Internally, this command analyzes all of the ConfigBeans and AdminCommands deployed to GlassFish, creates the source files for the clients, compiles it, and returns the binary and source jars for the client, as well as a POM file that developers can use to install the jars into a local Maven repository.

Note: All of this code is still pretty new, so file names, etc. may change. I’m still not happy with the CLI command name or the name of the resulting artifacts, for example.

Great! How do I use it?

For those familiar with GlassFish internals, these classes largely mimic the public interfaces of the `ConfigBean`s they represent. There are additional methods exposed to make available the CLI commands that GlassFish exposes via REST. With that out of the way, perhaps the best way to explain how to use the library is to show a couple of examples. We’ll start with a simple example, creating a JDBC connection pool:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
RestClient restClient = new RestClient("localhost", 4848, false /* use ssl? */);
Domain domain = new Domain(restClient);
final Resources resources = domain.getResources();
JdbcConnectionPool cp = resources.getJdbcConnectionPool("TestPool");
if (cp != null) {
    // The get method will return null if the requested resource does not exist
    cp.delete();
}

RestResponse rr = resources.createJdbcConnectionPool("TestPool", new HashMap<String, Object>() {{
    put("restype", "javax.sql.XADataSource");
    put("datasourceclassname", "org.apache.derby.jdbc.ClientDataSource");
    put("property",
        "portNumber=1527:password=APP:user=APP:serverName=localhost:databaseName=sun-appserv-samples");
}});

if (rr.isSuccess()) {
    System.out.println("Successfully created connection pool.");
} else {
    System.out.println("There was an error while creating the connection pool:  " +
            rr.getMessage());
}

This simple example does several things. First, we create the base RestClient. We tell the constructor that our server is on localhost, listens on port 4848, and does not use SSL. Next, we create a Domain object, which is, of course, the root node for all configuration data in the GlassFish server. From here, we have methods exposed that allow the client code to walk down the REST tree you’ve come to expect if you’ve used the REST interface before.

With a reference to the Resources, we have access to the createJdbcConnectionPool method. One thing to note about CLI command wrapper methods, is that all required parameters are explicitly listed, by name and type, in the method signature. All optional parameters are passed in a Map<String, Object>, as shown above.

Calls to CLI endpoint methods return a RestResponse object, which wraps all of the complexities of the REST response payload. In fact, you don’t even need to care if you’re using JSON or XML (<whisper>It’s currently using JSON ; )</whisper>). There are several methods on this class, but all we care about here is whether or not we’ve succeeded (.isSuccess()), and what message was returned if there was a failure (.getMessage()).

That’s fun, but let’s try something a bit more hard core: Let’s deploy an application. I hate to disappoint, but it’s not all that exciting:

1
2
3
RestClient restClient = new RestClient("localhost", 4848, false /* use ssl? */);
Domain domain = new Domain(restClient);
RestResponse rr = domain.getApplications().deploy(new File("test.war"));

And that’s it. You can now access your application as expected. Need to undeploy the application?

1
2
3
4
Application app = domain.getApplications().getApplication("test");
if (app != null) {
    app.delete();
}

Whew! That’s hard! : )

But, wait! That’s not all!

One of the goals of the REST interface is to allow non-Java clients to interact with the GlassFish administration layer. These classes, then, clearly don’t help much with that, but I have a glimmer of hope for all of you Pythonistas and Rubyists out there. My hope, once I have a good handle on the Java client interface, is to extends the CLI command to generate Python and Ruby bindings. Apart from learning Ruby, I think it should be a fairly simple task. There might even be hope for PHP users in the offing as well. GlassFish is, of course, open source, so if your language isn’t supported, you know how to fix that. ; )

Final Word

All of this code, is, as I’ve mentioned, very new. Names, interfaces, etc may very well change, and you can actually make that happen. If you have a vested interest in this new feature, we could use your feedback. Filing issues in JIRA is the best way to do that. Comments here, while are, might get lost in the shuffle. :)

tags: GlassFish REST

Quotes

Sample quote

Quote source