Tutorial: 3. Workspace API

3. Workspace API

The SAP HANA REST Application Programming Interface (REST API) includes a Workspace API that enables you to create and manipulate workspaces and projects via HTTP. For more information about the original Orion API, on which the Workspace API is based, see http://wiki.eclipse.org/Orion/Server_API/Workspace_API.

The information in this section describes how to use the Workspace API in the context of SAP HANA. To better understand how it can be used, it is essential to understand the meaning of the terms workspace and project in the context of the Eclipse ORION concept.

  • ORION Workspace A concept taken over from the Eclipse architecture. A workspace is an area where the design artifacts used in coding or modeling work are located. In this sense, the workspace is user specific; it is the place where a user collects all the smaller entities required for development activities, for example, projects. This Eclipse-based workspace concept is different to the meaning of the workspace currently used in the context of the SAP HANA XS Repository.
  • ORION Project A collection of design time and modeling entities that not only have a common storage location, but to which you can also apply activities that typically occur during the development lifecycle, for example: compile, build, distribution, deployment, sharing objects with other developers.

Both ORION concepts are technicaly mapped to the SAP HANA XS package concept, which means that both are implemented as SAP HANA XS packages with specific content and in a specific location.

Contents

Actions on workspaces

List all Available Workspaces

Obtain the list of available workspaces (http://wiki.eclipse.org/Orion/Server_API/Workspace_API#Getting_the_list_of_available_workspaces).

Example Request

GET /sap/hana/xs/dt/base/workspace

EclipseWeb-Version: 1.0

Example Response

HTTP/1.1 200 OK

Content-Type: application/json
Content-Length: 132
ETag: "1"

{
"UserName": "Sam",
"Id": "987fd076g5sd6",
"Workspaces": [{ "Id" : "SAM_My_Dev_workspace_0", "Location" : "http://example.com/sap/hana/xs/dt/base/file/sap/hana/xs/dt/base/workspace/SAM_My_Dev_workspace_0", "LastModified" : 1291907325193", "Name" : "My Dev Workspace" }]
}

Create a Workspace

Create a new workspace.

Based on: http://wiki.eclipse.org/Orion/Server_API/Workspace_API#Creating_a_workspace

Example Request

POST sap/hana/xs/dt/base/workspace

EclipseWeb-Version: 1.0
X-CSRF-Token: "65ABA3082325A3408FBE71C87929102B"
Slug: My Dev Workspace

Example Response

HTTP/1.1 201 Created

Location: [http://example.com/sap/hana/xs/dt/base/file/sap/hana/xs/dt/base/content/workspace/SAM_My_Dev_workspace_0]
ETag: "1"
Content-Type: application/json

{
"Id": "SAM_My_Dev_workspace_0",
"Name": "My Dev Workspace",
"Location": "http://example.com/sap/hana/xs/dt/base/file/sap/hana/xs/dt/base/content/workspace/SAM_My_Dev_workspace_0",
"Projects": [],
"Children": []
}

Display Workspace Metadata

Retrieve metadata about a specified workspace.

Based on: http://wiki.eclipse.org/Orion/Server_API/Workspace_API#Getting_workspace_metadata

Example Request

GET sap/hana/xs/dt/base/workspace/SAM_My_Dev_workspace_0

EclipseWeb-Version: 1.0

Example Response

HTTP/1.1 200 OK

Content-Type: application/json
Content-Length: 132
ETag: "33"

{
"Id" ; "SAM_My_Dev_workspace_0",
"Name": "My Dev Workspace",
"Projects":
[{ "Id" : "SAM_My_Dev_Workspace_0My_Project_AA", "Location" : "http://example.com/sap/hana/xs/dt/base/file/SAM_My_Dev_Workspace_0/SAM_My_Dev_Workspace_0_My_Project_AA" }],
"Children":
[{ "Name" : "My Project AA", "Location" : "http://example.com/sap/hana/xs/dt/base/file/SAM_My_Dev_workspace_0/SAM_My_Dev_Workspace_0_My_Project_AA", "Children-Location" : "http://example.com/sap/hana/xs/dt/base/file/SAM_My_Dev_workspace_0/SAM_My_Dev_Workspace_0_My_Project_AA?depth=1", "Directory" : true }]
}

Change Workspace Metadata

Change workspace metadata.

Based on: http://wiki.eclipse.org/Orion/Server_API/Workspace_API#Changing_workspace_metadata

Example Request

PUT /sap/hana/xs/dt/base/workspace/SAM_My_Dev_Workspace_0

X-CSRF-Token: "65ABA3082325A3408FBE71C87929102B"
{
"Name" : "My Dev Workspace Update",
}

Example Response

HTTP/1.1 204 OK

Delete a Workspace

Delete an existing workspace. Note that deleting a non-existent workspace has no effect.

Based on http://wiki.eclipse.org/Orion/Server_API/Workspace_API#Deleting_a_workspace

Example Request

DELETE /sap/hana/xs/dt/base/workspace/SAM_My_Dev_Workspace_0

X-CSRF-Token: "65ABA3082325A3408FBE71C87929102B"

Example Response

HTTP/1.1 204 OK

Actions on Projects

Add a Project to a Workspace

Add a project to an existing workspace. If the project does not already exist it will be created.You can create an ORION project or an SAP HANA XS project as described in the respective section.

Based on: http://wiki.eclipse.org/Orion/Server_API/Workspace_API#Add_a_project_to_a_workspace

2.1.1. Create an ORION Native Project

Create the project as an SAP HANA XS subpackage in the specified workspace package; it is not an SAP HANA XS application package. The project is assigned to the projects list in the workspace metadata.

Example Request

POST /sap/hana/xs/dt/base/workspace/SAM_My_Dev_workspace_0

X-CSRF-Token: "65ABA3082325A3408FBE71C87929102B"
EclipseWeb-Version: 1.0
Slug: "My Project"

Example Response

HTTP/1.1 201 OK

Location: [http://localhost:8080/sap/hana/xs/dt/base/file/SAM_My_Dev_workspace_0/My Project]

{
"Id": "SAM_My_Dev_Workspace_0_My_Project_0",
"Location": "http://localhost:8080/sap/hana/xs/dt/base/file/sap/hana/xs/dt/base/content/workspace/SAM_My_Dev_Workspace_0/My Project",
"ContentLocation": "http://localhost:8080/sap/hana/xs/dt/base/file/sap/hana/xs/dt/base/content/workspace/SAM_My_Dev_Workspace_0/My Project",
"Name": "My Project"
}

2.1.2 Create an SAP HANA XS Project at a Specified Location and assign it to a Workspace

Create the project as an SAP HANA XS subpackage in the specified location; it is an SAP HANA XS application package. The project is assigned to the projects list in the workspace metadata.

Note that the method described in this section is not part of the current ORION API specification.

Example Request

// Triggering SAP extension

oSapBackPack = new Object();
strProjectName = "My Project" ;
oSapBackPack.isXSProject = true;
oSapBackPack.xsProjectLocation = "/content";
sapBackPack = JSON.stringify(oSapBackPack);

POST /sap/hana/xs/dt/base/workspace/SAM_My_Dev_Workspace_0
X-CSRF-Token: "65ABA3082325A3408FBE71C87929102B"
EclipseWeb-Version: 1.0
Slug: "My Project"
SapBackPack: "{"isXSProject": 'true', "xsProjectLocation":'/content'}"

Example Response

HTTP/1.1 201 OK

Location: [http://localhost:8080/sap/hana/xs/dt/base/file/content/My Project]

{
"Id": "SAM_My_Dev_Workspace_0_My_Project_0",
"Location": "http://localhost:8080/sap/hana/xs/dt/base/file/content/My_Project",
"ContentLocation": "http://localhost:8080/sap/hana/xs/dt/base/file/content/My_Project",
"Name": "My Project"
}

2.1.3 Create an SAP HANA XS Project in a Specified Location, Which is Not Visible in the ORION Workspace

Create the project as an SAP HANA XS subpackage in the specified location; it is not an SAP HANA XS application package. The project is not assigned to the projects list in the workspace metadata.

This method for creating a new project is not part of the current ORION API specification.

Example Request

// Triggering SAP extension

oSapBackPack = new Object();
strProjectName = "My Project" ;
oSapBackPack.isXSProject = true;
oSapBackPack.xsProjectLocation = "/content";
sapBackPack = JSON.stringify(oSapBackPack);

POST /sap/hana/xs/dt/base/workspace
X-CSRF-Token: "65ABA3082325A3408FBE71C87929102B"
EclipseWeb-Version: 1.0
Slug: "My Project"
SapBackPack: "{"isXSProject": 'true', "xsProjectLocation":'/content'}"

Example Response

HTTP/1.1 201 OK

Location: [http://localhost:8080/sap/hana/xs/dt/base/file/content/My Project]

{
"Id": "My_Project_0",
"Location": "http://localhost:8080/sap/hana/xs/dt/base/file/content/My Project",
"ContentLocation": "http://localhost:8080/sap/hana/xs/dt/base/file/content/My Project",
"Name": "My Project"
}

Moving (Renaming) a Project

Move an existing project to a new location.

Based on: http://wiki.eclipse.org/Orion/ServerAPI/Workspace_API#Moving.28renaming.29_a_project

Example Request

POST /sap/hana/xs/dt/base/workspace/SAM_My_Dev_workspace_0

X-CSRF-Token: "65ABA3082325A3408FBE71C87929102B"
Orion-Version: 1.0
Content-Length: 144
Content-Type: application/json
Slug: "destinationProject"
X-Create-Options: move

{
"Location": "http://example.com/sap/hana/xs/dt/base/file/SAM_My_Dev_workspace_0/destinationProject"
}

Example Response

HTTP/1.1 200 OK

Location: [http://example.com/sap/hana/xs/dt/base/file/SAM_My_Dev_workspace_0/destinationProject]
ETag: "1"
Content-Type: application/json

{
"ContentLocation": "//example.com/sap/hana/xs/dt/base/file/content/destinationProject",
"Id": "SAM_My_Dev_workspace_0_destinationProject_0",
"Location": "/sap/hana/xs/dt/base/file/content/destinationProject",
"Name": "destinationProject"
}

Remove a Project from a Workspace

Remove an existing project from a workspace. It removes the project reference from the workspace metadata but leaves the project itself in the repository. This method is based on http://wiki.eclipse.org/Orion/Server_API/Workspace_API#Remove_a_project_from_a_workspace. To remove the project (with all its content) from the repository, use either the File API or the method described in 2.4.Remove a project including content.

Example Request

DELETE /sap/hana/xs/dt/base/workspace/SAM_My_Dev_workspace_0/SAM_My_Dev_workspace_0_My_Project_0

X-CSRF-Token: "65ABA3082325A3408FBE71C87929102B"

Example Response

HTTP/1.1 204 OK

Remove a Project Including Content

Remove an existing project from a workspace including its content. Package and content are physically deleted. This method is not part of the current ORION SERVER API specification.

Example Request

// Triggering SAP extension

strProjectName = "My_Project_0" ;
var oSapBackPack = new Object();
oSapBackPack.isXSProject = true;
oSapBackPack.xsDeleteLocation = "/content/"+ strProjectName ;
var sapBackPack = JSON.stringify(oSapBackPack);

DELETE /sap/hana/xs/dt/base/workspace/SAM_My_Dev_workspace_0/SAM_My_Dev_workspace_0_My_Project_0
X-CSRF-Token: "65ABA3082325A3408FBE71C87929102B"
SapBackPack: {"isXSProject":'true', "xsDeleteLocation":'/content/My_Project_0'}

Example Response

HTTP/1.1 204 OK

Using Mustache Templates

This part of the REST API provides functionaliy that enables you to use so-called "mustache" templates in your implementation. Mustache templates enable you to create any kind of text-based, reusable components in the context of your tool, for example, to support the generation of project-specific files and pacakage layouts. This includes project-specific naming during the creation of a new project instance.

getProjectArtifactTemplate

Provides the complete list of template descriptions for a specific project.

Example Request

var strServiceName = "getProjectArtifactTemplate";

var strSapBackPack = "{\"projectType\":\"XS\",\"isTemplateContentRequired\":true}";
var request = new $.net.http.Request($.net.http.GET, strExecPathTemplate);;
request.headers.set('Service-Name', strServiceName);
request.headers.set('SapBackPack', strSapBackPack);
var response = client.request(request, destination).getResponse();

Input and Output Input

NamemandatoryDescription
projectTypeYXS (future possibilities: DB,RIVER)
projectLocation [1]YProject's full package name
isTemplateContentRequiredYtrue: Template content returned

JSON

{

"projectType": "XS",
"projectLocation": "/sap/hana/xs/myproject",
"isTemplateContentRequired": false
}

Output

The output returned is an array of entries whose format is described in the code block below The response is formatted as a JSON string, which can be directly instantiated into a JavaScript object using the JSON.parse method or tranformed into an object instance of the consuming runtime. The information displayed in the following table describes the structure of the returned array:

NamemandatoryDescription
ListYProject's artifacts list with related content
type [a]YArtifact type (file suffix)
subType [a]Artifact sub type (for example, Modification Exit for XSOData)
name [b]YArtifact name (for label)
groupName [2],[a]or[b]YArtifact group name
desc [b]YArtifact description (for tooltip)
isExist [3],[a]YArtifact already exists
isMandatory [a]YArtifact mandatory indicator
isRecommended [a]YArtifact recommended indicator
version [b]YArtifact version (compatibility indicator for client-side)
List [b] YArtifact template parameters for template instantiation
nameYArtifact template parameter name
defaultValArtifact template parameter default value
descYArtifact template parameter description (for tooltip)
templateContent [4],[c]Artifact template content

JSON

{

"artifact": [
{
"type": "xsodata",
"subType": "modificationExit",
"name": "OData descriptor",
"groupName": "XS",
"isMandatory": false
"isRecommended": false
"desc": "OData descriptor with Modification Exit",
"version": 1,
"templateParam": [
{
"name": "artifactName",
"defaultVal": "",
"desc": "Artifact name"
}
],
"templateContent": ""
}
]
}

Note the following:

[1] projectLocation: the place where the project will be created. The server uses this information to check artifact requirements.

xsaccess - package restriction - server does not return artifact, if it already exists in the same package

xsapp - package hierarchy restriction - server does not return artifact, if it already exists in the package hierarchy

if projectionLocation is not provided: artifacts will be returned without a check (as long as they appear in the .project file)

[2] groupName: stored at both the project level [a] (optionally) and artifact level [b] (mandatory); the server returns the project's level attribute if there is content, otherwise the server returns the artifact's level attribute

[3] true if artifact already exists. The main purpuse is to support the use of xsaccess (application access) and xsapp (application descriptor).

[4] templateContent: empty if: isTemplateContentRequired = false

getArtifactTemplate

Provides a template description for a specific template in a specific project..

Example Request

var strServiceName = "getArtifactTemplate";

var strSapBackPack = "{\"artifact\":[{\"type\":\"hdbtable\",\"subType\":\"columnstore\"}],\"isTemplateContentRequired\":true}";
var request = new $.net.http.Request($.net.http.GET, strExecPathTemplate);;
request.headers.set('Service-Name', strServiceName);
request.headers.set('SapBackPack', strSapBackPack);
var response = client.request(request, destination).getResponse();

Input and Output

Input

NamemandatoryDescription
ListYArtifacts list
type [a]YArtifact type (file suffix)
subType [a]Artifact sub type (for example, Modification Exit for XSOData)
isTemplateContentRequiredYtrue: Template content returned

JSON

{

"artifact": [
{
"type": "xsodata",
"subType": "modificationExit"
}
],
"isTemplateContentRequired": false
}

Output

NamemandatoryDescription
ListYProject's artifacts list with related content
type [a]YArtifact type (file suffix)
subType [a]Artifact sub type (for example, Modification Exit for XSOData)
name [b]YArtifact name (for label)
groupName [2],[a]or[b]YArtifact group name
desc [b]YArtifact description (for tooltip)
version [b]YArtifact version (compatibility indicator for client-side)
List [b] YArtifact template parameters for template instantiation
nameYArtifact template parameter name
defaultValArtifact template parameter default value
descYArtifact template parameter description (for tooltip)
templateContent [4],[c]Artifact template content

JSON

{

"artifact": [
{
"type": "xsodata",
"subType": "modificationExit",
"name": "OData descriptor",
"groupName": "XS",
"desc": "OData descriptor with Modification Exit",
"version": 1,
"templateParam": [
{
"name": "artifactName",
"defaultVal": "",
"desc": "Artifact name"
}
],
"templateContent": ""
}
]
}

[1] type, subType: based on artifact's file name - <artifactType>-<artifactSubType>
[2] templateContent: empty if: isTemplateContentRequired = false

getInstantiatedArtifact

Provides an instantiated template based on asset of parameters.

Example Request

var strServiceName = "getInstantiatedArtifact";

var strSapBackPack = "{\"artifact\":[{\"type\":\"hdbtable\",\"subType\":\"columnstore\",\"templateParam\":[{\"name\":\"schemaType\",\"val\":\"HUGO\"}]}]}";
var request = new $.net.http.Request($.net.http.GET, strExecPathTemplate);;
request.headers.set('Service-Name', strServiceName);
request.headers.set('SapBackPack', strSapBackPack);
var response = client.request(request, destination).getResponse();

Input and Output

Input

NamemandatoryDescription
ListYArtifacts list
typeYArtifact type (file suffix)
subTypeArtifact sub type (for example, Modification Exit for XSOData)
ListOptional list of template parameters
nameArtifact template parameter name
valArtifact template parameter value

JSON

 {                             

"artifact": [
{
"type": "xsodata",
"subType": "modificationExit",
"templateParam": [
{
"name": "artifactName",
"val": "MyArtifact"
}
]
}
]
}

Output

NamemandatoryDescription
ListYArtifacts list
type [a]YArtifact type (file suffix)
subType [a]Artifact sub type (for example, Modification Exit for XSOData)
isTemplateContentRequiredYInstantiated artifact content, based on template and parameters

JSON

{

"artifact": [
{
"type": "xsodata",
"subType": "modificationExit",
"instantiatedContent": "TemplateContentWithInjectedParamVals"
}
]
}

[1] artifactType, artifactSubType: based on artifact's file name <artifactType>-<artifactSubType>

Create Application Support

Based on the functionality for copying complete packages including all their content and the available mustache template renderer was introduced funcionality to enable the creation of complete project or application specific content with one REST API call in SP09.

Create Internal Application

Creates an internal Application based on a location in the repository (package) including all elements of the content neccessary for this application.

Example Request

var strServiceName = "CreateApplication"; 

var oSapBackPack =
{
"source" : "home/hana/xs/dt/base/work/wolfgang/project/template"
,"target" : "home/hana/xs/dt/base/work/wolfgang/project/target/Dest1"
,"parameters" : [{"name":"test","val":"HUGO"}
,{"name":"test2","val":"MORITZ"}
,{"name":"Test4","val":"MAX"}]
}
var sapBackPack = JSON.stringify(oSapBackPack);
geturl = $.ajax({
url: "/sap/hana/xs/dt/base/workspace",
type: 'POST',
headers: {
"Orion-Version": "1",
'Service-Name': strServiceName,
"Content-Type": "application/json",
"SapBackPack" : sapBackPack,
"X-CSRF-Token": frames.securityToken
},

Input and Output

Input

NamemandatoryDescription
sourceYrepository location of the template package
targetYrepository location of the generated package/application
parametersYJSON string containing the set of variable name a and value combinations neccessary for mustache rendcering.

JSON

{                                                                           

"source" : "home/hana/xs/dt/base/work/wolfgang/project/template"
,"target" : "home/hana/xs/dt/base/work/wolfgang/project/target/Dest1"
,"parameters" : [{"name":"test","val":"HUGO"}
,{"name":"test2","val":"MORITZ"}
,{"name":"Test4","val":"MAX"}]
}

Output

http return code cotaining or success information or error code. API specific error code is 555

Create External Application

This functionality enables the creation of Appications from zipped content. The zipped content can be provided in the body of the http request or at a location in the repository.

The other steps are executed in the same way like in the create application functionality- mustache rendering is executed and content is creatred at the specified location.

Example Request

var strServiceName = "CreateApplication";                                

var oSapBackPack =
{
"source" : ""
,"target" : "home/hana/xs/dt/base/work/wolfgang/project/target"
,"sourceType" : "remote"
,"parameters" : [
{"name":"Bla","val":"HUGO"}
,{"name":"Blu","val":"MORITZ"}
,{"name":"Bli","val":"GrueTZe"}
,{"name":"Ble","val":"Max"}
]
}
var sapBackPack = JSON.stringify(oSapBackPack);
geturl = $.ajax({
url: "/sap/hana/xs/dt/base/workspace",
type: 'POST',
processData: false,
contentType: type,
data: contents,
headers: {
"Orion-Version": "1",
'Service-Name': strServiceName,
"Content-Type": type,
"SapBackPack" : sapBackPack,
"X-CSRF-Token": frames.securityToken,
"X-Create-Options": "no-overwrite"
},
success: onComplete,
error: onError
});

Input and Output

Input

NamemandatoryDescription
sourceYrepository location of the zipped content. Empty if sourceType equals internal
targetYrepository location of the generated package/application
sourceTypeYspecifies if the zipped content is provide in the data section of the request or in the location specified in the source parameter
parametersYJSON string containing the set of variable name a and value combinations neccessary for mustache rendcering.
dataYcontains the zipped object if sourceType value equals external

JSON

{                                                                         

"source" : ""
,"target" : "home/hana/xs/dt/base/work/wolfgang/project/target"
,"sourceType" : "remote"
,"parameters" : [
{"name":"Bla","val":"HUGO"}
,{"name":"Blu","val":"MORITZ"}
,{"name":"Bli","val":"GrueTZe"}
,{"name":"Ble","val":"Max"}
]
}

Output

Copntains or OK Code for execution or error information returned in API specific RC 555.