Skip to content

Wf RO transformation service API

Soumya Brahma edited this page Feb 5, 2016 · 8 revisions

Table of Contents

Info
The service is running at http://sandbox.wf4ever-project.org/wf-ro/jobs/
*Reference implementation server: https://github.com/wf4ever/wf-ro
*Reference implementation client: https://github.com/wf4ever/wf-ro-client

API function overview

The Workflow Transformation API exposes a service that transforms workflows into research objects. Workflows are often complex data structures that embed data such as their sub-resources, annotations and provenance. The service described by this API creates a research object that exposes these data according to the RO model.

The service API allows to create a transformation job which the client can subsequently monitor. The output of the transformation job contains a list of resources aggregated in the research object that have been created based on the workflow.

API usage

Input:

  1. t2flow workflow
  2. RO identifier
  3. ROSRS URI
  4. OAuth access token
Output:
  1. HTTP Status code: 200 OK or other
Service algorithm:
  1. Extract the UUID from the workflow bundle, which is usually the same as the UUID of the main worfklow.
  2. Check if the RO exists in ROSRS:
    • if yes, do nothing. In the future, previous workflow versions may be deleted/preserved, together with their annotations.
    • if no, create a new one.
  3. Upload the workflow bundle to ROSRS, with the UUID as the resource identifier.
  4. Generate a wfdesc description of the workflow bundle (RDF graph). This describes all workflows inside the bundle, including relations between them.
  5. Upload the wfdesc description as workflow bundle annotation.
  6. Generate a roevo description of the workflow bundle (RDF graph). This includes the chains of UUIDs of all workflows in the bundle.
  7. Upload the roevo description as workflow bundle annotation.

Create a conversion job: POST /jobs/

The clients sends a transformation job parameters in a POST requests, requesting all resources to be extracted to the specified folders.

C: POST http://example.net/translate/jobs/ HTTP/1.1
C: Content-Type: application/json
C:
C: {
C:   "resource": "http://www.example.com/workflow.t2flow",
C:   "format": "application/vnd.taverna.t2flow+xml",
C:   "ro": "http://www.example.org/rodl/ROs/someRO/",
C:   "extract": {
C:       "main": "http://www.example.org/rodl/ROs/someRO/workflows/main/",
C:       "nested": "http://www.example.org/rodl/ROs/someRO/workflows/nested/",
C:       "scripts": "http://www.example.org/rodl/ROs/someRO/config/scripts/",
C:       "services": "http://www.example.org/rodl/ROs/someRO/config/web%20services/"
C:   },
C:   "token": ""47d5423c-b507-4e1c-7"
C: }

S: HTTP/1.1 201 Created
S: Location: http://example.net/translate/jobs/fefe-fefefef-fefefefefefe
The extract key and its subkeys are optional. If no extract is given, then only the main workflow is extracted, and it will be aggregated without being added to an RO folder.

How to create the conversion job in Java using org.apache.commons.httpclient.methods.PostMethod and Form data, here only extracting main workflow and scripts:

PostMethod method = new PostMethod(Constants.apiURL);    
method.addParameter("resource", t2flowURI);//"https://raw.github.com/wf4ever/provenance-corpus/master/Taverna_repository/workflow_2228_version_1/amiga_conesearch_from_a_file_of_targets_positions_268018.t2flow");
method.addParameter("format", Constants.format);//"application/vnd.taverna.t2flow+xml"
method.addParameter("ro", roID);//"http://sandbox.wf4ever-project.org/rodl/ROs/Sample2/"
method.addParameter("token", Constants.authToken);//"541002e2-9ff9-4cff-b85c-2b4af2c33e98"
method.addParameter("extract_main", folder_main);//"http://sandbox.wf4ever-project.org/rodl/ROs/Sample2/workflows/main/"
method.addParameter("extract_scripts", folder_scripts);//"http://sandbox.wf4ever-project.org/rodl/ROs/Sample2/config/scripts/"
method.addRequestHeader("Content-Type", Constants.contentType_URLencoded);//"application/x-www-form-urlencoded"
try{
          int returnCode = client.executeMethod(method);

          if(returnCode == HttpStatus.SC_NOT_IMPLEMENTED) {
                System.err.println("The Post method is not implemented by this URI");            
                method.getResponseBodyAsString();
          }else{
              br = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream()));
              String readLine;        
              while(((readLine = br.readLine()) != null)) {
                  System.err.println(readLine);
              }
              System.out.println(method.getStatusText());
              System.out.println("Location :"+method.getResponseHeader("Location").getValue());
          }
      } catch (Exception e) {
          System.err.println(e);
      } finally {
          method.releaseConnection();
          if(br != null) try { br.close(); } catch (Exception fe) {}
      }

