...
Code Block |
---|
GET /namespaces/default/artifacts/myapp/versions/1.0.0 { "name": "purchasemyapp", "version": "31.10.0", "meta": { "created": "1234567890000", ... }, "classes": { "apps": [ { "className": "co.cask.cdap.examples.myapp.MyApp", "properties": { "stream": { "name": "stream", "description": "The name of the stream to read from. Defaults to 'A'.", "type": "string", "required": false }, "table": { "name": "table", "description": "The name of the table to write to. Defaults to 'X'.", "type": "string", "required": false, }, "flowConfig": { "name": "flow", "description": "", "type": "config", "fields": { "reader": { "name": "reader", "description": "", "type": "config", "required": true, "fields": { "name": { "name": "name", "description": "The name of the reader plugin to use.", "type": "string", "required": true }, "properties": { "name": "properties", "description": "The properties needed by the chosen reader plugin.", "type": "plugin", "plugintype": "reader", "required": true } } }, "writer": { ... } } } } } ], "plugins": [ { "name": "default", "type": "reader", "description": "Writes timestamp and body as two columns and expects the row key to come as a header in the stream event.", "className": "co.cask.cdap.examples.myapp.plugins.DefaultStreamReader", "properties": { "rowkey": { "name": "rowkey", "description": "The header that should be used as the row key to write to. Defaults to 'rowkey'.", "type": "string", "required": false } } } ], "flows": [ ... ], "flowlets": [ ... ], "datasetModules": [ ... ] } } |
...
Code Block |
---|
GET /namespaces/default/plugintypes/reader/plugins/default [ { "type": "reader", "name": "default", "description": "Writes timestamp and body as two columns and expects the row key to come as a header in the stream event.", "className": "co.cask.cdap.examples.myapp.plugins.DefaultStreamReader", "properties": { "rowkey": { "name": "rowkey", "description": "The header that should be used as the row key to write to. Defaults to 'rowkey'.", "type": "string", "required": false } }, "artifact": { "namespace": "default", "name": "myapp", "version": "1.0.0" } } ] |
contained in the artifact.
Users will still be able to deploy an app in one call. Suppose a user wants to deploy their application contained in myapp-1.0.0.jar. They make the same RESTful call they would todayNow the admin has all the information needed to create an application from the artifact:
Code Block |
---|
PUT /namespaces/default/apps/myapppurchaseDump -H "X-Archive-Name: myapp-d ' { "artifact": { "name": "myapp", "version": "1.0.0.jar" -H "Content-Type: application/octet-stream" --data-binary @myapp-1.0.0.jar |
Internally, CDAP will add the jar to its ArtifactRepository (new in CDAP 3.1), and then create an application from that artifact. In this example, the application creates stream A and Table X by default.
After the app is deployed, a user can now create Application myapp2 by referencing the artifact and config in their request without actually including the jar contents in the request. This lets users create applications using only config.
Code Block |
---|
PUT /namespaces/default/apps/myapp2 -H "Content-Type: application/json" -d '{ "artifact": { "name": "myapp", "version": "1.0.0" }, "config": { "stream": "B", "table": "X" } }' |
Deploying an Artifact, then an Application
Users can also deploy an artifact without creating an application.
Code Block |
---|
POST /namespaces/default/artifacts/myapp --data-binary @myapp-1.0.1.jar |
An application can then be created from that artifact in a separate call.
Code Block |
---|
PUT /namespaces/default/apps/myapp3 -H "Content-Type: application/json" -d '{ "artifact": { "name": "my-app", }, "config": { "stream": "purchases", "table": "events", "flow": { "reader": { "name": "default", "properties": { } }, "writer": { ... } } } }' |
This creates an application that reads from the 'purchases' stream and writes to the 'events' table. In the same way, other applications can be created that read from and write to configurable data sources.
3. Upgrading an Application
A bug is found in the application code. A new version of the artifact is created and deployed:
Code Block |
---|
POST /namespaces/default/artifacts/myapp --data-binary @myapp-1.0.1.jar |
The admin wants to see what applications are using the old version of the artifact:
Code Block |
---|
GET /namespaces/default/apps?artifactName=myapp&artifactVersion=1.0.0
[
{
"name": "purchaseDump"
}
] |
The admin stops all running programs for the app using existing APIs. A call is then made to upgrade the app to the latest artifact:
Code Block |
---|
PUT /namespaces/default/apps/purchaseDump/properties -d '
{
"artifact": {
"name": "myapp",
"version": "1.0.1"
},
"config": {
"stream": "purchases",
"table": "events",
"flow": {
"reader": {
"name": "default",
"properties": { }
},
"writer": { ... }
}
}
}' |
4. Rolling back an Application
Oops, it turns out v1.0.1 has a critical bug. The admin stops all running programs then makes a call to rollback to the previous version:
Code Block |
---|
PUT /namespaces/default/apps/purchaseDump/properties -d '
{
"artifact": {
"name": "myapp",
"version": "1.0.0"
},
"config": {
"stream": "purchases",
"table": "events",
"flow": {
"reader": {
"name": "default",
"properties": { }
},
"writer": { ... }
}
}
}' |
5. System Artifacts
System artifacts are special artifacts that can be accessed in other namespaces. They cannot be deployed through the RESTful API. Instead, they are placed in a directory on the CDAP master host. When CDAP starts up, the directory will be scanned and those artifacts will be added to the system. Example uses for system artifacts are the ETLBatch and ETLRealtime applications that we want to include out of the box.
System artifacts are included in results by default and are indicated with a special flag.
Code Block |
---|
GET /namespaces/default/artifacts?includeSystem=true [ { "name": "ETLBatch", "version": "3.1.0", "isSystem": true }, { "name": "ETLRealtime", "version": "3.1.0", "isSystem": true }, { "name": "ETLPlugins", "version": "3.1.0", "isSystem": true }, { "name": "myapp", "version": "1.0.10", }, "configisSystem": false }, { "streamname": "Cmyapp", "tableversion": "X"} }' |
Updating an Application
Users will also be able to update their applications to use a different version of an artifact.
Code Block |
---|
PUT1.0.1", "isSystem": false } ] |
System artifacts can be excluded from results using a filter:
Code Block |
---|
GET /namespaces/default/apps/myapp/properties -H "Content-Type: application/json" -d '{ "artifact": {artifacts?includeSystem=false [ { "name": "myapp", "version": "1.0.10", }, "configisSystem": false }, { "streamname": "Amyapp", "tableversion": "X" } }' |
System Artifacts
...
"1.0.1",
"isSystem": false
}
] |
When a user wants to create an application from a system artifact, they make the same RESTful call as before, except adding the namespace to the artifact section of the calla special flag to indicate it is a system artifact:
Code Block |
---|
PUT /namespaces/default/apps/somePipeline -H "Content-Type: application/json" /namespaces/default/apps/somePipeline -d ' { "artifact": { "namespace": "system", "name":"ETLBatch", "version":"3.1.0", "isSystem": true }, "config": { ... } }' |
...
RESTful API changes
Application APIs
Type | Path | Body | Headers | Description |
---|---|---|---|---|
GET | /v3/namespaces/<namespace-id>/apps?label=<label>artifactName=<name>[&artifactVersion=<version>] | for example, to get all "ETLBatch" applications | get all apps using the given artifact name and version | |
POST | /v3/namespaces/<namespace-id>/apps | application jar contents | Application-Config: <json of config> | same as deploy api today, except allows passing config as a header |
PUT | /v3/namespaces/<namespace-id>/apps/<app-name> | application jar contents | Application-Config: <json of config> | same as deploy api today, except allows passing config as a header |
PUT | /v3/namespaces/<namespace-id>/apps/<app-name> | { 'artifact': 'name-version', 'config': { ... } } | Content-Type: application/json | create an application from an existing artifact. Note: Edits existing API, different behavior based on content-type |
PUT | /v3/namespaces/<namespace-id>/apps/<app-name>/properties | { 'artifact': 'name-version', 'config': { ... } } | update an existing application. No programs can be running |
...
Type | Path | Body | Headers | Description | ||
---|---|---|---|---|---|---|
GET | /v3/namespaces/<namespace-id>/artifacts | |||||
GET | /v3/namespaces/<namespace-id>/artifacts/<artifact-name> | Get data about all artifact versions | ||||
POST | /v3/namespaces/<namespace-id>/artifacts/<artifact-name> | jar contents | Artifact-Version: <version> | Add a new artifact. Version header only needed if Bundle-Version is not in jar Manifest. If both present, header wins. | ||
GET | /v3/namespaces/<namespace-id>/artifacts/<artifact-name>/versions/<version> | Get details about the artifact, such as what plugins and applications are in the artifact and properties they support | ||||
PUT | /v3/namespaces/<namespace-id>/artifacts/<artifact-name>/versions/<version>/plugins | list of plugins contained in the jar | This is required for 3rd party jars, such as the mysql jdbc connector. It is the equivalent of the .json file we have in 3.0 | |||
GET | /v3/namespaces/<namespace-id>/extensionsplugintypes |
| ||||
GET | /v3/namespaces/<namespace-id>/extensionsplugintypes/<plugin-type> | |||||
GET | /v3/namespaces/<namespace-id>/extensionsplugintypes/<plugin-type>/plugins/<plugin-name> | config properties can be nested now. For example:
|
...
Type | Path | Replaced By |
---|---|---|
GET | /v3/templates | |
GET | /v3/templates/<template-name> | |
GET | /v3/templates/<template-name>/extensions/<plugin-type> | /v3/namespaces/<namespace-id>/extensionsplugintypes/<plugin-type> |
GET | /v3/templates/<template-name>/extensions/<plugin-type>/plugins/<plugin-name> | /v3/namespaces/<namespace-id>/extensionsplugintypes/<plugin-type>/plugins/<plugin-name> |
PUT | /v3/namespaces/<namespace-id>/templates/<template-id> | |
GET | /v3/namespaces/<namespace-id>/adapters | |
GET | /v3/namespaces/<namespace-id>/adapters/<adapter-name> | |
POST | /v3/namespaces/<namespace-id>/adapters/<adapter-name>/start | |
POST | /v3/namespaces/<namespace-id>/adapters/<adapter-name>/stop | |
GET | /v3/namespaces/<namespace-id>/adapters/<adapter-name>/status | |
GET | /v3/namespaces/<namespace-id>/adapters/<adapter-name>/runs | |
GET | /v3/namespaces/<namespace-id>/adapters/<adapter-name>/runs/<run-id> | |
DELETE | /v3/namespaces/<namespace-id>/adapters/<adapter-name> |