Repository: incubator-zeppelin
Updated Branches:
  refs/heads/master d9ac131e1 -> 28d30b4d4


[ZEPPELIN-420] Improve notebook clone behavior

This PR handles two issues with notebook clone behavior.
* If same paragraphs from original notebook and cloned notebook run at the same 
time, both paragraphs can be in `RUNNING` status. And clone notebook's 
paragraph stays in running status until restart Zeppelin server because two 
paragraphs have same paragraph id and job id:
![before1](https://cloud.githubusercontent.com/assets/8503346/11164773/35fba1be-8b3d-11e5-9d70-d49ed1b25bba.gif)

  After:
![after1](https://cloud.githubusercontent.com/assets/8503346/11164844/a6aff5fc-8b3f-11e5-9bb4-72152790db03.gif)

* Copy paragraph status(RUNNING, PENDING):
![before2](https://cloud.githubusercontent.com/assets/8503346/11164793/265029fa-8b3e-11e5-9105-e2bf7f4af07e.gif)

  After:
![after2 
fig](https://cloud.githubusercontent.com/assets/8503346/11164855/25a64938-8b40-11e5-87ba-8f3b6ff492b9.gif)

Author: Mina Lee <[email protected]>

Closes #432 from minahlee/ZEPPELIN-420 and squashes the following commits:

8eb7973 [Mina Lee] [ZEPPELIN-420] Add clone note test
102f8ea [Mina Lee] [ZEPPELIN-420] Improve notebook clone behavior


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

Branch: refs/heads/master
Commit: 28d30b4d47d9e3267ae991ba0bece461a3a83e92
Parents: d9ac131
Author: Mina Lee <[email protected]>
Authored: Sun Nov 15 21:32:59 2015 +0900
Committer: Lee moon soo <[email protected]>
Committed: Wed Nov 18 12:46:59 2015 +0900

----------------------------------------------------------------------
 .../java/org/apache/zeppelin/notebook/Note.java | 29 +++++++++++++++++---
 .../org/apache/zeppelin/notebook/Notebook.java  |  5 ++--
 .../org/apache/zeppelin/notebook/Paragraph.java | 14 +---------
 .../apache/zeppelin/notebook/NotebookTest.java  | 21 ++++++++++++++
 4 files changed, 49 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/28d30b4d/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 033039c..89a72b5 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
@@ -28,9 +28,11 @@ import java.util.Random;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.display.AngularObject;
 import org.apache.zeppelin.display.AngularObjectRegistry;
+import org.apache.zeppelin.display.Input;
 import org.apache.zeppelin.interpreter.Interpreter;
 import org.apache.zeppelin.interpreter.InterpreterException;
 import org.apache.zeppelin.interpreter.InterpreterGroup;
+import org.apache.zeppelin.interpreter.InterpreterResult;
 import org.apache.zeppelin.interpreter.InterpreterSetting;
 import org.apache.zeppelin.notebook.repo.NotebookRepo;
 import org.apache.zeppelin.notebook.utility.IdHashes;
@@ -40,6 +42,8 @@ import org.apache.zeppelin.scheduler.JobListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.gson.Gson;
+
 /**
  * Binded interpreters for a note
  */
@@ -144,13 +148,30 @@ public class Note implements Serializable, JobListener {
   }
 
   /**
-   * Add the paragraph p to the list of paras in note.
+   * Clone paragraph and add it to note.
    *
-   * @param p
+   * @param srcParagraph
    */
-  public void addParagraph(Paragraph p) {
+  public void addCloneParagraph(Paragraph srcParagraph) {
+    Paragraph newParagraph = new Paragraph(this, this, replLoader);
+
+    Map<String, Object> config = new HashMap<>(srcParagraph.getConfig());
+    Map<String, Object> param = new 
HashMap<>(srcParagraph.settings.getParams());
+    Map<String, Input> form = new HashMap<>(srcParagraph.settings.getForms());
+    Gson gson = new Gson();
+    InterpreterResult result = gson.fromJson(
+        gson.toJson(srcParagraph.getReturn()),
+        InterpreterResult.class);
+
+    newParagraph.setConfig(config);
+    newParagraph.settings.setParams(param);
+    newParagraph.settings.setForms(form);
+    newParagraph.setText(srcParagraph.getText());
+    newParagraph.setTitle(srcParagraph.getTitle());
+    newParagraph.setReturn(result, null);
+
     synchronized (paragraphs) {
-      paragraphs.add(p);
+      paragraphs.add(newParagraph);
     }
   }
   

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/28d30b4d/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Notebook.java
----------------------------------------------------------------------
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 770172a..6624310 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
@@ -141,9 +141,8 @@ public class Notebook {
     bindInterpretersToNote(newNote.id(), boundInterpreterSettingsIds);
 
     List<Paragraph> paragraphs = sourceNote.getParagraphs();
-    for (Paragraph para : paragraphs) {
-      Paragraph p = (Paragraph) para.clone();
-      newNote.addParagraph(p);
+    for (Paragraph p : paragraphs) {
+      newNote.addCloneParagraph(p);
     }
     newNote.persist();
     return newNote;

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/28d30b4d/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
----------------------------------------------------------------------
diff --git 
a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java 
b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
index fc3646a..1332f16 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
@@ -276,19 +276,7 @@ public class Paragraph extends Job implements 
Serializable, Cloneable {
 
   @Override
   public Object clone() throws CloneNotSupportedException {
-    Paragraph paraClone = (Paragraph) super.clone();
-    Map<String, Object> config = new HashMap<>(this.getConfig());
-    // Show the editor by default
-    String hideEditorKey = "editorHide";
-    Object object = config.get(hideEditorKey);
-    if (object != null && object == Boolean.TRUE) {
-      config.put(hideEditorKey, Boolean.FALSE);
-    }
-    Map<String, Object> param = new HashMap<>(this.settings.getParams());
-    paraClone.setConfig(config);
-    paraClone.settings.setParams(param);
-    paraClone.setTitle(this.getTitle());
-    paraClone.setText(this.getText());
+    Paragraph paraClone = (Paragraph) this.clone();
     return paraClone;
   }
 }

http://git-wip-us.apache.org/repos/asf/incubator-zeppelin/blob/28d30b4d/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
----------------------------------------------------------------------
diff --git 
a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java 
b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
index faad058..5d887e9 100644
--- 
a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
+++ 
b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/NotebookTest.java
@@ -18,6 +18,7 @@
 package org.apache.zeppelin.notebook;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -222,6 +223,26 @@ public class NotebookTest implements JobListenerFactory{
   }
 
   @Test
+  public void testCloneNote() throws IOException, CloneNotSupportedException,
+      InterruptedException {
+    Note note = notebook.createNote();
+    
note.getNoteReplLoader().setInterpreters(factory.getDefaultInterpreterSettingList());
+
+    final Paragraph p = note.addParagraph();
+    p.setText("hello world");
+    note.runAll();
+    while(p.isTerminated()==false || p.getResult()==null) Thread.yield();
+
+    p.setStatus(Status.RUNNING);
+    Note cloneNote = notebook.cloneNote(note.getId(), "clone note");
+    Paragraph cp = cloneNote.paragraphs.get(0);
+    assertEquals(cp.getStatus(), Status.READY);
+    assertNotEquals(cp.getId(), p.getId());
+    assertEquals(cp.text, p.text);
+    assertEquals(cp.getResult().message(), p.getResult().message());
+  }
+
+  @Test
   public void testAngularObjectRemovalOnNotebookRemove() throws 
InterruptedException,
       IOException {
     // create a note and a paragraph

Reply via email to