You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by jo...@apache.org on 2016/08/18 05:50:23 UTC

zeppelin git commit: [ZEPPELIN-1268] As an enduser, I would like to embed paragraph and refresh the content of it in my custom UI

Repository: zeppelin
Updated Branches:
  refs/heads/master 051929db3 -> bba6ddd24


[ZEPPELIN-1268] As an enduser, I would like to embed paragraph and refresh the content of it in my custom UI

### What is this PR for?
This pull request is to add the below options so when someone develops a custom UI it would ease them.
1. Add a new option "Get paragraph id" in the notebook UI
2. Add a new REST API to get the status of a single paragraph

### What type of PR is it?
Improvement

### Todos
* Need to update the REST APIs documentation http://zeppelin.apache.org/docs/0.7.0-SNAPSHOT/rest-api/rest-notebook.html#get-the-status-of-all-paragraphs

### What is the Jira issue?
* https://issues.apache.org/jira/browse/ZEPPELIN-1268

### How should this be tested?
* Navigate to the notebook UI and a new option "Get paragraph id" will be shown for each paragraph and on clicking on it, the paragraph id would be alerted
* The new REST API http://%5Bzeppelin-server%5D:%5Bzeppelin-port%5D/api/notebook/job/%5BnotebookId%5D/%5BparagraphId%5D could be accessed to get the status of a single paragraph.

### Screenshots (if appropriate)

### Questions:

Author: Kavin Kumar <ju...@gmail.com>
Author: Kavin <ka...@imaginea.com>

Closes #1262 from kavinkumarks/zeppelin-1268-custom-UI and squashes the following commits:

88a0627 [Kavin Kumar] Reverted UI code, added unit test for the new REST API and updated docs
4d11553 [Kavin] Changes to show new option to get paragraph id in notebook UI and new REST API to get status of a single paragraph


Project: http://git-wip-us.apache.org/repos/asf/zeppelin/repo
Commit: http://git-wip-us.apache.org/repos/asf/zeppelin/commit/bba6ddd2
Tree: http://git-wip-us.apache.org/repos/asf/zeppelin/tree/bba6ddd2
Diff: http://git-wip-us.apache.org/repos/asf/zeppelin/diff/bba6ddd2

Branch: refs/heads/master
Commit: bba6ddd2496d5f73354f2e5d510e2f989b93165f
Parents: 051929d
Author: Kavin Kumar <ju...@gmail.com>
Authored: Fri Aug 5 01:21:01 2016 +0530
Committer: Jongyoul Lee <jo...@apache.org>
Committed: Thu Aug 18 14:50:11 2016 +0900

----------------------------------------------------------------------
 docs/rest-api/rest-notebook.md                  | 37 ++++++++++++++++++
 .../apache/zeppelin/rest/NotebookRestApi.java   | 29 ++++++++++++++
 .../zeppelin/rest/NotebookRestApiTest.java      | 22 +++++++++++
 .../java/org/apache/zeppelin/notebook/Note.java | 40 ++++++++++++++------
 4 files changed, 116 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/bba6ddd2/docs/rest-api/rest-notebook.md
----------------------------------------------------------------------
diff --git a/docs/rest-api/rest-notebook.md b/docs/rest-api/rest-notebook.md
index 1275740..fa96b6e 100644
--- a/docs/rest-api/rest-notebook.md
+++ b/docs/rest-api/rest-notebook.md
@@ -393,6 +393,43 @@ If you work with Apache Zeppelin and find a need for an additional REST API, ple
   </table>
 
 <br/>
