Deploy API
This is the API specification and some examples for the RESTful HTTP Deploy API that can be used to deploy applications in a Vespa. The API supports multiple tenants and applications. Each tenant may have multiple applications deployed in different environments and different regions, all of which can be deployed using this API.
For a tenant, upload, prepare and activate applications. The response format is JSON. Examples are found in the use-cases.
The current API version is 2. The API port is 19071 - use
vespa-model-inspect service configserver
to find config server hosts. Example:
http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session
.
All operations are synchronous across the cluster of config servers,
meaning that requests return after the operations complete on all servers.
Note: An application file path in a request URL or parameter refers to a relative path in the application package. A path ending with '/' refers to a directory.
Entities:
Tenant | The tenant used in this API is created using the tenant REST API. The tenant name is required for all operations. Tenant names may only contain word characters and dash: [a-zA-Z_0-9-]. |
---|---|
Application | The application is the name of the application taken from the application package or given during prepare. Application names may only contain word characters: [a-zA-Z_0-9]. |
Environment | Multiple environments are not yet supported. Default is used. |
Region | Multiple regions are not yet supported. Default is used. |
Instance | Multiple instances are not yet supported. Default is used. |
Session-id | The session id used in this API is generated by the server and is required for all operations after creating a session. The session id is valid as long as it is one of the last 10 session ids created. |
Path |
When deploying to Vespa, use the vespa-deploy tool which wraps the Deploy API.
POST /application/v2/tenant/[tenant name]/session
Creates a new session with the application package that is included in the request.
Parameters |
|
||||||
---|---|---|---|---|---|---|---|
Request body |
|
||||||
Response |
A response includes:
|
Examples (both requests return same response):
POST /application/v2/tenant/mytenant/session
POST /application/v2/tenant/mytenant/session?from=http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/application/myapp/environment/default/region/default/instance/default
{ "tenant": "mytenant", "session-id": "1", "prepared": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/session-id/prepared/", "content": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/session-id/content/", "message": "Session 1 for tenant 'mytenant' created." }
PUT /application/v2/tenant/[tenant name]/session/[session id]/content/[path]
Writes the content to the given path, or creates a directory if the path ends with '/'.
Parameters | None |
---|---|
Request body |
|
Response |
None
|
GET /application/v2/tenant/[tenant name]/session/[session id]/content/[path]
Returns the content of the file at this path, or lists files and
directories if path
ends with '/'.
Parameters |
|
|||||||||
---|---|---|---|---|---|---|---|---|---|---|
Request body | None. | |||||||||
Response |
|
GET /application/v2/tenant/mytenant/session/3/content/
[ "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/3/content/hosts.xml", "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/3/content/services.xml", "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/3/content/schemas/" ]
GET /application/v2/tenant/mytenant/session/3/content/?recursive=true
[ "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/3/content/hosts.xml", "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/3/content/services.xml", "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/3/content/schemas/", "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/3/content/schemas/music.sd", "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/3/content/schemas/video.sd" ]
GET /application/v2/tenant/mytenant/session/3/content/hosts.xml
<?xml version="1.0" encoding="utf-8" ?> <hosts> <host name="myhost.mydomain.com"> <alias>vespa1</alias> </host> <host name="myhost.mydomain.com"> <alias>vespa2</alias> </host> </hosts>
GET /application/v2/tenant/mytenant/session/3/content/hosts.xml?return=status
{ "name": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/3/content/hosts.xml", "status": "new", "md5": "03d7cff861fcc2d88db70b7857d4d452" }
GET /application/v2/tenant/mytenant/session/3/content/schemas/?return=status
[ { "name": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/3/content/schemas/music.sd", "status": "new", "md5": "03d7cff861fcc2d88db70b7857d4d452" }, { "name": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/3/content/schemas/video.sd", "status": "changed", "md5": "03d7cff861fcc2d88db70b7857d4d452" }, { "name": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/3/content/schemas/book.sd", "status": "deleted", "md5": "03d7cff861fcc2d88db70b7857d4d452" } ]
DELETE /application/v2/tenant/[tenant name]/session/[session id]/content/[path]
Deletes the resource at the given path.
Parameters | None |
---|---|
Request body | None |
Response | Any errors or warnings from deleting the resource. |
PUT /application/v2/tenant/[tenant name]/session/[session id]/prepared
Prepares an application with the session id given.
Parameters |
|
|||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Request body | None | |||||||||||||||||||||
Response |
Returns a session id and a link to activate the session.
|
PUT /application/v2/tenant/mytenant/session/3/prepared
{ "tenant": "mytenant", "activate": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/session/3/active", "message": "Session 3 for tenant 'mytenant' prepared.", "log": [ { "level": "WARNING", "message": "Warning message 1", "time": 1430134091319 }, { "level": "WARNING", "message": "Warning message 2", "time": 1430134091320 } ], "configChangeActions": { "restart": [ { "clusterName": "mycluster", "clusterType": "search", "serviceType": "searchnode", "messages": [ "Document type 'test': Field 'f1' changed: add attribute aspect" ], "services": [ { "serviceName": "searchnode", "serviceType": "searchnode", "configId": "mycluster/search/cluster.mycluster/0", "hostName": "myhost.mydomain.com" } ] } ], "reindex": [ { "documentType": "test", "clusterName": "mycluster", "messages": [ "Document type 'test': Field 'f1' changed: add index aspect" ], "services": [ { "serviceName": "searchnode", "serviceType": "searchnode", "configId": "mycluster/search/cluster.mycluster/0", "hostName": "myhost.mydomain.com" } ] } ] } }
GET /application/v2/tenant/mytenant/session/[session id]/prepared
Returns the state of a prepared session. The response is the same as a successful prepare operation (above), however the configChangeActions element will be empty.
PUT /application/v2/tenant/[tenant name]/session/[session id]/active
Activates an application with the session id given. The session id must be for a prepared session. The operation will make sure the session is activated on all config servers, if more than one is configured.
Parameters |
|
||||||
---|---|---|---|---|---|---|---|
Request body | None | ||||||
Response |
Returns a session id, a message and a URL to the activated application.
|
PUT /application/v2/tenant/mytenant/session/3/active
{ "tenant": "mytenant", "message": "Session 3 for tenant 'mytenant' activated.", "url": "http://myconfigserver.mydomain.com:19071/application/v2/tenant/mytenant/application/myapp/environment/default/region/default/instance/default" }
GET /application/v2/tenant/[tenant name]/application/
Returns a list of the currently active applications for the given tenant
Parameters | None |
---|---|
Request body | None |
Response |
Returns a list of applications
|
GET /application/v2/tenant/mytenant/application/
{ ["http://myconfigserver.mydomain.com:19071/application/v2/tenant/default/application/default/environment/default/region/default/instance/default"] }
GET /application/v2/tenant/[tenant name]/application/[application name]
Gets info about the application.
Parameters | None |
---|---|
Request body | None |
Response |
Returns information about the application specified.
|
GET /application/v2/tenant/mytenant/application/foo
{ "generation": 2 }
GET /application/v2/tenant/[tenant name]/application/[application name]/environment/prod/region/default/instance/default/reindexing
Returns reindexing status for the given application.
Parameters | N/A |
---|---|
Request body | N/A |
Response |
JSON detailing current reindexing status for the application, with all its clusters and document types.
|
POST /application/v2/tenant/mytenant/application/foo/environment/prod/region/default/instance/default/reindexing
{ "clusters": { "db": { "ready": { "test_artifact": { "readyMillis": 1607937250998, "startedMillis": 1607940060012, "state": "running", "progress": 0.04013824462890625 }, "test_result": { "readyMillis": 1607688477294, "startedMillis": 1607690520026, "endedMillis": 1607709294236, "state": "successful" }, "test_run": { "readyMillis": 1607937250998, "state": "pending" } } } } }
POST /application/v2/tenant/[tenant name]/application/[application name]/environment/prod/region/default/instance/default/reindex
Triggers reindexing of specified document types in specified clusters of an application. Reindexing starts with the next redeployment of the application. All document types in all clusters are reindexed unless restricted, using parameters as specified:
Parameters |
|
||||||||
---|---|---|---|---|---|---|---|---|---|
Request body | N/A | ||||||||
Response | A human-readable message indicating what reindexing was triggered. |
POST /application/v2/tenant/mytenant/application/foo/environment/prod/region/default/instance/default/reindex?clusterId=foo,bar&documentType=moo,baz&indexedOnly=true
{"message": "Reindexing document types [moo, baz] in 'foo', [moo] in 'bar' of application mytenant.foo"}
GET /application/v2/tenant/[tenant name]/application/[application name]/environment/prod/region/default/instance/default/content/[path]
Returns content at the given path for an application. See getting content for usage and response.
DELETE /application/v2/tenant/[tenant name]/application/[application name]
Deletes an active application
Parameters | None |
---|---|
Request body | None |
Response | Returns a message stating if the operation was successful or not |
DELETE /application/v2/tenant/mytenant/application/foo
{ "message": "Application 'foo' was deleted" }
GET /application/v2/host/[hostname]
Gets information about which tenant and application a hostname is used by.
Parameters | None |
---|---|
Request body | None |
Response | Returns a message with tenant and application details. |
GET /application/v2/host/myhost.mydomain.com
{ "tenant":"mytenant" "application":"foo" "environment":"test" "region":"Europe" "instance":"1" }
Error Handling
Errors are returned using standard HTTP status codes. Any additional info is included in the body of the return call, JSON-formatted. The general format for an error response is:
{ "error-code": "ERROR_CODE", "message": "An error message" }
HTTP status code | Error code | Description |
---|---|---|
400 | BAD_REQUEST | Bad request. Client error. The error message should indicate the cause. |
400 | INVALID_APPLICATION_PACKAGE | There is an error in the application package. The error message should indicate the cause. |
400 | OUT_OF_CAPACITY | Not enough nodes available for the request to be fulfilled. |
401 | Not authorized. The error message should indicate the cause. | |
404 | NOT_FOUND | Not found. E.g. when using a session id that doesn't exist. |
405 | METHOD_NOT_ALLOWED | Method not implemented. E.g. using GET where only POST or PUT is allowed. |
409 | CONFLICT | Conflict, returned when activating an application fails due to a conflict with other changes to the same application (in another session). Client should retry. |
500 | INTERNAL_SERVER_ERROR | Internal server error. Generic error. The error message should indicate the cause. |
Request log
The log files for calls to the Deploy API are named configserver.<timestamp> and are found in $VESPA_HOME/logs/vespa/configserver/access.log. The format is the same as for the container access log - example:
10.76.246.20 - - [31/Jan/2013:22:05:45 +0000] "PUT /application/v2/tenant/mytenant/session/1/active HTTP/1.1" 200 1238 "" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:18.0) Gecko/20100101 Firefox/18.0" 1359669945.93 1 0.0 1
Use Cases
It is assumed that the tenant mytenant is already created in these use cases, and the application package is in app.
Create, prepare and activate an application
Create a session with the application package:
$ tar -C app -cf - . | gzip | curl -s --header "Content-Type: application/x-gzip" --data-binary @- \ "http://host:19071/application/v2/tenant/mytenant/session"Prepare the application with the URL in the prepared link from the response:
$ curl -s -X PUT "http://host:19071/application/v2/tenant/mytenant/session/1/prepared?applicationName=fooapp"Activate the application with the URL in the activate link from the response:
$ curl -s -X PUT "http://host:19071/application/v2/tenant/mytenant/session/1/active"
Modify the application package
Dump services.xml from session 1:
$ curl -s -X GET "http://host:19071/application/v2/tenant/mytenant/session/1/content/services.xml" <?xml version="1.0" encoding="utf-8" ?> <services version="1.0"> <admin version="2.0"> <config name="config.logd"> <logserver> <port>12345</port> </logserver> </config> <adminserver hostalias="node1" /> </admin> </services>Session 1 is activated and cannot be changed - create a new session based on the active session:
$ curl -s -X POST "http://host:19071/application/v2/tenant/mytenant/session?from=http://host:19071/application/v2/tenant/mytenant/application/fooapp/environment/default/region/default/instance/default"
Modify port number in services.xml, deploy the change:
$ curl -s -X PUT --data-binary @app/services.xml \ "http://host:19071/application/v2/tenant/mytenant/session/2/content/services.xml"Get services.xml from session 2 to validate:
$ curl -s -X GET "http://host:19071/application/v2/tenant/mytenant/session/2/content/services.xml" <?xml version="1.0" encoding="utf-8" ?> <services version="1.0"> <admin version="2.0"> <config name="config.logd"> <logserver> <port>12346</port> </logserver> </config> <adminserver hostalias="node1" /> </admin> </services>To add the file files/test1.txt, first create the directory, then add the file:
$ curl -s -X PUT "http://host:19071/application/v2/tenant/mytenant/session/2/content/files/" $ curl -s -X PUT --data-binary @app/files/test1.txt "http://host:19071/application/v2/tenant/mytenant/session/2/content/files/test1.txt"Prepare and activate the session:
$ curl -s -X PUT "http://host:19071/application/v2/tenant/mytenant/session/2/prepared?applicationName=fooapp" $ curl -s -X PUT "http://host:19071/application/v2/tenant/mytenant/session/2/active"
Rollback
Say that you find out that the changes done in the latest application did not work out as expected and you want to rollback to a previous state known to work. This is achieved by having multiple instance of an application. To rollback, simply create a new session passing the previous instance as the from argument.