The Enterprise Manager provides a complete, interactive user interface described earlier in this book. However, there are times when it is desirable to automate frequently repeated actions or to script a series of actions into a single function.
To allow for these sorts of customizations, the VoltDB Enterprise Manager also provides a programmable interface based on the REST ("Representational State Transfer") architecture. If you are familiar with REST interfaces, you can skip to the reference section at the end of this chapter. If you are new to REST interfaces, the following sections provide a quick overview of:
How to program against the VoltDB management interface
What resources are available to you
A sample application using the REST API
The VoltDB Management interface uses the REST architecture to provide programmable services. At its simplest, the REST architecture allows an application to use HTTP requests to operate on a set of defined resources. For example, the following HTTP request adds a server to the Enterprise Manager's list of resources:
POST/man/api/1.0/mgmt/servers
HTTP/1.1 User-Agent: curl/7.21.0 (x86_64-pc-linux-gnu) Host: voltdbmgr:8080 Accept: */* Content-Length: 71 Content-Type: application/x-www-form-urlencoded {"Server":{"name":"Test Server","host":"localhost",""sshuser":"admin"}}
![]()
The key to understanding how the REST architecture works is to understand the components of the HTTP request.
The request method specifies the action to take. | |
The URL specifies the resource to operate on. | |
The body of the request specifies any arguments, values, or content needed to complete the action. |
So in the previous example, the request adds (POST) a server resource (/man/api/1.0/mgmt/servers) using the arguments in the request body (name="Test Server", host="localhost", and sshuser="admin"). It is important to note that for the VoltDB REST interface, with only one or two exceptions, all of the input and output (that is, the body of the requests and responses) is encoded as JSON strings. This is not required by the REST architecture per se, but provides a consistent standards-based mechanism for communicating through the VoltDB API.
The advantage of a REST interface is that many requests can be accomplished using a web browser or command line utility such as curl. For example, the following Linux shell script issues two requests to add servers and then requests a list of the servers currently defined within the Enterprise Manager.
curl --data "{'Server':{'name':'Server #1','host':'MyServer1',}}" \ http://voltdbmgr:9000/man/api/1.0/mgmt/servers curl --data "{'Server':{'name':'Server #2','host':'MyServer2',}}" \ http://voltdbmgr:9000/man/api/1.0/mgmt/servers curl http://voltdbmgr:9000/man/api/1.0/mgmt/servers
Once you understand the components of the REST request, the key to making the interface useful is understanding what resources are available and what actions you can perform. For the VoltDB Management interface, there are five types of resources you can operate on:
Catalogs
Databases
Deployments
Servers
Snapshots
You specify the type of resource as part of the URL. For example, /man/api/1.0/mgmt/databases
refers to database resources. To act on a specific resource, you include the resource's internal ID in the URL. So, for
example, the following command deletes the database with the internal ID of "154":
curl -X DELETE http://voltdbmgr:8080/man/api/1.0/mgmt/databases/154
For any given resource, there can be up to four methods you can apply to the resource:
GET — fetch information about the resource
POST — add a new resource
PUT — update an existing resource
DELETE — remove an existing resource
Section A.2, “VoltDB Management Interface: Reference Section” explains which methods are possible for each resource type and what arguments are required to perform a POST or PUT.
In addition, there are special actions possible for database resources only. For the database itself, the actions are START, STOP, PAUSE, RESUME, and SNAPSHOT. You can also perform a START and STOP on individual servers assigned to a database.
Since there are no equivalent HTTP methods for these actions, you invoke them by specifying the action as part of the URL and use the HTTP PUT method. For example, the following command starts the database identified by the ID 236:
curl -X PUT http://voltdbmgr:9000/man/api/1.0/mgmt/databases/236/start
When you use the VoltDB Management Interface, the REST services can return information to your program or script in several different ways. The three most important pieces of information the REST interface returns are the status code, any error messages if the request failed, and the return data when the request succeeds.
The REST interface uses standard HTTP response status codes to indicate the success or failure of requests. The specific return code depends upon the action requested. Table A.1, “REST Success Codes” describes the status codes that are returned when a call to the REST interface succeeds.
Table A.1. REST Success Codes
Method | HTTP Status | Description |
---|---|---|
GET | 200 | The information requested is returned in the body of the response as a JSON-encoded string. |
POST | 303 | When adding a new object, the URL of the created resource is returned as the redirect location in the HTTP header. |
POST | 200 | When requesting an action via a POST other than creating a new object (such as requesting a comparison of two catalogs), success is reported as code 200. |
PUT | 200 | When updating a resource, success is reported as code 200. |
PUT | 202 | When requesting an extended action (such as start, stop, or update) which is performed asynchronously, the successful initiation of that action is reported as code 202. The application should query the object periodically to check the status to see if and when the action completes. |
DELETE | 200 | Successful deletion of a resource is reported as code 200. |
As noted in the tables, the information returned by the response also depends upon the action requested. For GET methods, the information is returned in the body of the response as a JSON-encoded string. For successful POST actions, the URL for the created resource is returned in the redirect location in the HTTP header.
If a request fails, the VoltDB interface returns both an error status using the HTTP code and a detailed description of the error in the body of the response. The return status depends on the nature of the failure. Table A.2, “REST Error Codes” describes the status codes that are returned when a call to the REST interface fails.
Table A.2. REST Error Codes
Error | HTTP Status | Description |
---|---|---|
Invalid request | 400 | The HTTP request URL or JSON contents are invalid. See the body of the response for more information on the specific error. |
Invalid action | 403 | The action you requested is not currently permitted. This usually involves attempts to update or delete an object (such as a database) that is currently in use. Check the status of the object to determine what actions (such as stopping the database or server) are needed before repeating this request. |
Object not found | 404 | A valid request was made but the referenced object does not exist. This can happen if you try to update a server or database that has already been deleted or if you specify an invalid object ID. |
Internal error | 500 | An unexpected error occurred while attempting to execute your request. This condition should not occur during normal operation. See the body of the response for more information about the specific error. |
Note that the header, including the status code, is separate from the standard content of the response. You may need to use special arguments to capture the header in the output. For example, the following curl command uses the -w (write-out) argument to include the HTTP code in the output:
curl -w "Code: %{http_code}\n" http://castor:9000/man/api/1.0/mgmt/servers
The best way to understand an interface is often to see it in action. The following are some examples of Linux shell scripts that use the VoltDB Management interface to create and manage databases.
The following script creates the necessary servers, deployment, and catalog resources to define and start a database. In this case, it uses a script routine (RestAdd) to create each of the resources and return the resulting resource ID.
Note the use of the curl -w argument to write the redirect location as part of the output so the script can capture the resource ID created by the REST service. This is necessary since the ID is not in the body of the HTTP resource. An alternative approach is to use -L to have curl follow the redirection. In which case the full JSON representation of the new resource, including the ID, will be in the body of the response.
# # Sample script to create database. # MGTHOST="http://voltdbmgr:9000" RestAdd () { ID=$( curl -sw "%{redirect_url}" -d "$2" \ "$MGTHOST/man/api/1.0$1" \ | grep -oP "(?<=$1/)[0-9]+" ) echo "$ID" } # Define Three servers JSON='{"Server":{"host":"goneril","name":"goneril"}}' S1=$( RestAdd "/mgmt/servers" "$JSON" ) JSON='{"Server":{"host":"regan","name":"regan"}}' S2=$( RestAdd "/mgmt/servers" "$JSON" ) JSON='{"Server":{"host":"cordelia","name":"cordelia"}}' S3=$( RestAdd "/mgmt/servers" "$JSON" ) # Define a deployment JSON='{"Deployment":{"name":"Flight deployment"}}' D1=$( RestAdd "/mgmt/deployments" "$JSON" ) # Load a catalog (use base64-encoding) CATALOG=$( base64 flight.jar ) JSON="{\"Catalog\":{\"name\":\"flight\",\ \"catalogbytes\":\"$CATALOG\"}}" C1=$( RestAdd "/mgmt/catalogs" "$JSON" ) # Define and start database JSON="{\"Database\":{\"name\":\"Flight DB\",\ \"catalog\":\"$C1\",\"deployment\":\"$D1\",\ \"remotedir\":\"flightdb\",\ \"Servers\":[{\"server\":\"$S1\"},\ {\"server\":\"$S2\"},{\"server\":\"$S3\"}]}}" DB=$( RestAdd "/mgmt/databases" "$JSON" ) curl -X PUT "$MGTHOST/man/api/1.0/mgmt/databases/$DB/start"