+### Get the status of a single paragraph
+  <table class="table-configuration">
+    <col width="200">
+    <tr>
+      <td>Description</td>
+      <td>This ```GET``` method gets the status of a single paragraph by the given notebook and paragraph id.
+          The body field of the returned JSON contains of the array that compose of the paragraph id, paragraph status, paragraph finish date, paragraph started date.
+      </td>
+    </tr>
+    <tr>
+      <td>URL</td>
+      <td>```http://[zeppelin-server]:[zeppelin-port]/api/notebook/job/[notebookId]/[paragraphId]```</td>
+    </tr>
+    <tr>
+      <td>Success code</td>
+      <td>200</td>
+    </tr>
+    <tr>
+      <td> Fail code</td>
+      <td> 500 </td>
+    </tr>
+    <tr>
+      <td> sample JSON response </td>
+      <td><pre>
+{
+  "status": "OK",
+  "body": {
+      "id":"20151121-212654\_766735423",
+      "status":"FINISHED",
+      "finished":"Tue Nov 24 14:21:40 KST 2015",
+      "started":"Tue Nov 24 14:21:39 KST 2015"
+    }
+}</pre></td>
+    </tr>
+  </table>
+
+<br/>
 ### Run a paragraph
   <table class="table-configuration">
     <col width="200">

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/bba6ddd2/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
index f33bef1..a724003 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
@@ -529,6 +529,35 @@ public class NotebookRestApi {
   }
 
   /**
+   * Get notebook paragraph job status REST API
+   *
+   * @param notebookId ID of Notebook
+   * @param paragraphId ID of Paragraph
+   * @return JSON with status.OK
+   * @throws IOException, IllegalArgumentException
+   */
+  @GET
+  @Path("job/{notebookId}/{paragraphId}")
+  @ZeppelinApi
+  public Response getNoteParagraphJobStatus(@PathParam("notebookId") String notebookId, 
+      @PathParam("paragraphId") String paragraphId)
+      throws IOException, IllegalArgumentException {
+    LOG.info("get notebook paragraph job status.");
+    Note note = notebook.getNote(notebookId);
+    if (note == null) {
+      return new JsonResponse<>(Status.NOT_FOUND, "note not found.").build();
+    }
+
+    Paragraph paragraph = note.getParagraph(paragraphId);
+    if (paragraph == null) {
+      return new JsonResponse<>(Status.NOT_FOUND, "paragraph not found.").build();
+    }
+
+    return new JsonResponse<>(Status.OK, null, note.generateSingleParagraphInfo(paragraphId)).
+      build();
+  }
+
+  /**
    * Run paragraph job REST API
    *
    * @param message - JSON with params if user wants to update dynamic form's value

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/bba6ddd2/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java
index 94e7fa8..b06c7ca 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java
@@ -122,6 +122,28 @@ public class NotebookRestApiTest extends AbstractTestRestApi {
     ZeppelinServer.notebook.removeNote(note2.getId(), null);
 
   }
+
+  @Test
+  public void testGetNoteParagraphJobStatus() throws IOException {
+    Note note1 = ZeppelinServer.notebook.createNote(null);
+    note1.addParagraph();
+
+    String paragraphId = note1.getLastParagraph().getId();
+
+    GetMethod get = httpGet("/notebook/job/" + note1.getId() + "/" + paragraphId);
+    assertThat(get, isAllowed());
+    Map<String, Object> resp = gson.fromJson(get.getResponseBodyAsString(), new TypeToken<Map<String, Object>>() {
+    }.getType());
+    Map<String, Set<String>> paragraphStatus = (Map<String, Set<String>>) resp.get("body");
+
+    // Check id and status have proper value
+    assertEquals(paragraphStatus.get("id"), paragraphId);
+    assertEquals(paragraphStatus.get("status"), "READY");
+
+    //cleanup
+    ZeppelinServer.notebook.removeNote(note1.getId(), null);
+
+  }
 }
 
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/bba6ddd2/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
index 9106cf5..d9a3f96 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Note.java
@@ -411,24 +411,40 @@ public class Note implements Serializable, ParagraphJobListener {
     List<Map<String, String>> paragraphsInfo = new LinkedList<>();
     synchronized (paragraphs) {
       for (Paragraph p : paragraphs) {
-        Map<String, String> info = new HashMap<>();
-        info.put("id", p.getId());
-        info.put("status", p.getStatus().toString());
-        if (p.getDateStarted() != null) {
-          info.put("started", p.getDateStarted().toString());
-        }
-        if (p.getDateFinished() != null) {
-          info.put("finished", p.getDateFinished().toString());
-        }
-        if (p.getStatus().isRunning()) {
-          info.put("progress", String.valueOf(p.progress()));
-        }
+        Map<String, String> info = populatePragraphInfo(p);
         paragraphsInfo.add(info);
       }
     }
     return paragraphsInfo;
   }
 
+  public Map<String, String> generateSingleParagraphInfo(String paragraphId) {
+    synchronized (paragraphs) {
+      for (Paragraph p : paragraphs) {
+        if (p.getId().equals(paragraphId)) {
+          return populatePragraphInfo(p);
+        }
+      }
+      return new HashMap<>();
+    }
+  }
+  
+  private Map<String, String> populatePragraphInfo(Paragraph p) {
+    Map<String, String> info = new HashMap<>();
+    info.put("id", p.getId());
+    info.put("status", p.getStatus().toString());
+    if (p.getDateStarted() != null) {
+      info.put("started", p.getDateStarted().toString());
+    }
+    if (p.getDateFinished() != null) {
+      info.put("finished", p.getDateFinished().toString());
+    }
+    if (p.getStatus().isRunning()) {
+      info.put("progress", String.valueOf(p.progress()));
+    }
+    return info;
+  }
+
   /**
    * Run all paragraphs sequentially.
    */