GlassFish Server Open Source Edition 3.2 RESTful API 1.2. Name(s) and e-mail address of Document Author(s)/Supplier:
- Jason Lee: jdlee@java.net
- Ludovic Champenois: ludovic.champenois
- Mitesh Meswani: mm110999@java.net
1.3. Date of This Document: 4/7/2011 2. Project Summary This is still a work in progress, especially the technical information at the bottom, which is still being cleaned up based on the work done for 3.1 2.1. Project Description: The RESTful interface is the primary interface for not only third party developers, but the Admin Console as well. The primary goal of this effort, then, will be support for 3.2's primary feature, which is Platform as a Service (PaaS) support. Additionally, changes will be made to better support the various GlassFish backend modules (in terms of REST support for ConfigBeans and AdminCommands), as well as REST client support (improved client libraries, cleaned up resource tree, etc). 2.2. Risks and Assumptions: Currently, REST support is fairly reactionary, meaning the REST team must wait until the backend teams finish their commands (or until the console team asks for support) before they can be mapped into the REST resource tree. In the previous release, this tended to push such support later in the development cycle. With the addition of the annotation-driven mapping approach described below, though, it is hoped that this will not be the case in this release. It should also be noted that the three resources assigned to the REST module are also splitting their time with other efforts, so there is the very real possibility that some goals, especially on the client side, may have to be postponed. 3. Problem Summary 3.1. Problem Area: As alluded to above, REST mapping is very manual in some areas. While ConfigBean instances are automatically picked an added to the tree, most {{AdminCommand}}s are not. While we do have basic annotation support for adding commands to the tree, this support is not complete, nor is it used consistently across the system. As things stand now, the annotations we offer module developers are not sufficient to achieve everything we currently do through manual mapping via hardcoded List-/Map-based data structures. On the client side, users have two choices: manipulate XML or JSON. While it is manageable (the Admin Console wrote an abstraction layer, for example), it's non-optimal, and can be non-trivial. 3.2. Justification: PaaS support is non-negotiable. Given the Admin Console's dependence on the REST interface (as of GlassFish 3.1), it must expose all of the functionality needed by the console (and any other related applications) for managing and monitoring these new PaaS features. The move from a hardcoded data structure mapping to a purely annotation-driven approach is essential to long-term maintainability of the interface, as well as reduced turn-around times in getting new ConfigBeans/AdminCommands properly exposed via REST. In 3.1, this was treated mostly as an extra add-on. However, for the REST interface to be successful and maintainable, REST support must be treated as the part of the admin infrastructure it is. A part of this effort will result in formal documentation of the requirements of ConfigBean and CLI authors. Improved client-side support, specifically improved XML support, such as XSDs and/or schemas, has been requested by at least one major customer. While not a show stopper for release, the overall appeal of the product will be enhanced if the third party integration story is improved. 4. Technical Description: 4.0. Details: 4.0.1 PaaS support Since one of the major features of 3.2 is PaaS support, the REST API must fully support the new commands and ConfigBean instances added to the server to implement the platform as a service offering. 4.0.2 Annotation-based configuration Currently, CLI commands are mapped manually, via one of 5 data structures. This data will be moved from these data structures, which are maintained by the REST team, to annotations, which will be managed by the ConfigBean/CLI authors. The primary means of doing so will be via the CRUD infrastructure introduced in GlassFish v3. Take, for example, this snippet from the Clusters and Cluster ConfigBean instances:
@Configured
public interface Clusters extends ConfigBeanProxy, Injectable {
/**
* Return the list of clusters currently configured
*
* @return list of {@link Cluster }
*/
@Element
@Create(value="create-cluster", decorator=Cluster.Decorator.class, i18n=@I18n("create.cluster.command"))
@Delete(value="delete-cluster", resolver= TypeAndNameResolver.class, decorator=Cluster.DeleteDecorator.class
, i18n=@I18n("delete.cluster.command"))
public List<Cluster> getCluster();
// ..
}
When this class is processed, REST endpoints will be created for clusters/ and cluster/. For the latter, methods will be added to the generated ClusterResource class for adding and deleting (POST AND DELETE, respectively) Cluster objects. While this covers all the uses of the CRUD framework in the system, many CLI commands pre-date this feature, so support must added/expanded to cover these cases. To that end, basic support already exists in the system via the @RestRedirect annotation. This annotation instructs the system to redirect REST requests for the configured HTTP verb to the specified CLI command. For example,
@Configured
@RestRedirects({
@RestRedirect(opType = RestRedirect.OpType.POST, commandName = "create-admin-object"),
@RestRedirect(opType = RestRedirect.OpType.DELETE, commandName = "delete-admin-object")
})
public interface AdminObjectResource extends ConfigBeanProxy, Injectable, BindableResource, Resource,
//..
}
In this example, a POST to http://_server_:_port_/management/domain/.../admin-object-resource will result in a call to create-admin-object. Likewise, a DELETE sent to http://_server_:_port_/management/domain/.../admin-object-resource/resourceName will result in a call to delete-admin-object. These annotations, then, can be applied to ConfigBean instances to tie them to their related CLI commands. That doesn't cover all of the use cases, though. There are numerous examples in the system where a CLI command needs to be exposed via REST at some arbitrary point in the tree. Rather than putting all of these commands at the root of the resource tree, it is very much preferred to map these commands as closely to the ConfigBeans they manipulate as possible. While the exact positioning will be left largely up to the developer, the REST module must provide a means to specify such data. One possible solution is to alter the aforementioned @RestRedirect annotation to allow such optional metadata:
@RestRedirects({
@RestRedirect(opType=OpType.POST, configBean="Cluster", path="/foo")
})
public class MyNewCommand implements AdminCommand {
//
}
In this example, MyNewCommand would be exposed as an endpoint with the path /foo, accessible via POST, as a child resource of a Cluster element (e.g, http://localhost:4848/management/domain/clusters/cluster/c1/foo). Overloading this annotation in such a manner may not be desirable, though. Another possible solution is a new annotation for this explicit purpose. For example:
@RestEndpoints({
@RestEndpoint(configBean=Cluster.class,
opType=OpType.POST,
description="A description of the command",
path="foo",
params={
@RestParam(name="target", value="$parent")
})
})
public class MyNewCommand implements AdminCommand {
//
}
The exact semantics and nomenclature will be determined and documented as part of this effort. 4.0.3 Expanded Client-side support Since we've had external requests for an improved client-side experience, for GlassFish 3.2 we will deliver, at the very least, an XML schema and/or DTD of the XML response payload. This will make the "deserialization" of the XML back into Java much simpler. A more ambitious goal will be to provide a set of Java classes, which will likely closely resemble the ConfigBeans themselves. These classes will, of course, support each of the properties exposed via REST, but will also expose the CLI mappings where appropriate. Given the dynamic nature of the server, this client library will face the same issues that the REST endpoints themselves face. To address, it is proposed the we employ a mechanism similar to the endpoint generation to create this client library at runtime based on the current set modules installed on the server. Developers then might run a command like this:
asadmin get-rest-client-library --outputdir=lib/
or
curl -o glassfish-rest-client-jar http://localhost:4848/management/restclient
This library could then be imported into the developer's project, giving the user a much cleaner, higher-level API to work with than HTTP connections and JSON. Currently, only Java support is planned, but other languages (such as Python or Ruby) would be nice to have, time-permitting. 4.1. Advanced Details: 4.1.1 Introduction to RESTFul HTTP API More sophisticated clients, such as Admin UI, may need fine grained access to configuration. To satisfy the need of such clients, this API will provide direct access to the whole configuration tree. All the backend config beans will be exposed as JAX-RS resources enabling access to their attributes and parent-child relationships. A RESTful web service is based on the following principles:
- Resources and representations. Instead of providing just one endpoint for a particular web service and having that endpoint perform various operations, you provide access to resources. A resource is a single piece of a web application that is made accessible to clients.
- Addressability and connectedness. Resources have their representations, but providing representations of resources would be useless if you could not address them. In REST, every resource must have at least one address, that is, one URI. To address the resource, you simply specify the URI. This concept is called "addressability". By publishing a web application, you introduce many different URIs that are connected to each other. Because of that connectedness, the only URI you need to give to your clients is one URI called the "bootstrap URI".
- Uniform interface. Even if you make resources available through URIs and representations to exchange between the client and server, it still does not allow you to establish communication. You need a communication protocol/interface to use. In a REST architecture, such an interface must be uniform. It means that whatever URI you access, the interface should be the same. For instance, on the World Wide Web no matter what URI (resource address) you enter, your web browser simply uses an HTTP GET method to retrieve a corresponding web page (resource representation) and displays it.
- Statelessness. Statelessness means that a web application is not responsible for keeping any information about the state of its clients. REST does not encompass the concept of HTTP sessions. The client is responsible for tracking its own actions (if it needs to). The service maintains its resources and provides a uniform interface to the clients.
REST operates by leveraging the HTTP verbs specified in the W3C specification, two of which are likely familiar to web developers: GET and POST. Some others verbs used by REST are PUT, PATCH, DELETE, and OPTIONS. GET is usually used for read-only operations, and POST is usually reserved for create operations. The DELETE verb is used to delete a resource, and OPTIONS can be used to interrogate a resource for supported methods, attributes, etc. Updates are a bit trickier, as there two verbs dedicated to this function, PUT and PATCH. While a complete discussion of the beyond the scope of this document, their use can summarized as follows: PUT should be used for updating an entire entity (i.e., the entity is replaced by the one submitted from the client) and PATCH should be used to update a subset of an entity. Discussions on how to handle these verbs is still ongoing. The RESTFul architecture applies well to expose access to the generic @Configured ConfigBean layer described in HK2 (GlassfishV3Final_hk2_overview#section-GlassfishV3Final_hk2_overview-4.1.4ConfigurationSupport). HK2 Configured objects represent configuration that will be used by the server, it is usually stored in an xml file (like the domain.xml in GlassFish). Such configuration is described using interface definitions that are binding interfaces (like JAXB interfaces) using annotations in the Config module. An interface is annotated with the @Configured annotation, and XML attributes can be described using the @Attribute annotation while XML sub elements are defined with a @Element annotation. The @Element can return a single object or a List of objects. Example :
@Configured
public interface SomeConfig extends ConfigBeanProxy {
@Attribute
String getAttributeName();
@Element
SubConfig getSub();
}
GlassFish 3.x backend configuration is mostly described in the admin/config-api module (and for Grizzly configuration, in the Grizzly component). The root of all the ConfigBean instances is the Domain object that holds a reference to all the ConfigBean instances available in the system. This interface provides access to RESTFul resources that are mapped to the ConfigBean instances so that the content of these can be read, modified, created or deleted using the RESTful concepts. The Jersey implementation (https://jsr311.java.net/) which is available now in the Java EE 6 specification is used via a special Grizzly connector to avoid a dependency to the GlassFish Web container. Having minimal dependencies to GlassFish modules permits one, for example, to be able to manage via REST containers like the JRuby/Rails scripting container without our Web Server. The mapping is as follows: Each @Configured configuration will have a REST resource that exposes the list of @Attribute of this configuration (HTTP GET). Navigation rules using JAX-RS sub-paths will be available to navigate from one configuration resource to a child configuration resource or to a List of children. HTTP methods (POST, PUT – and possibly PATCH – and DELETE) on these resources will create, update or delete the corresponding ConfigBeans. An optional redirect to actual AdminCommand is possible to implement these POST, PUT/PATCH, DELETE methods to guarantee the behavior of the actions. DELETE is exposed only on specific resources. For example, the Domain resource should not have a DELETE operation for obvious reasons (catastrophic results will happen). The top level URL for accessing the entire resources is
http://machinename:adminport/management
For example, to get the list of Attributes and child Elements of the Domain ConfigBeans, the following URL will be used:
http://localhost:4848/management/domain
This is the main entry point to access to all the sub configurations. The output will always be as HTML by default (on Safari, Chrome, IE and Firefox). The HTML view has some convenient content to allow for navigation to child resources as well as Create, Update or Delete Forms when possible. One can also specify easily the type of the representation by adding the .xml or .json or .html extension. For example:
http://localhost:4848/management/domain.html
http://localhost:4848/management/domain.json
http://localhost:4848/management/domain.xml
will return the appropriate media representation of the resource. Of course, after this extension, one can add the optional parameters if needed. When the child Element is a List of other ConfigBean instances, a corresponding resource will be exposed for this collection. To select one element among n inside this Collection, one must specify the value of a Key attribute (the @Attribute annotation supports the definition of a Key). The value of the Key is passed as a sub-path What if the key contains the "/" char? For such resources, we have enabled a property on the Grizzly Adapter to allow encoding of special characters in the URL. For example, the collection of [[jdbc-resources}} can be accessed via:
http://localhost:4848/management/domain/resources/jdbc-resource
There are 2 jdbc-resource children, called jdbc/_TimerPool and jdbc/default that contain the "/" character in their name which is the unique key field to identify them. To access the jdbc/_TimerPool resource, you can use:
http://localhost:4848/management/domain/resources/jdbc-resource/jdbc%2F__TimerPool
It is also possible to add some child resources to a given ConfigBean REST resource, by attaching a GlassFish AdminCommand to it. For example the ConfigBean Domain is associated with the REST resource /management/domain and we can add the 3 CLI commands (uptime, stop, restart) to some corresponding child resource:
http://localhost:4848/management/domain/uptime
http://localhost:4848/management/domain/stop
http://localhost:4848/management/domain/restart
Our generator allows us to specify the type of HTTP method for each of these added commands. It is expected that for CLI commands that do not modify the backend (like for example the uptime command), a simple GET can return the result of the command. For CLI commands that modify the state of the backend (as stop or restart do), a POST is to be used to execute the command. The payload of these resources can be in XML, JSON, or APPLICATION_FORM_URLENCODED and should contain all the Command parameters necessary to execute this command on the server side. The returned document from these CLI resources is derived from the corresponding ActionReporter class of the CLI backend (see below for sample output). The combination of full access to the GlassFish ConfigBean instances and the CLIs that implement transactional, authoritative complex business logic on the admin backend will provide the necessary set of APIs for a comprehensive server management via HTTP(s) REST access. 4.1.2 Output Formats RESTFul configuration APIs will leverage existing support for XML, HTML and JSON representations. Additional representations can be plugged-in, if there is a requirement. For the supported representations, the output format will be as defined below. As you can see in the following examples, the Domain ConfigBean has locale, log-root, application-root and version as attributes. The Domain also has children resources: applications, resources, servers, configs and property. Navigating between parent-children resources is very natural using URL sub-paths. JSON format
{
"command": "command name",
"exit_code": "SUCCESS|WARNING|FAILURE",
"extraProperties": {
"commands": [command-metadata],
"methods": [method-metadata] ,
"entity": {attributes},
"childResources": {values}}
}
Where:
- command-metadata: one or more mapped CLI commands with the path, the command name, and the HTTP verb required to invoke the command
- method-metadata: one or more HTTP method with the list of messageParameters each describing the possible field name, default value, type, field key, and wether the field is optional or not.
- attributes: one or more Attribute value pairs separated by comma(,)
- values: a map of child names and URLs separated by comma(,).
Having the list of child resources is useful for auto-discovering on the client side the potential sub resources. This also could achieve via the WADL application.wadl file (see section 4.1.5 below), or calling each resource with the HTTP OPTIONS method that would return only the meta-data portion of the resource. Example of a complete resource, the Domain resource: http://localhost:4848/management/domain.json JSON Output:
{
"command": "Domain",
"exit_code": "SUCCESS",
"extraProperties": {
"commands": [
{
"path": "change-admin-password",
"command": "change-admin-password",
"method": "POST"
},
{
"path": "collect-log-files",
"command": "collect-log-files",
"method": "POST"
},
//...
],
"methods": [
{"name": "GET"},
{
"name": "POST",
"messageParameters": {
"applicationRoot": {
"optional": "true",
"type": "string",
"key": "false"
},
"locale": {
"optional": "true",
"type": "string",
"key": "false"
},
"logRoot": {
"optional": "true",
"type": "string",
"key": "false"
},
"version": {
"optional": "true",
"type": "string",
"key": "false"
}
}
}
],
"entity": {
"applicationRoot": "${com.sun.aas.instanceRoot}\/applications",
"locale": "EN_US",
"logRoot": "${com.sun.aas.instanceRoot}\/logs",
"version": "43"
},
"childResources": {
"applications": "http:\/\/localhost:4848\/management\/domain\/applications",
"clusters": "http:\/\/localhost:4848\/management\/domain\/clusters",
"configs": "http:\/\/localhost:4848\/management\/domain\/configs",
"jmx-urls": "http:\/\/localhost:4848\/management\/domain\/jmx-urls",
"lb-configs": "http:\/\/localhost:4848\/management\/domain\/lb-configs",
"load-balancers": "http:\/\/localhost:4848\/management\/domain\/load-balancers",
"node-agents": "http:\/\/localhost:4848\/management\/domain\/node-agents",
"nodes": "http:\/\/localhost:4848\/management\/domain\/nodes",
"property": "http:\/\/localhost:4848\/management\/domain\/property",
"resources": "http:\/\/localhost:4848\/management\/domain\/resources",
"secure-admin": "http:\/\/localhost:4848\/management\/domain\/secure-admin",
"servers": "http:\/\/localhost:4848\/management\/domain\/servers",
"set": "http:\/\/localhost:4848\/management\/domain\/set",
"system-applications": "http:\/\/localhost:4848\/management\/domain\/system-applications",
"system-properties": "http:\/\/localhost:4848\/management\/domain\/system-properties",
"system-property": "http:\/\/localhost:4848\/management\/domain\/system-property",
"view-log": "http:\/\/localhost:4848\/management\/domain\/view-log"
}
}
}
XML format
<map>
<entry key="extraProperties">
<map>
<entry key="methods">
<list>
<!-- method metadata
</list>
</entry>
<entry key="entity">
<!-- attributes -->
</entry>
<entry key="commands">
<!- command metadata -->
</entry>
<entry key="childResources">
<!-- child metadata
</entry>
</map>
</entry>
</map>
Each of the metadata entries is identical in intent to that of the JSON format. Since XML doesn't have a native means of expressing such constructs as lists and maps, semantically meaningful XML elements have been added to the document to help express such intent where needed. A concrete example should illustrate this more clearly. Example http://localhost:4848/management/domain.xml Output:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<map>
<entry key="extraProperties">
<map>
<entry key="methods">
<list>
<map>
<entry key="name" value="GET"/>
</map>
<map>
<entry key="name" value="POST"/>
<entry key="messageParameters">
<map>
<entry key="applicationRoot">
<map>
<entry key="optional" value="true"/>
<entry key="type" value="string"/>
<entry key="key" value="false"/>
</map>
</entry>
<entry key="locale">
<map>
<entry key="optional" value="true"/>
<entry key="type" value="string"/>
<entry key="key" value="false"/>
</map>
</entry>
<entry key="logRoot">
<map>
<entry key="optional" value="true"/>
<entry key="type" value="string"/>
<entry key="key" value="false"/>
</map>
</entry>
<entry key="version">
<map>
<entry key="optional" value="true"/>
<entry key="type" value="string"/>
<entry key="key" value="false"/>
</map>
</entry>
</map>
</entry>
</map>
</list>
</entry>
<entry key="entity">
<map>
<entry key="applicationRoot" value="${com.sun.aas.instanceRoot}/applications"/>
<entry key="locale" value="EN_US"/>
<entry key="logRoot" value="${com.sun.aas.instanceRoot}/logs"/>
<entry key="version" value="jasonlee-private"/>
</map>
</entry>
<entry key="commands">
<list>
<map>
<entry key="command" value="anonymous-user-enabled"/>
<entry key="path" value="__anonymous-user-enabled"/>
<entry key="method" value="GET"/>
</map>
<map>
<entry key="command" value="location"/>
<entry key="path" value="__locations"/>
<entry key="method" value="GET"/>
</map>
<!-- Entries edited for brevity -->
</list>
</entry>
<entry key="childResources">
<map>
<entry key="resources" value="http://localhost:4848/management/domain/resources"/>
<entry key="lb-configs" value="http://localhost:4848/management/domain/lb-configs"/>
<entry key="load-balancers" value="http://localhost:4848/management/domain/load-balancers"/>
<entry key="jmx-urls" value="http://localhost:4848/management/domain/jmx-urls"/>
<entry key="set" value="http://localhost:4848/management/domain/set"/>
<entry key="secure-admin" value="http://localhost:4848/management/domain/secure-admin"/>
<entry key="property" value="http://localhost:4848/management/domain/property"/>
<entry key="system-applications" value="http://localhost:4848/management/domain/system-applications"/>
<entry key="configs" value="http://localhost:4848/management/domain/configs"/>
<entry key="system-properties" value="http://localhost:4848/management/domain/system-properties"/>
<entry key="clusters" value="http://localhost:4848/management/domain/clusters"/>
<entry key="view-log" value="http://localhost:4848/management/domain/view-log"/>
<entry key="nodes" value="http://localhost:4848/management/domain/nodes"/>
<entry key="servers" value="http://localhost:4848/management/domain/servers"/>
<entry key="node-agents" value="http://localhost:4848/management/domain/node-agents"/>
<entry key="system-property" value="http://localhost:4848/management/domain/system-property"/>
<entry key="applications" value="http://localhost:4848/management/domain/applications"/>
</map>
</entry>
</map>
</entry>
<entry key="message"/>
<entry key="exit_code" value="SUCCESS"/>
<entry key="command" value="Domain"/>
</map>
A third format, HTML, is also supported. It's purpose, though, is to allow users to interact with the RESTful management API through a web browser, and is not intended to be use programmatically. It's layout, then, need not be covered here. A simple mention of its existence should be sufficient. 4.1.3 Log Viewer Resource The server.log of an instance is not managed by a ConfigBean, and is not accessible via CLI, so we have created a specific set of REST resources for viewing its content. The first resource is accessible under
http://localhost:4848/management/domain/view-log
It returns in text the content of the log file (gzipped if the client supports it) until the end of the file. It also returns an HTTP header called X-Text-Append-Next which when defined contains the entire URL to call via GET to get the delta content of the log file from the last call. So if you use a client thread looping every 3 seconds and testing the value of the header called
you can get all the new log entries since the last 3 seconds. An optional start param
http://localhost:4848/management/domain/view-log?start=10000
allows to specify the characters number you want to skip from the start of the file. (If it is larger than the file size, 0 is assumed. Another REST resource returns in JSON or XML format (Only JSON as of today) a structured view of the log file (the same way AMX used to return the log content to the Admin Console). The resource is at
http://localhost:4848/management/domain/view-log/details
The JSON output is like:
{
"records": [{
"recordNumber":145,
"loggedDateTimeInMS":1277905336097,
"loggedLevel":"INFO",
"productName":"glassfish3.1",
"loggerName":"null",
"nameValuePairs":"_ThreadID=27;_ThreadName=Thread-1;",
"messageID":"",
"Message":"The Admin Console application is loaded."}
,
{
"recordNumber":144,
"loggedDateTimeInMS":1277905336097,
"loggedLevel":"INFO",
"productName":"glassfish3.1",
"loggerName":"null",
"nameValuePairs":"_ThreadID=27;_ThreadName=Thread-1;",
"messageID":"",
"Message":"Loading __admingui Application done is 8523 ms"}
,
{
"recordNumber":143,
"loggedDateTimeInMS":1277905336095,
"loggedLevel":"INFO",
"productName":"glassfish3.1",
"loggerName":"javax.enterprise.system.container.web.com.sun.enterprise.web",
"nameValuePairs":"_ThreadID=68;_ThreadName=Thread-1;",
"messageID":"WEB0671",
"Message":" Loading application [__admingui] at [/]"}
,
{...
This is an array of log entries, each entry having the following attributes: "recordNumber","loggedDateTimeInMS","loggedLevel","productName","loggerName","nameValuePairs","messageID","Message". It is possible to refine the query for this array with the following HTTP params (similar again to what AMX log viewer APIs defined):
- "logFileName" with default value of "${com.sun.aas.instanceRoot}/logs/server.log")
- "startIndex" with default value of "-1"
- "searchForward" with default value of "false"
- "maximumNumberOfResults" with default value of "40"
- "fromTime" with default value of "-1" a long value in milliseconds
- "toTime" with default value of "-1" a long value in milliseconds
- "logLevel" with default value of "INFO"
4.1.4 Security Support
- The REST resources are protected by HTTP Basic Auth. Using Basic Auth should be sufficient if HTTPS is used at transport layer. However, it requires REST client to cache credentials so that it can be passed with each request.
- If it is not acceptable for a REST client to cache credentials, it can use Session Token mechanism. The mechanism works as follows:
- Investigation is underway to see if we can use HTTP Digest mechanism to authenticate. If we decide to use it, work needs to be done on Jersey Client side for this.
4.1.5 WADL representation Since the GlassFish REST admin backend is a JAX-RS application, the application.wadl Web Application Definition Language file is available at the standard location:
http://localhost:4848/management/application.wadl
It contains the complete meta-data information in XML for all the resources that are available and the resource paths, as well as all the HTTP methods available on each resource. Here is a subset of our current WADL file as generated by the JAX-RS backend for our REST application:
<application xmlns="http://research.sun.com/wadl/2006/10">
<doc xmlns:jersey="http://jersey.java.net/" jersey:generatedBy="Jersey: 1.1.5 01/20/2010 04:04 PM"/>
<resources base="http://localhost:4848/management/">
<resource path="/sessions">
<method id="create" name="POST">
<response>
<representation mediaType="*/*"/>
</response>
</method>
<resource path="{sessionId}/">
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="sessionId" style="template" type="xs:string"/>
<method id="delete" name="DELETE">
<response>
<representation mediaType="*/*"/>
</response>
</method>
</resource>
</resource>
<resource path="/domain/">
<method id="get" name="GET">
<request>
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="expandLevel" style="query" type="xs:int" default="1"/>
</request>
<response>
<representation mediaType="text/html;qs=2"/>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
<representation mediaType="application/x-www-form-urlencoded"/>
</response>
</method>
<method id="delete" name="DELETE">
<request>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
<representation mediaType="application/x-www-form-urlencoded"/>
<representation mediaType="application/octet-stream"/>
</request>
<response>
<representation mediaType="*/*"/>
</response>
</method>
<method id="options" name="OPTIONS">
<response>
<representation mediaType="application/json"/>
<representation mediaType="text/html;qs=2"/>
<representation mediaType="application/xml"/>
</response>
</method>
<method id="updateEntity" name="POST">
<request>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
<representation mediaType="application/x-www-form-urlencoded"/>
</request>
<response>
<representation mediaType="text/html;qs=2"/>
<representation mediaType="application/json"/>
<representation mediaType="application/xml"/>
</response>
</method>
...
4.1.7 Cluster DAS, and Instances Support While running in a cluster, the REST management adapter will only be available the Domain Administration Server (DAS). Some security changes will have to be implemented at the REST Grizzly adapter. TBD. We need to decide whether the monitoring adapter will be available on all instances or only on DAS. TBD. 4.1.8 Jersey Optimization for local access of REST resources The current main client for the REST admin back end is the GlassFish Admin Console. Currently, this application is running in the same process as the GlassFish process and the REST application. If performance of the Admin Console accessing the REST resources is an issue, we can implement a layer between the JAX-RS Jersey Client and the Server side to by pass the HTTP traffic in local mode. There are ways with our Jersey implementation to implement that in a transparent way. 4.1.8 Monitoring Support Monitoring HTTP API enables monitoring of GlassFish through HTTP urls. This support enable GlassFish monitoring through new tools and technologies. For example, using these API's cloud computing provider can charge customers based on number of sessions, number of requests etc. This API essentially exposes telemetry objects as HTTP urls. This RESTFul API will provide direct access to the whole monitoring tree. Monitoring Output Formats: Monitoring API supports following output formats XML, HTML and JSON. Additional representations can be plugged-in/provided, if there is a requirement. For the supported representations the output format will be same as defined for config objects Using this, the output format for specific data types will be: Example 1 Output for Statistic object in JSON format:
{
"{statistic}":{
"name"="xyz",
"unit"="xyz",
"description"="xyz",
"start-time"=xyz,
"last-sample-time"=xyz}
}
in XML format:
<statistic name="xyz"
unit="xyz"
description="xyz"
start-time="xyz"
last-sample-time="xyz"/>
in HTML format.
<html>
<body>
<h1>statistic</h1>
<hr>
<h2>name: xyz</h2>
<h2>unit: xyz</h2>
<h2>description: xyz</h2>
<h2>start-time: xyz</h2>
<h2>last-sample-time: xyz</h2>
</body>
</html>
Example 2 Output for Range Statistic object JSON
{"range-statistic":
{"high-water-mark"=xyz,
"low-water-mark"=xyz,
"current"=xyz,
"name"="xyz",
"unit"="xyz",
"description"="xyz",
"start-time"=xyz,
"last-sample-time"=xyz}
}
}
XML
<range-statistic high-water-mark="xyz"
low-water-mark="xyz"
current="xyz"
name="xyz"
unit="xyz"
description="xyz"
start-time="xyz"
last-sample-time="xyz"/>
HTML
<html>
<body>
<h1>range-statistic</h1>
<hr>
<h2>high-water-mark: xyz</h2>
<h2>low-water-mark: xyz</h2>
<h2>current: xyz</h2>
<h2>name: xyz</h2>
<h2>unit: xyz</h2>
<h2>description: xyz</h2>
<h2>start-time: xyz</h2>
<h2>last-sample-time: xyz</h2>
</body>
</html>
Monitoring URL Format: The monitoring URLs can have the following format
http://host:port/monitoring/path
- host: server host
- port: administration port
- path: identifies the resource
Monitoring Methods: Monitoring API will support get and options HTTP methods.
- GET /monitoring/{path} HTTP/1.1
- OPTIONS /monitoring/{path} HTTP/1.1
**Get meta-data of the resource
4.2. Bug/RFE Number(s): 4.3. In Scope:
- Full support for the new PaaS administration commands under development for 3.2
- Limited support for JMS administration
4.4. Out of Scope: 4.5. Interfaces: 4.5.1 Public Interfaces
- the management URL: http://_server_:_port_/management/
- the set of resources under this url is by nature dynamic, depending on the GlassFish configuration (set of modules installed).
- the output for each ConfigBean resource is depending on the corresponding ConfigBean structure and attributes (defined via the @Attribute HK2 annotation)
- the output of each CLI command resource depends on the list of params of this CLI. The XML and JSON output relies on the corresponding ActionReporter and how the command defines its output via the reporter
- the monitoring URL http://_server_:_port_/monitoring/
- @RestRedirects/@RestRedirect, as well as the new annotations for command mapping (e.g., @RestAttachments/@RestAttachement)
4.5.2 Private Interfaces None identified at this time 4.5.3 Deprecated/Removed Interfaces: As part of this effort, it is likely that one or more endpoints, especially those that relate to CLI commands, will be relocated to a more appropriate point in the resource tree, or removed altogether. These must be documented and clearly communicated to the end users of the interface. 4.6. Doc Impact: Formal documentation of what is expected of the backend developers is a planned deliverable for this project. The documentation team will either be involved in the drafting of this documentation, or, at the very least, will need to be aware of the existence of such documentation as they update the official REST documents. Once the design has been settled upon, the bulk of this document will be split out into a separate design document, allowing for easier reference and smaller one pagers in the future. 4.7. Admin/Config Impact: The Admin Console will have to be modified to support changes in the REST API. 4.8. HA Impact: None anticipated. 4.9. I18N/L10N Impact: None anticipated. 4.10. Packaging, Delivery & Upgrade: 4.10.1. Packaging This proposal will affect only the rest-services.jar already shipped with the server. 4.10.2. Delivery No impact on delivery. The module is already included in the distribution. 4.10.3. Upgrade and Migration: Any tree reorganization will likely have an effect on any existing clients (notably the Admin Console). The documentation delivered at the end of this project should make it clear what, if anything, a client will need to change. Due to the nature of the Admin Console (and it's concurrent development cycle), the REST team will need to work closely with the Console team as these changes are made. 4.11. Security Impact: The REST API is secured using the same admin realm as the console. 4.12. Compatibility Impact See above for discussion of resource tree reorganization. 4.13. Dependencies: 4.13.1 Internal Dependencies
4.13.2 External Dependencies
4.14. Testing Impact: There are a number of existing dev tests for the RESTful interface. These will be expanded and modified as needed to insure proper coverage. 5. Reference Documents:
6. Schedule: 6.1. Projected Availability: See Project Page (linked above) |