Check job status: GET /jobs/{id}

The job status may be retrieved with a GET request to the job URI.

Job running

C: GET http://example.net/translate/jobs/fefe-fefefef-fefefefefefe HTTP/1.1
C: Accept: application/json

S: HTTP/1.1 200 OK
S: Content-Type: application/json
S:
S: {
S:   "resource": "http://www.example.com/workflow.t2flow",
S:   "format": "application/vnd.taverna.t2flow+xml",
S:   "ro": "http://www.example.org/rodl/ROs/someRO/",
S:   "extract": {
S:       "main": "http://www.example.org/rodl/ROs/someRO/workflows/main/",
S:       "scripts": "http://www.example.org/rodl/ROs/someRO/config/scripts/"
C:   },
S:   "status": "running"
S: }

Job finished

When the job has finished, the resources added or a reason for the jobs' failure is indicated:

C: GET http://example.net/translate/jobs/fefe-fefefef-fefefefefefe HTTP/1.1
C: Accept: application/json

S: HTTP/1.1 200 OK
S: Content-Type: application/json
S:
S: {
S:   "resource": "http://www.example.com/workflow.t2flow",
S:   "format": "application/vnd.taverna.t2flow+xml",
S:   "ro": "http://www.example.org/rodl/ROs/someRO/",
S:   "extract": {
S:       "main": "http://www.example.org/rodl/ROs/someRO/workflows/main/",
S:       "scripts": "http://www.example.org/rodl/ROs/someRO/config/scripts/"
C:   },
S:   "status": "done",
S:   "added": [
S:       "http://www.example.org/rodl/ROs/someRO/workflows/main/workflow.wfbundle",
S:       "http://www.example.org/rodl/ROs/someRO/config/scripts/ascript.txt", 
S:       "http://www.example.org/rodl/ROs/someRO/config/scripts/anotherscript.txt"
S:   ]
S: }
When the job has finished, the service may provide its status for an arbitrary amount time, large enough to allow clients to check that the job has finished. Retrieving the job status after that time will result in 404 Not Found.

Invalid resource

If the workflow resource is not valid, e.g. can't be found or not a supported workflow definition, the status is invalid_resource:

C: GET http://example.net/translate/jobs/fefe-fefefef-fefefefefefe HTTP/1.1
C: Accept: application/json

S: HTTP/1.1 200 OK
S: Content-Type: application/json
S:
S: {
S:   "resource": "http://www.example.com/non-existing-workflow.t2flow",
S:   "format": "application/vnd.taverna.t2flow+xml",
S:   "ro": "http://www.example.org/rodl/ROs/someRO/",
S:   "status": "invalid_resource",
S:   "reason": "Can't read the workflow: 404 Not Found"
S: }

Job failed

If the job failed, the status is runtime_error and reason shows the error message.

C: GET http://example.net/translate/jobs/fefe-fefefef-fefefefefefe HTTP/1.1
C: Accept: application/json

S: HTTP/1.1 200 OK
S: Content-Type: application/json
S:
S: {
S:   "resource": "http://www.example.com/workflow.t2flow",
S:   "format": "application/vnd.taverna.t2flow+xml",
S:   "ro": "http://www.example.org/rodl/ROs/someRO/",
S:   "status": "runtime_error",
S:   "reason": "It didn't work today"
S: }