From 364535481ede86385356291e31b6575ccde93ed3 Mon Sep 17 00:00:00 2001 From: Ramaswamy Devarajan Date: Fri, 8 Jan 2016 16:24:31 -0800 Subject: [PATCH 01/12] Rest Apis to export/import --- .../apache/zeppelin/rest/NotebookRestApi.java | 54 ++++++++++++- .../zeppelin/rest/ZeppelinRestApiTest.java | 77 +++++++++++++++++++ 2 files changed, 130 insertions(+), 1 deletion(-) 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 f696b4614e1..30705089c45 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 @@ -52,7 +52,9 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; - +import com.google.gson.GsonBuilder; +import com.google.gson.stream.JsonReader; +import java.io.StringReader; /** * Rest api endpoint for the noteBook. */ @@ -146,6 +148,56 @@ public Response getNotebook(@PathParam("notebookId") String notebookId) throws I return new JsonResponse<>(Status.OK, "", note).build(); } + /** + * export note REST API + * @param + * @return note JSON with status.OK + * @throws IOException + */ + @GET + @Path("export/{id}") + public Response exportNoteBook(@PathParam("id") String noteId) { + GsonBuilder gsonBuilder = new GsonBuilder(); + gsonBuilder.setPrettyPrinting(); + Gson gson = gsonBuilder.create(); + Note note = notebook.getNote(noteId); + String json = gson.toJson(note); + return new JsonResponse(Status.OK, "", json).build(); + } + + /** + * import new note REST API + * @param req - notebook Json + * @return JSON with new note ID + * @throws IOException + */ + @PUT + @Path("import") + public Response importNotebook(String req) { + GsonBuilder gsonBuilder = new GsonBuilder(); + gsonBuilder.setPrettyPrinting(); + Gson gson = gsonBuilder.create(); + JsonReader reader = new JsonReader(new StringReader(req)); + reader.setLenient(true); + Note newNote; + try { + Note oldNote = gson.fromJson(reader, Note.class); + newNote = notebook.createNote(); + newNote.setName(oldNote.getName()); + List paragraphs = oldNote.getParagraphs(); + for (Paragraph p : paragraphs) { + newNote.addCloneParagraph(p); + } + + newNote.persist(); + } catch (IOException e) { + return new JsonResponse(Status.INTERNAL_SERVER_ERROR).build(); + } + notebookServer.broadcastNote(newNote); + notebookServer.broadcastNoteList(); + return new JsonResponse<>(Status.CREATED, "", newNote.getId() ).build(); + } + /** * Create new note REST API * @param message - JSON with new note name diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java index c7ac6319f30..42dc8787d06 100644 --- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java +++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java @@ -319,6 +319,83 @@ public void testDeleteNoteBadId() throws IOException { } + @Test + public void testExportNotebook() throws IOException { + LOG.info("testExportNotebook"); + Note note = ZeppelinServer.notebook.createNote(); + assertNotNull("can't create new note", note); + note.setName("source note for export"); + Paragraph paragraph = note.addParagraph(); + Map config = paragraph.getConfig(); + config.put("enabled", true); + paragraph.setConfig(config); + paragraph.setText("%md This is my new paragraph in my new note"); + note.persist(); + String sourceNoteID = note.getId(); + // Call export Notebook REST API + GetMethod get = httpGet("/notebook/export/" + sourceNoteID); + LOG.info("testNotebookExport \n" + get.getResponseBodyAsString()); + assertThat("test notebook export method:", get, isAllowed()); + + Map resp = gson.fromJson(get.getResponseBodyAsString(), new TypeToken>() { + }.getType()); + + String exportJSON = (String) resp.get("body"); + assertNotNull("Can not find new notejson", exportJSON); + LOG.info("export JSON:=" + exportJSON); + ZeppelinServer.notebook.removeNote(sourceNoteID); + get.releaseConnection(); + + } + + @Test + public void testImportNotebook() throws IOException { + Map resp; + String noteName="source note for import"; + LOG.info("testImortNotebook"); + //create test notebook + Note note = ZeppelinServer.notebook.createNote(); + assertNotNull("can't create new note", note); + note.setName(noteName); + Paragraph paragraph = note.addParagraph(); + Map config = paragraph.getConfig(); + config.put("enabled", true); + paragraph.setConfig(config); + paragraph.setText("%md This is my new paragraph in my new note"); + note.persist(); + String sourceNoteID = note.getId(); + // get note content as JSON + String oldJson = getNoteContent(sourceNoteID); + //call notebook put + PutMethod importPut = httpPut("/notebook/import/" , oldJson); + assertThat(importPut, isCreated()); + resp = gson.fromJson(importPut.getResponseBodyAsString(), new TypeToken>(){}.getType()); + String importId = (String) resp.get("body"); + + assertNotNull("Did not get back a notebook id in body", importId); + Note newNote=ZeppelinServer.notebook.getNote(importId); + assertEquals("Compare note names", noteName, newNote.getName()); + assertEquals("Compare paragraphs count", note.getParagraphs().size(), newNote.getParagraphs().size()); + //cleanup + ZeppelinServer.notebook.removeNote(note.getId()); + ZeppelinServer.notebook.removeNote(newNote.getId()); + importPut.releaseConnection(); + } + + private String getNoteContent(String id) throws IOException { + GetMethod get = httpGet("/notebook/export/" + id); + assertThat(get, isAllowed()); + get.addRequestHeader("Origin", "http://localhost"); + Map resp = gson.fromJson(get.getResponseBodyAsString(), + new TypeToken>() { + }.getType()); + assertEquals(200, get.getStatusCode()); + String body = resp.get("body").toString(); + // System.out.println("Body is " + body); + get.releaseConnection(); + return body; + } + private void testDeleteNotebook(String notebookId) throws IOException { DeleteMethod delete = httpDelete(("/notebook/" + notebookId)); From 0e94dcede33a9750249e792ad77069d80cae803b Mon Sep 17 00:00:00 2001 From: Ramaswamy Devarajan Date: Fri, 8 Jan 2016 16:57:17 -0800 Subject: [PATCH 02/12] add documentation --- docs/rest-api/rest-notebook.md | 115 ++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-) diff --git a/docs/rest-api/rest-notebook.md b/docs/rest-api/rest-notebook.md index 3c94268e707..c2a4795008f 100644 --- a/docs/rest-api/rest-notebook.md +++ b/docs/rest-api/rest-notebook.md @@ -33,7 +33,7 @@ limitations under the License.
### Notebook REST API list - Notebooks REST API supports the following operations: List, Create, Get, Delete, Clone, Run as detailed in the following table + Notebooks REST API supports the following operations: List, Create, Get, Delete, Clone, Run, Export, Import as detailed in the following table @@ -773,3 +773,116 @@ limitations under the License.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Export notebook
DescriptionThis ```GET``` method exports a notebook by the given id and gernerates a JSON + +
URL```http://[zeppelin-server]:[zeppelin-port]/api/notebook/export/[notebookId]```
Success code201
Fail code 500
sample JSON response
{
+  "paragraphs": [
+    {
+      "text": "%md This is my new paragraph in my new note",
+      "dateUpdated": "Jan 8, 2016 4:49:38 PM",
+      "config": {
+        "enabled": true
+      },
+      "settings": {
+        "params": {},
+        "forms": {}
+      },
+      "jobName": "paragraph_1452300578795_1196072540",
+      "id": "20160108-164938_1685162144",
+      "dateCreated": "Jan 8, 2016 4:49:38 PM",
+      "status": "READY",
+      "progressUpdateIntervalMs": 500
+    }
+  ],
+  "name": "source note for export",
+  "id": "2B82H3RR1",
+  "angularObjects": {},
+  "config": {},
+  "info": {}
+}
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Export notebook
DescriptionThis ```PUT``` method imports a notebook from the notebook JSON + +
URL```http://[zeppelin-server]:[zeppelin-port]/api/notebook/import```
Success code201
Fail code 500
sample JSON input
{
+  "paragraphs": [
+    {
+      "text": "%md This is my new paragraph in my new note",
+      "dateUpdated": "Jan 8, 2016 4:49:38 PM",
+      "config": {
+        "enabled": true
+      },
+      "settings": {
+        "params": {},
+        "forms": {}
+      },
+      "jobName": "paragraph_1452300578795_1196072540",
+      "id": "20160108-164938_1685162144",
+      "dateCreated": "Jan 8, 2016 4:49:38 PM",
+      "status": "READY",
+      "progressUpdateIntervalMs": 500
+    }
+  ],
+  "name": "source note for export",
+  "id": "2B82H3RR1",
+  "angularObjects": {},
+  "config": {},
+  "info": {}
+}
sample JSON response
"status": "CREATED","message": "","body": "2AZPHY918"}
\ No newline at end of file From 9b64a6603c5e23f5b8fe96cbc1399c014ec81b36 Mon Sep 17 00:00:00 2001 From: Ramaswamy Devarajan Date: Fri, 8 Jan 2016 16:59:24 -0800 Subject: [PATCH 03/12] fixed alignments --- docs/rest-api/rest-notebook.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/docs/rest-api/rest-notebook.md b/docs/rest-api/rest-notebook.md index c2a4795008f..097caf59aa5 100644 --- a/docs/rest-api/rest-notebook.md +++ b/docs/rest-api/rest-notebook.md @@ -784,7 +784,6 @@ limitations under the License. Description This ```GET``` method exports a notebook by the given id and gernerates a JSON - @@ -799,8 +798,7 @@ limitations under the License. Fail code 500 - - sample JSON response + sample JSON response
{
   "paragraphs": [
     {
@@ -838,7 +836,6 @@ limitations under the License.
     
       Description
       This ```PUT``` method imports a notebook from the notebook JSON
-         
       
     
     
@@ -853,8 +850,7 @@ limitations under the License.
        Fail code
        500 
     
-    
-       sample JSON input 
+     sample JSON input 
       
{
   "paragraphs": [
     {

From ecb8f1eaf59a399c0692d19041af8a553db5b3b2 Mon Sep 17 00:00:00 2001
From: Ramaswamy Devarajan 
Date: Fri, 8 Jan 2016 19:55:02 -0800
Subject: [PATCH 04/12] Formatting for google style

---
 .../apache/zeppelin/rest/NotebookRestApi.java |  4 +-
 .../zeppelin/rest/ZeppelinRestApiTest.java    | 60 ++++++++++---------
 2 files changed, 35 insertions(+), 29 deletions(-)

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 30705089c45..dfe7ab6c3ab 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
@@ -150,6 +150,7 @@ public Response getNotebook(@PathParam("notebookId") String notebookId) throws I
 
   /**
    * export note REST API
+   * 
    * @param
    * @return note JSON with status.OK
    * @throws IOException
@@ -167,6 +168,7 @@ public Response exportNoteBook(@PathParam("id") String noteId) {
 
   /**
    * import new note REST API
+   * 
    * @param req - notebook Json
    * @return JSON with new note ID
    * @throws IOException
@@ -195,7 +197,7 @@ public Response importNotebook(String req) {
     }
     notebookServer.broadcastNote(newNote);
     notebookServer.broadcastNoteList();
-    return new JsonResponse<>(Status.CREATED, "", newNote.getId() ).build();
+    return new JsonResponse<>(Status.CREATED, "", newNote.getId()).build();
   }
   
   /**
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
index 42dc8787d06..e1c6d50e2a7 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
@@ -337,23 +337,24 @@ public void testExportNotebook() throws IOException {
     LOG.info("testNotebookExport \n" + get.getResponseBodyAsString());
     assertThat("test notebook export method:", get, isAllowed());
 
-    Map resp = gson.fromJson(get.getResponseBodyAsString(), new TypeToken>() {
-    }.getType());
+    Map resp =
+        gson.fromJson(get.getResponseBodyAsString(),
+            new TypeToken>() {}.getType());
 
-    String exportJSON =  (String) resp.get("body");
+    String exportJSON = (String) resp.get("body");
     assertNotNull("Can not find new notejson", exportJSON);
     LOG.info("export JSON:=" + exportJSON);
     ZeppelinServer.notebook.removeNote(sourceNoteID);
     get.releaseConnection();
 
   }
-  
+
   @Test
   public void testImportNotebook() throws IOException {
-	Map resp;
-	String noteName="source note for import";
+    Map resp;
+    String noteName = "source note for import";
     LOG.info("testImortNotebook");
-    //create test notebook
+    // create test notebook
     Note note = ZeppelinServer.notebook.createNote();
     assertNotNull("can't create new note", note);
     note.setName(noteName);
@@ -366,36 +367,39 @@ public void testImportNotebook() throws IOException {
     String sourceNoteID = note.getId();
     // get note content as JSON
     String oldJson = getNoteContent(sourceNoteID);
-    //call notebook put
-    PutMethod importPut = httpPut("/notebook/import/" , oldJson);
+    // call notebook put
+    PutMethod importPut = httpPut("/notebook/import/", oldJson);
     assertThat(importPut, isCreated());
-    resp = gson.fromJson(importPut.getResponseBodyAsString(), new TypeToken>(){}.getType());
+    resp =
+        gson.fromJson(importPut.getResponseBodyAsString(),
+            new TypeToken>() {}.getType());
     String importId = (String) resp.get("body");
-   
+
     assertNotNull("Did not get back a notebook id in body", importId);
-    Note newNote=ZeppelinServer.notebook.getNote(importId);
+    Note newNote = ZeppelinServer.notebook.getNote(importId);
     assertEquals("Compare note names", noteName, newNote.getName());
-    assertEquals("Compare paragraphs count", note.getParagraphs().size(), newNote.getParagraphs().size());
-    //cleanup
+    assertEquals("Compare paragraphs count", note.getParagraphs().size(), newNote.getParagraphs()
+        .size());
+    // cleanup
     ZeppelinServer.notebook.removeNote(note.getId());
     ZeppelinServer.notebook.removeNote(newNote.getId());
     importPut.releaseConnection();
   }
 
-	private String getNoteContent(String id) throws IOException {
-		GetMethod get = httpGet("/notebook/export/" + id);
-		assertThat(get, isAllowed());
-		get.addRequestHeader("Origin", "http://localhost");
-		Map resp = gson.fromJson(get.getResponseBodyAsString(),
-				new TypeToken>() {
-				}.getType());
-		assertEquals(200, get.getStatusCode());
-		String body = resp.get("body").toString();
-		// System.out.println("Body is " + body);
-		get.releaseConnection();
-		return body;
-	}
-  
+  private String getNoteContent(String id) throws IOException {
+    GetMethod get = httpGet("/notebook/export/" + id);
+    assertThat(get, isAllowed());
+    get.addRequestHeader("Origin", "http://localhost");
+    Map resp =
+        gson.fromJson(get.getResponseBodyAsString(),
+            new TypeToken>() {}.getType());
+    assertEquals(200, get.getStatusCode());
+    String body = resp.get("body").toString();
+    // System.out.println("Body is " + body);
+    get.releaseConnection();
+    return body;
+  }
+
   private void testDeleteNotebook(String notebookId) throws IOException {
 
     DeleteMethod delete = httpDelete(("/notebook/" + notebookId));

From 6c19668c535c66867fb8b941dda4878d4b6e8149 Mon Sep 17 00:00:00 2001
From: Ramaswamy Devarajan 
Date: Sun, 10 Jan 2016 19:10:13 -0800
Subject: [PATCH 05/12] Changed http put to Http post for REST import

---
 .../java/org/apache/zeppelin/rest/NotebookRestApi.java |  2 +-
 .../org/apache/zeppelin/rest/ZeppelinRestApiTest.java  | 10 +++++-----
 2 files changed, 6 insertions(+), 6 deletions(-)

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 dfe7ab6c3ab..d05a8076e66 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
@@ -173,7 +173,7 @@ public Response exportNoteBook(@PathParam("id") String noteId) {
    * @return JSON with new note ID
    * @throws IOException
    */
-  @PUT
+  @POST
   @Path("import")
   public Response importNotebook(String req) {
     GsonBuilder gsonBuilder = new GsonBuilder();
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
index e1c6d50e2a7..d8049cc6b80 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
@@ -367,11 +367,11 @@ public void testImportNotebook() throws IOException {
     String sourceNoteID = note.getId();
     // get note content as JSON
     String oldJson = getNoteContent(sourceNoteID);
-    // call notebook put
-    PutMethod importPut = httpPut("/notebook/import/", oldJson);
-    assertThat(importPut, isCreated());
+    // call notebook post
+    PostMethod importPost = httpPost("/notebook/import/", oldJson);
+    assertThat(importPost, isCreated());
     resp =
-        gson.fromJson(importPut.getResponseBodyAsString(),
+        gson.fromJson(importPost.getResponseBodyAsString(),
             new TypeToken>() {}.getType());
     String importId = (String) resp.get("body");
 
@@ -383,7 +383,7 @@ public void testImportNotebook() throws IOException {
     // cleanup
     ZeppelinServer.notebook.removeNote(note.getId());
     ZeppelinServer.notebook.removeNote(newNote.getId());
-    importPut.releaseConnection();
+    importPost.releaseConnection();
   }
 
   private String getNoteContent(String id) throws IOException {

From 7351f3196384afe9868f92c12381f5f715c97996 Mon Sep 17 00:00:00 2001
From: Ramaswamy Devarajan 
Date: Sun, 10 Jan 2016 21:29:13 -0800
Subject: [PATCH 06/12] Moved export/import methods to Notebook.java

---
 .../apache/zeppelin/rest/NotebookRestApi.java | 34 ++----------
 .../apache/zeppelin/notebook/Notebook.java    | 52 +++++++++++++++++++
 2 files changed, 57 insertions(+), 29 deletions(-)

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 d05a8076e66..d9374ae3fdd 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
@@ -157,13 +157,9 @@ public Response getNotebook(@PathParam("notebookId") String notebookId) throws I
    */
   @GET
   @Path("export/{id}")
-  public Response exportNoteBook(@PathParam("id") String noteId) {
-    GsonBuilder gsonBuilder = new GsonBuilder();
-    gsonBuilder.setPrettyPrinting();
-    Gson gson = gsonBuilder.create();
-    Note note = notebook.getNote(noteId);
-    String json = gson.toJson(note);
-    return new JsonResponse(Status.OK, "", json).build();
+  public Response exportNoteBook(@PathParam("id") String noteId) throws IOException {
+    String exportJson = notebook.exportNote(noteId);
+    return new JsonResponse(Status.OK, "", exportJson).build();
   }
 
   /**
@@ -175,28 +171,8 @@ public Response exportNoteBook(@PathParam("id") String noteId) {
    */
   @POST
   @Path("import")
-  public Response importNotebook(String req) {
-    GsonBuilder gsonBuilder = new GsonBuilder();
-    gsonBuilder.setPrettyPrinting();
-    Gson gson = gsonBuilder.create();
-    JsonReader reader = new JsonReader(new StringReader(req));
-    reader.setLenient(true);
-    Note newNote;
-    try {
-      Note oldNote = gson.fromJson(reader, Note.class);
-      newNote = notebook.createNote();
-      newNote.setName(oldNote.getName());
-      List paragraphs = oldNote.getParagraphs();
-      for (Paragraph p : paragraphs) {
-        newNote.addCloneParagraph(p);
-      }
-
-      newNote.persist();
-    } catch (IOException e) {
-      return new JsonResponse(Status.INTERNAL_SERVER_ERROR).build();
-    }
-    notebookServer.broadcastNote(newNote);
-    notebookServer.broadcastNoteList();
+  public Response importNotebook(String req) throws IOException {
+    Note newNote = notebook.importNote(req, null);
     return new JsonResponse<>(Status.CREATED, "", newNote.getId()).build();
   }
   
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
index 6d08e7b352f..b1b79be9178 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
@@ -18,6 +18,7 @@
 package org.apache.zeppelin.notebook;
 
 import java.io.IOException;
+import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -54,6 +55,9 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.stream.JsonReader;
 /**
  * Collection of Notes.
  */
@@ -150,6 +154,54 @@ public Note createNote(List interpreterIds) throws IOException {
     note.persist();
     return note;
   }
+  
+  /**
+   * Export existing note.
+   * @param noteId - the note ID to clone
+   * @return Note JSON
+   * @throws IOException
+   */
+  public String exportNote(String noteId) throws IOException {
+    GsonBuilder gsonBuilder = new GsonBuilder();
+    gsonBuilder.setPrettyPrinting();
+    Gson gson = gsonBuilder.create();
+    Note note = getNote(noteId);
+    return gson.toJson(note);
+  }
+
+  /**
+   * import JSON as a new note.
+   * @param sourceJSON - the note JSON to import
+   * @param noteName - the name of the new note
+   * @return notebook ID
+   * @throws IOException
+   */
+  public Note importNote(String sourceJson, String noteName) throws IOException {
+    GsonBuilder gsonBuilder = new GsonBuilder();
+    gsonBuilder.setPrettyPrinting();
+    Gson gson = gsonBuilder.create();
+    JsonReader reader = new JsonReader(new StringReader(sourceJson));
+    reader.setLenient(true);
+    Note newNote;
+    try {
+      Note oldNote = gson.fromJson(reader, Note.class);
+      newNote = createNote();
+      if (noteName != null)
+        newNote.setName(noteName);
+      else
+        newNote.setName(oldNote.getName());
+      List paragraphs = oldNote.getParagraphs();
+      for (Paragraph p : paragraphs) {
+        newNote.addCloneParagraph(p);
+      }
+
+      newNote.persist();
+    } catch (IOException e) {
+      throw new IOException(e);
+    }
+    
+    return newNote;
+  }
 
   /**
    * Clone existing note.

From db8b016beea9b1a59abbf769c5c614134070a378 Mon Sep 17 00:00:00 2001
From: Ramaswamy Devarajan 
Date: Sun, 10 Jan 2016 22:06:19 -0800
Subject: [PATCH 07/12] added note not found check for export

---
 .../main/java/org/apache/zeppelin/notebook/Notebook.java   | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
index b1b79be9178..ac2f26225fc 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
@@ -159,13 +159,16 @@ public Note createNote(List interpreterIds) throws IOException {
    * Export existing note.
    * @param noteId - the note ID to clone
    * @return Note JSON
-   * @throws IOException
+   * @throws IOException, IllegalArgumentException
    */
-  public String exportNote(String noteId) throws IOException {
+  public String exportNote(String noteId) throws IOException, IllegalArgumentException {
     GsonBuilder gsonBuilder = new GsonBuilder();
     gsonBuilder.setPrettyPrinting();
     Gson gson = gsonBuilder.create();
     Note note = getNote(noteId);
+    if (note == null) {
+      throw new IllegalArgumentException(noteId + "not found");
+    }
     return gson.toJson(note);
   }
 

From db6a5800b75eddfc9defa49da69aa6a8995c1815 Mon Sep 17 00:00:00 2001
From: swakrish 
Date: Wed, 13 Jan 2016 11:00:24 -0800
Subject: [PATCH 08/12] changed HTTP Put to POST in the docs

---
 docs/rest-api/rest-notebook.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/rest-api/rest-notebook.md b/docs/rest-api/rest-notebook.md
index 097caf59aa5..63371ac9d39 100644
--- a/docs/rest-api/rest-notebook.md
+++ b/docs/rest-api/rest-notebook.md
@@ -835,7 +835,7 @@ limitations under the License.
     
     
       Description
-      This ```PUT``` method imports a notebook from the notebook JSON
+      This ```POST``` method imports a notebook from the notebook JSON
       
     
     

From e928c1450ed5de1732f84a1840fd5bde302669c4 Mon Sep 17 00:00:00 2001
From: swakrish 
Date: Wed, 13 Jan 2016 11:02:30 -0800
Subject: [PATCH 09/12] changed doc to make it http post

---
 docs/rest-api/rest-notebook.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/docs/rest-api/rest-notebook.md b/docs/rest-api/rest-notebook.md
index 63371ac9d39..a1e8de61fac 100644
--- a/docs/rest-api/rest-notebook.md
+++ b/docs/rest-api/rest-notebook.md
@@ -835,7 +835,7 @@ limitations under the License.
     
     
       Description
-      This ```POST``` method imports a notebook from the notebook JSON
+      This ```POST``` method imports a notebook from the notebook JSON input
       
     
     

From e282958b40b4601d0ee61b33d2e7e8d9d04e9177 Mon Sep 17 00:00:00 2001
From: swakrish 
Date: Sat, 16 Jan 2016 10:57:11 -0800
Subject: [PATCH 10/12] Changed websocket import to use common code

---
 .../zeppelin/socket/NotebookServer.java       | 53 +++----------------
 1 file changed, 6 insertions(+), 47 deletions(-)

diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
index 3dfdca3cd8d..cc7ce7bd04a 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
@@ -494,56 +494,15 @@ private void cloneNote(NotebookSocket conn, Notebook notebook, Message fromMessa
 
   protected Note importNote(NotebookSocket conn, Notebook notebook, Message fromMessage)
       throws IOException {
-
-    Note note = notebook.createNote();
+    Note note = null;
     if (fromMessage != null) {
       String noteName = (String) ((Map) fromMessage.get("notebook")).get("name");
-      if (noteName == null || noteName.isEmpty()) {
-        noteName = "Note " + note.getId();
-      }
-      note.setName(noteName);
-      ArrayList paragraphs = ((Map) fromMessage.get("notebook"))
-          .get("paragraphs");
-      if (paragraphs.size() > 0) {
-        for (Map paragraph : paragraphs) {
-          try {
-            Paragraph p = note.addParagraph();
-            String text = (String) paragraph.get("text");
-            p.setText(text);
-            p.setTitle((String) paragraph.get("title"));
-            Map params = (Map) ((Map) paragraph
-                .get("settings")).get("params");
-            Map forms = (Map) ((Map) paragraph
-                .get("settings")).get("forms");
-            if (params != null) {
-              p.settings.setParams(params);
-            }
-            if (forms != null) {
-              p.settings.setForms(forms);
-            }
-            Map result = (Map) paragraph.get("result");
-            if (result != null) {
-              InterpreterResult.Code code = InterpreterResult.Code
-                  .valueOf((String) result.get("code"));
-              InterpreterResult.Type type = InterpreterResult.Type
-                  .valueOf((String) result.get("type"));
-              String msg = (String) result.get("msg");
-              p.setReturn(new InterpreterResult(code, type, msg), null);
-            }
-
-            Map config = (Map) paragraph
-                .get("config");
-            p.setConfig(config);
-          } catch (Exception e) {
-            LOG.error("Exception while setting parameter in paragraph", e);
-          }
-        }
-      }
+      String noteJson = gson.toJson(fromMessage.get("notebook"));
+      note = notebook.importNote(noteJson, noteName);
+      note.persist();
+      broadcastNote(note);
+      broadcastNoteList();
     }
-
-    note.persist();
-    broadcastNote(note);
-    broadcastNoteList();
     return note;
   }
 

From 270e17b338bba8b936f55826f5c3bf2e71f1923c Mon Sep 17 00:00:00 2001
From: swakrish 
Date: Mon, 18 Jan 2016 21:53:05 -0800
Subject: [PATCH 11/12] changed soureJSON to sourceJson

---
 .../src/main/java/org/apache/zeppelin/notebook/Notebook.java    | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
index 7c039df9fdc..0ad1caf7eee 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
@@ -174,7 +174,7 @@ public String exportNote(String noteId) throws IOException, IllegalArgumentExcep
 
   /**
    * import JSON as a new note.
-   * @param sourceJSON - the note JSON to import
+   * @param sourceJson - the note JSON to import
    * @param noteName - the name of the new note
    * @return notebook ID
    * @throws IOException

From 869b48f4284373e3762584055c92b9bb0fe6983c Mon Sep 17 00:00:00 2001
From: swakrish 
Date: Thu, 21 Jan 2016 13:22:45 -0800
Subject: [PATCH 12/12] logging the error

---
 .../src/main/java/org/apache/zeppelin/notebook/Notebook.java | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
index 0ad1caf7eee..e58df0d8f22 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
@@ -167,7 +167,7 @@ public String exportNote(String noteId) throws IOException, IllegalArgumentExcep
     Gson gson = gsonBuilder.create();
     Note note = getNote(noteId);
     if (note == null) {
-      throw new IllegalArgumentException(noteId + "not found");
+      throw new IllegalArgumentException(noteId + " not found");
     }
     return gson.toJson(note);
   }
@@ -200,7 +200,8 @@ public Note importNote(String sourceJson, String noteName) throws IOException {
 
       newNote.persist();
     } catch (IOException e) {
-      throw new IOException(e);
+      logger.error(e.toString(), e);
+      throw e;
     }
     
     return newNote;