zeppelin-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From zjf...@apache.org
Subject [07/16] zeppelin git commit: ZEPPELIN-2619. Save note in ${notename_noteid}.zpln instead of ${noteid}/note.json
Date Thu, 20 Sep 2018 02:42:50 GMT
http://git-wip-us.apache.org/repos/asf/zeppelin/blob/085efeb6/zeppelin-plugins/notebookrepo/git/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-plugins/notebookrepo/git/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java b/zeppelin-plugins/notebookrepo/git/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java
index ec1a2d4..5215027 100644
--- a/zeppelin-plugins/notebookrepo/git/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java
+++ b/zeppelin-plugins/notebookrepo/git/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.zeppelin.notebook.repo;
 
+
 import static com.google.common.truth.Truth.assertThat;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
@@ -27,19 +28,26 @@ import java.io.IOException;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
+
+import com.google.common.io.Files;
+
 import org.apache.commons.io.FileUtils;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
-import org.apache.zeppelin.dep.DependencyResolver;
 import org.apache.zeppelin.display.AngularObjectRegistryListener;
 import org.apache.zeppelin.helium.ApplicationEventListener;
 import org.apache.zeppelin.interpreter.InterpreterFactory;
 import org.apache.zeppelin.interpreter.InterpreterSettingManager;
 import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcessListener;
 import org.apache.zeppelin.notebook.Note;
+import org.apache.zeppelin.notebook.NoteInfo;
 import org.apache.zeppelin.notebook.Notebook;
 import org.apache.zeppelin.notebook.NotebookAuthorization;
 import org.apache.zeppelin.notebook.Paragraph;
+
+import org.apache.zeppelin.notebook.ParagraphJobListener;
+import org.apache.zeppelin.scheduler.Job.Status;
+
 import org.apache.zeppelin.search.SearchService;
 import org.apache.zeppelin.storage.ConfigStorage;
 import org.apache.zeppelin.user.AuthenticationInfo;
@@ -54,7 +62,7 @@ import org.slf4j.LoggerFactory;
 // TODO(zjffdu) move it to zeppelin-zengine
 public class NotebookRepoSyncTest {
 
-  private File mainZepDir;
+  private File ZEPPELIN_HOME;
   private ZeppelinConfiguration conf;
   private File mainNotebookDir;
   private File secNotebookDir;
@@ -62,7 +70,6 @@ public class NotebookRepoSyncTest {
   private NotebookRepoSync notebookRepoSync;
   private InterpreterFactory factory;
   private InterpreterSettingManager interpreterSettingManager;
-  private DependencyResolver depResolver;
   private SearchService search;
   private NotebookAuthorization notebookAuthorization;
   private Credentials credentials;
@@ -71,22 +78,20 @@ public class NotebookRepoSyncTest {
 
   @Before
   public void setUp() throws Exception {
-    String zpath = System.getProperty("java.io.tmpdir")+"/ZeppelinLTest_"+System.currentTimeMillis();
-    mainZepDir = new File(zpath);
-    mainZepDir.mkdirs();
-    new File(mainZepDir, "conf").mkdirs();
-    String mainNotePath = zpath+"/notebook";
-    String secNotePath = mainNotePath + "_secondary";
+    ZEPPELIN_HOME = Files.createTempDir();
+    new File(ZEPPELIN_HOME, "conf").mkdirs();
+    String mainNotePath = ZEPPELIN_HOME.getAbsolutePath() + "/notebook";
+    String secNotePath = ZEPPELIN_HOME.getAbsolutePath() + "/notebook_secondary";
     mainNotebookDir = new File(mainNotePath);
     secNotebookDir = new File(secNotePath);
     mainNotebookDir.mkdirs();
     secNotebookDir.mkdirs();
 
-    System.setProperty(ConfVars.ZEPPELIN_HOME.getVarName(), mainZepDir.getAbsolutePath());
+    System.setProperty(ConfVars.ZEPPELIN_HOME.getVarName(), ZEPPELIN_HOME.getAbsolutePath());
     System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_DIR.getVarName(), mainNotebookDir.getAbsolutePath());
     System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_STORAGE.getVarName(), "org.apache.zeppelin.notebook.repo.VFSNotebookRepo,org.apache.zeppelin.notebook.repo.mock.VFSNotebookRepoMock");
     System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_ONE_WAY_SYNC.getVarName(), "false");
-    System.setProperty(ConfVars.ZEPPELIN_CONFIG_FS_DIR.getVarName(), mainZepDir.getAbsolutePath() + "/conf");
+    System.setProperty(ConfVars.ZEPPELIN_CONFIG_FS_DIR.getVarName(), ZEPPELIN_HOME.getAbsolutePath() + "/conf");
     System.setProperty(ConfVars.ZEPPELIN_PLUGINS_DIR.getVarName(), new File("../../../plugins").getAbsolutePath());
 
     LOG.info("main Note dir : " + mainNotePath);
@@ -95,7 +100,6 @@ public class NotebookRepoSyncTest {
 
     ConfigStorage.reset();
 
-    depResolver = new DependencyResolver(mainZepDir.getAbsolutePath() + "/local-repo");
     interpreterSettingManager = new InterpreterSettingManager(conf,
         mock(AngularObjectRegistryListener.class), mock(RemoteInterpreterProcessListener.class), mock(ApplicationEventListener.class));
     factory = new InterpreterFactory(interpreterSettingManager);
@@ -104,21 +108,14 @@ public class NotebookRepoSyncTest {
     notebookRepoSync = new NotebookRepoSync(conf);
     notebookAuthorization = NotebookAuthorization.init(conf);
     credentials = new Credentials(conf.credentialsPersist(), conf.getCredentialsPath(), null);
-    notebookSync =
-        new Notebook(
-            conf,
-            notebookRepoSync,
-            factory,
-            interpreterSettingManager,
-            search,
-            notebookAuthorization,
-            credentials);
+    notebookSync = new Notebook(conf, notebookRepoSync, factory, interpreterSettingManager, search,
+        notebookAuthorization, credentials);
     anonymous = new AuthenticationInfo("anonymous");
   }
 
   @After
   public void tearDown() throws Exception {
-    delete(mainZepDir);
+    delete(ZEPPELIN_HOME);
   }
 
   @Test
@@ -139,7 +136,7 @@ public class NotebookRepoSyncTest {
     // check that automatically saved on both storages
     assertEquals(1, notebookRepoSync.list(0, anonymous).size());
     assertEquals(1, notebookRepoSync.list(1, anonymous).size());
-    assertEquals(notebookRepoSync.list(0, anonymous).get(0).getId(),notebookRepoSync.list(1, anonymous).get(0).getId());
+    assertEquals(notebookRepoSync.list(0, anonymous).get(0).getId(), notebookRepoSync.list(1, anonymous).get(0).getId());
 
     notebookSync.removeNote(notebookRepoSync.list(0, null).get(0).getId(), anonymous);
   }
@@ -156,7 +153,7 @@ public class NotebookRepoSyncTest {
     /* check that created in both storage systems */
     assertEquals(1, notebookRepoSync.list(0, anonymous).size());
     assertEquals(1, notebookRepoSync.list(1, anonymous).size());
-    assertEquals(notebookRepoSync.list(0, anonymous).get(0).getId(),notebookRepoSync.list(1, anonymous).get(0).getId());
+    assertEquals(notebookRepoSync.list(0, anonymous).get(0).getId(), notebookRepoSync.list(1, anonymous).get(0).getId());
 
     /* remove Note */
     notebookSync.removeNote(notebookRepoSync.list(0, anonymous).get(0).getId(), anonymous);
@@ -171,7 +168,8 @@ public class NotebookRepoSyncTest {
   public void testSyncUpdateMain() throws IOException {
 
     /* create note */
-    Note note = notebookSync.createNote("test", "", anonymous);
+    Note note = notebookSync.createNote("/test", "test", anonymous);
+    note.setInterpreterFactory(mock(InterpreterFactory.class));
     Paragraph p1 = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
     Map config = p1.getConfig();
     config.put("enabled", true);
@@ -183,41 +181,50 @@ public class NotebookRepoSyncTest {
 
     /* new paragraph not yet saved into storages */
     assertEquals(0, notebookRepoSync.get(0,
-        notebookRepoSync.list(0, anonymous).get(0).getId(), anonymous).getParagraphs().size());
+        notebookRepoSync.list(0, anonymous).get(0).getId(),
+        notebookRepoSync.list(0, anonymous).get(0).getPath(), anonymous).getParagraphs().size());
     assertEquals(0, notebookRepoSync.get(1,
-        notebookRepoSync.list(1, anonymous).get(0).getId(), anonymous).getParagraphs().size());
+        notebookRepoSync.list(1, anonymous).get(0).getId(),
+        notebookRepoSync.list(1, anonymous).get(0).getPath(), anonymous).getParagraphs().size());
 
     /* save to storage under index 0 (first storage) */
     notebookRepoSync.save(0, note, anonymous);
 
     /* check paragraph saved to first storage */
     assertEquals(1, notebookRepoSync.get(0,
-        notebookRepoSync.list(0, anonymous).get(0).getId(), anonymous).getParagraphs().size());
+        notebookRepoSync.list(0, anonymous).get(0).getId(),
+        notebookRepoSync.list(0, anonymous).get(0).getPath(),
+        anonymous).getParagraphs().size());
     /* check paragraph isn't saved to second storage */
     assertEquals(0, notebookRepoSync.get(1,
-        notebookRepoSync.list(1, anonymous).get(0).getId(), anonymous).getParagraphs().size());
+        notebookRepoSync.list(1, anonymous).get(0).getId(),
+        notebookRepoSync.list(0, anonymous).get(0).getPath(),
+        anonymous).getParagraphs().size());
     /* apply sync */
     notebookRepoSync.sync(null);
     /* check whether added to second storage */
     assertEquals(1, notebookRepoSync.get(1,
-    notebookRepoSync.list(1, anonymous).get(0).getId(), anonymous).getParagraphs().size());
+        notebookRepoSync.list(1, anonymous).get(0).getId(),
+        notebookRepoSync.list(1, anonymous).get(0).getPath(), anonymous).getParagraphs().size());
     /* check whether same paragraph id */
     assertEquals(p1.getId(), notebookRepoSync.get(0,
-        notebookRepoSync.list(0, anonymous).get(0).getId(), anonymous).getLastParagraph().getId());
+        notebookRepoSync.list(0, anonymous).get(0).getId(),
+        notebookRepoSync.list(0, anonymous).get(0).getPath(), anonymous).getLastParagraph().getId());
     assertEquals(p1.getId(), notebookRepoSync.get(1,
-        notebookRepoSync.list(1, anonymous).get(0).getId(), anonymous).getLastParagraph().getId());
-    notebookRepoSync.remove(note.getId(), anonymous);
+        notebookRepoSync.list(1, anonymous).get(0).getId(),
+        notebookRepoSync.list(1, anonymous).get(0).getPath(), anonymous).getLastParagraph().getId());
+    notebookRepoSync.remove(note.getId(), note.getPath(), anonymous);
   }
 
   @Test
-  public void testSyncOnReloadedList() throws IOException {
+  public void testSyncOnReloadedList() throws Exception {
     /* check that both storage repos are empty */
     assertTrue(notebookRepoSync.getRepoCount() > 1);
     assertEquals(0, notebookRepoSync.list(0, anonymous).size());
     assertEquals(0, notebookRepoSync.list(1, anonymous).size());
 
-    File srcDir = new File("src/test/resources/2A94M5J1Z");
-    File destDir = new File(secNotebookDir + "/2A94M5J1Z");
+    File srcDir = new File("src/test/resources/notebook");
+    File destDir = secNotebookDir;
 
     /* copy manually new notebook into secondary storage repo and check repos */
     try {
@@ -225,13 +232,14 @@ public class NotebookRepoSyncTest {
     } catch (IOException e) {
       LOG.error(e.toString(), e);
     }
+
     assertEquals(0, notebookRepoSync.list(0, anonymous).size());
-    assertEquals(1, notebookRepoSync.list(1, anonymous).size());
+    assertEquals(2, notebookRepoSync.list(1, anonymous).size());
 
     // After reloading notebooks repos should be synchronized
     notebookSync.reloadAllNotes(anonymous);
-    assertEquals(1, notebookRepoSync.list(0, anonymous).size());
-    assertEquals(1, notebookRepoSync.list(1, anonymous).size());
+    assertEquals(2, notebookRepoSync.list(0, anonymous).size());
+    assertEquals(2, notebookRepoSync.list(1, anonymous).size());
   }
 
   @Test
@@ -240,39 +248,32 @@ public class NotebookRepoSyncTest {
     System.setProperty(ConfVars.ZEPPELIN_NOTEBOOK_ONE_WAY_SYNC.getVarName(), "true");
     conf = ZeppelinConfiguration.create();
     notebookRepoSync = new NotebookRepoSync(conf);
-    notebookSync =
-        new Notebook(
-            conf,
-            notebookRepoSync,
-            factory,
-            interpreterSettingManager,
-            search,
-            notebookAuthorization,
-            credentials);
+    notebookSync = new Notebook(conf, notebookRepoSync, factory, interpreterSettingManager, search,
+        notebookAuthorization, credentials);
 
     // check that both storage repos are empty
     assertTrue(notebookRepoSync.getRepoCount() > 1);
     assertEquals(0, notebookRepoSync.list(0, null).size());
     assertEquals(0, notebookRepoSync.list(1, null).size());
 
-    File srcDir = new File("src/test/resources/2A94M5J1Z");
-    File destDir = new File(secNotebookDir + "/2A94M5J1Z");
+    File srcDir = new File("src/test/resources/notebook");
+    File destDir = secNotebookDir;
 
-    // copy manually new notebook into secondary storage repo and check repos
+    /* copy manually new notebook into secondary storage repo and check repos */
     try {
       FileUtils.copyDirectory(srcDir, destDir);
     } catch (IOException e) {
       LOG.error(e.toString(), e);
     }
     assertEquals(0, notebookRepoSync.list(0, null).size());
-    assertEquals(1, notebookRepoSync.list(1, null).size());
+    assertEquals(2, notebookRepoSync.list(1, null).size());
 
     // after reloading the notebook should be wiped from secondary storage
     notebookSync.reloadAllNotes(null);
     assertEquals(0, notebookRepoSync.list(0, null).size());
     assertEquals(0, notebookRepoSync.list(1, null).size());
 
-    destDir = new File(mainNotebookDir + "/2A94M5J1Z");
+    destDir = mainNotebookDir;
 
     // copy manually new notebook into primary storage repo and check repos
     try {
@@ -280,13 +281,13 @@ public class NotebookRepoSyncTest {
     } catch (IOException e) {
       LOG.error(e.toString(), e);
     }
-    assertEquals(1, notebookRepoSync.list(0, null).size());
+    assertEquals(2, notebookRepoSync.list(0, null).size());
     assertEquals(0, notebookRepoSync.list(1, null).size());
 
     // after reloading notebooks repos should be synchronized
     notebookSync.reloadAllNotes(null);
-    assertEquals(1, notebookRepoSync.list(0, null).size());
-    assertEquals(1, notebookRepoSync.list(1, null).size());
+    assertEquals(2, notebookRepoSync.list(0, null).size());
+    assertEquals(2, notebookRepoSync.list(1, null).size());
   }
 
   @Test
@@ -295,15 +296,8 @@ public class NotebookRepoSyncTest {
     ZeppelinConfiguration vConf = ZeppelinConfiguration.create();
 
     NotebookRepoSync vRepoSync = new NotebookRepoSync(vConf);
-    Notebook vNotebookSync =
-        new Notebook(
-            vConf,
-            vRepoSync,
-            factory,
-            interpreterSettingManager,
-            search,
-            notebookAuthorization,
-            credentials);
+    Notebook vNotebookSync = new Notebook(vConf, vRepoSync, factory, interpreterSettingManager, search,
+        notebookAuthorization, credentials);
 
     // one git versioned storage initialized
     assertThat(vRepoSync.getRepoCount()).isEqualTo(1);
@@ -314,15 +308,18 @@ public class NotebookRepoSyncTest {
     // no notes
     assertThat(vRepoSync.list(anonymous).size()).isEqualTo(0);
     // create note
-    Note note = vNotebookSync.createNote("test", "", anonymous);
+    Note note = vNotebookSync.createNote("/test", "test", anonymous);
     assertThat(vRepoSync.list(anonymous).size()).isEqualTo(1);
 
-    String noteId = vRepoSync.list(anonymous).get(0).getId();
+    NoteInfo noteInfo = vRepoSync.list(anonymous).values().iterator().next();
+    String noteId = noteInfo.getId();
+    String notePath = noteInfo.getPath();
     // first checkpoint
-    vRepoSync.checkpoint(noteId, "checkpoint message", anonymous);
-    int vCount = gitRepo.revisionHistory(noteId, anonymous).size();
+    vRepoSync.checkpoint(noteId, notePath, "checkpoint message", anonymous);
+    int vCount = gitRepo.revisionHistory(noteId, notePath, anonymous).size();
     assertThat(vCount).isEqualTo(1);
 
+    note.setInterpreterFactory(mock(InterpreterFactory.class));
     Paragraph p = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
     Map<String, Object> config = p.getConfig();
     config.put("enabled", true);
@@ -331,16 +328,16 @@ public class NotebookRepoSyncTest {
 
     // save and checkpoint again
     vRepoSync.save(note, anonymous);
-    vRepoSync.checkpoint(noteId, "checkpoint message 2", anonymous);
-    assertThat(gitRepo.revisionHistory(noteId, anonymous).size()).isEqualTo(vCount + 1);
-    notebookRepoSync.remove(note.getId(), anonymous);
+    vRepoSync.checkpoint(noteId, notePath, "checkpoint message 2", anonymous);
+    assertThat(gitRepo.revisionHistory(noteId, notePath, anonymous).size()).isEqualTo(vCount + 1);
+    notebookRepoSync.remove(note.getId(), note.getPath(), anonymous);
   }
 
   @Test
   public void testSyncWithAcl() throws IOException {
     /* scenario 1 - note exists with acl on main storage */
     AuthenticationInfo user1 = new AuthenticationInfo("user1");
-    Note note = notebookSync.createNote("test", "", user1);
+    Note note = notebookSync.createNote("/test", "test", user1);
     assertEquals(0, note.getParagraphs().size());
 
     // saved on both storages
@@ -358,6 +355,7 @@ public class NotebookRepoSyncTest {
     assertEquals(0, authInfo.getWriters(note.getId()).size());
 
     /* update note and save on secondary storage */
+    note.setInterpreterFactory(mock(InterpreterFactory.class));
     Paragraph p1 = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
     p1.setText("hello world");
     assertEquals(1, note.getParagraphs().size());
@@ -365,17 +363,20 @@ public class NotebookRepoSyncTest {
 
     /* check paragraph isn't saved into first storage */
     assertEquals(0, notebookRepoSync.get(0,
-        notebookRepoSync.list(0, null).get(0).getId(), null).getParagraphs().size());
+        notebookRepoSync.list(0, null).get(0).getId(),
+        notebookRepoSync.list(0, null).get(0).getPath(), null).getParagraphs().size());
     /* check paragraph is saved into second storage */
     assertEquals(1, notebookRepoSync.get(1,
-        notebookRepoSync.list(1, null).get(0).getId(), null).getParagraphs().size());
+        notebookRepoSync.list(1, null).get(0).getId(),
+        notebookRepoSync.list(1, null).get(0).getPath(), null).getParagraphs().size());
 
     /* now sync by user1 */
     notebookRepoSync.sync(user1);
 
     /* check that note updated and acl are same on main storage*/
     assertEquals(1, notebookRepoSync.get(0,
-        notebookRepoSync.list(0, null).get(0).getId(), null).getParagraphs().size());
+        notebookRepoSync.list(0, null).get(0).getId(),
+        notebookRepoSync.list(0, null).get(0).getPath(), null).getParagraphs().size());
     assertEquals(true, authInfo.isOwner(note.getId(), entity));
     assertEquals(1, authInfo.getOwners(note.getId()).size());
     assertEquals(0, authInfo.getReaders(note.getId()).size());
@@ -384,7 +385,7 @@ public class NotebookRepoSyncTest {
 
     /* scenario 2 - note doesn't exist on main storage */
     /* remove from main storage */
-    notebookRepoSync.remove(0, note.getId(), user1);
+    notebookRepoSync.remove(0, note.getId(), note.getPath(), user1);
     assertEquals(0, notebookRepoSync.list(0, null).size());
     assertEquals(1, notebookRepoSync.list(1, null).size());
     authInfo.removeNote(note.getId());
@@ -407,16 +408,17 @@ public class NotebookRepoSyncTest {
     assertEquals(true, authInfo.isWriter(note.getId(), entity));
   }
 
-  static void delete(File file){
-    if(file.isFile()) file.delete();
-      else if(file.isDirectory()){
-        File [] files = file.listFiles();
-        if(files!=null && files.length>0){
-          for(File f : files){
-            delete(f);
-          }
+  static void delete(File file) {
+    if (file.isFile()) {
+      file.delete();
+    } else if (file.isDirectory()) {
+      File[] files = file.listFiles();
+      if (files != null && files.length > 0) {
+        for (File f : files) {
+          delete(f);
         }
-        file.delete();
       }
+      file.delete();
+    }
   }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/085efeb6/zeppelin-plugins/notebookrepo/git/src/test/resources/2A94M5J1Z/note.json
----------------------------------------------------------------------
diff --git a/zeppelin-plugins/notebookrepo/git/src/test/resources/2A94M5J1Z/note.json b/zeppelin-plugins/notebookrepo/git/src/test/resources/2A94M5J1Z/note.json
deleted file mode 100644
index ff3d52d..0000000
--- a/zeppelin-plugins/notebookrepo/git/src/test/resources/2A94M5J1Z/note.json
+++ /dev/null
@@ -1,369 +0,0 @@
-{
-  "paragraphs": [
-    {
-      "text": "%md\n## Welcome to Zeppelin.\n##### This is a live tutorial, you can run the code yourself. (Shift-Enter to Run)",
-      "config": {
-        "colWidth": 12.0,
-        "graph": {
-          "mode": "table",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [],
-          "values": [],
-          "groups": [],
-          "scatter": {}
-        },
-        "editorHide": true
-      },
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1423836981412_-1007008116",
-      "id": "20150213-231621_168813393",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "HTML",
-            "data": "\u003ch2\u003eWelcome to Zeppelin.\u003c/h2\u003e\n\u003ch5\u003eThis is a live tutorial, you can run the code yourself. (Shift-Enter to Run)\u003c/h5\u003e\n"
-          }
-        ]
-      },
-      "dateCreated": "Feb 13, 2015 11:16:21 PM",
-      "dateStarted": "Apr 1, 2015 9:11:09 PM",
-      "dateFinished": "Apr 1, 2015 9:11:10 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "title": "Load data into table",
-      "text": "import org.apache.commons.io.IOUtils\nimport java.net.URL\nimport java.nio.charset.Charset\n\n// Zeppelin creates and injects sc (SparkContext) and sqlContext (HiveContext or SqlContext)\n// So you don\u0027t need create them manually\n\n// load bank data\nval bankText \u003d sc.parallelize(\n    IOUtils.toString(\n        new URL(\"https://s3.amazonaws.com/apache-zeppelin/tutorial/bank/bank.csv\"),\n        Charset.forName(\"utf8\")).split(\"\\n\"))\n\ncase class Bank(age: Integer, job: String, marital: String, education: String, balance: Integer)\n\nval bank \u003d bankText.map(s \u003d\u003e s.split(\";\")).filter(s \u003d\u003e s(0) !\u003d \"\\\"age\\\"\").map(\n    s \u003d\u003e Bank(s(0).toInt, \n            s(1).replaceAll(\"\\\"\", \"\"),\n            s(2).replaceAll(\"\\\"\", \"\"),\n            s(3).replaceAll(\"\\\"\", \"\"),\n            s(5).replaceAll(\"\\\"\", \"\").toInt\n        )\n).toDF()\nbank.registerTempTable(\"bank\")",
-      "config": {
-        "colWidth": 12.0,
-        "graph": {
-          "mode": "table",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [],
-          "values": [],
-          "groups": [],
-          "scatter": {}
-        },
-        "title": true
-      },
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1423500779206_-1502780787",
-      "id": "20150210-015259_1403135953",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "TEXT",
-            "data": "import org.apache.commons.io.IOUtils\nimport java.net.URL\nimport java.nio.charset.Charset\nbankText: org.apache.spark.rdd.RDD[String] \u003d ParallelCollectionRDD[32] at parallelize at \u003cconsole\u003e:65\ndefined class Bank\nbank: org.apache.spark.sql.DataFrame \u003d [age: int, job: string, marital: string, education: string, balance: int]\n"
-          }
-        ]
-      },
-      "dateCreated": "Feb 10, 2015 1:52:59 AM",
-      "dateStarted": "Jul 3, 2015 1:43:40 PM",
-      "dateFinished": "Jul 3, 2015 1:43:45 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "text": "%sql \nselect age, count(1) value\nfrom bank \nwhere age \u003c 30 \ngroup by age \norder by age",
-      "config": {
-        "colWidth": 4.0,
-        "graph": {
-          "mode": "multiBarChart",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [
-            {
-              "name": "age",
-              "index": 0.0,
-              "aggr": "sum"
-            }
-          ],
-          "values": [
-            {
-              "name": "value",
-              "index": 1.0,
-              "aggr": "sum"
-            }
-          ],
-          "groups": [],
-          "scatter": {
-            "xAxis": {
-              "name": "age",
-              "index": 0.0,
-              "aggr": "sum"
-            },
-            "yAxis": {
-              "name": "value",
-              "index": 1.0,
-              "aggr": "sum"
-            }
-          }
-        }
-      },
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1423500782552_-1439281894",
-      "id": "20150210-015302_1492795503",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "TABLE",
-            "data": "age\tvalue\n19\t4\n20\t3\n21\t7\n22\t9\n23\t20\n24\t24\n25\t44\n26\t77\n27\t94\n28\t103\n29\t97\n"
-          }
-        ]
-      },
-      "dateCreated": "Feb 10, 2015 1:53:02 AM",
-      "dateStarted": "Jul 3, 2015 1:43:17 PM",
-      "dateFinished": "Jul 3, 2015 1:43:23 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "text": "%sql \nselect age, count(1) value \nfrom bank \nwhere age \u003c ${maxAge\u003d30} \ngroup by age \norder by age",
-      "config": {
-        "colWidth": 4.0,
-        "graph": {
-          "mode": "multiBarChart",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [
-            {
-              "name": "age",
-              "index": 0.0,
-              "aggr": "sum"
-            }
-          ],
-          "values": [
-            {
-              "name": "value",
-              "index": 1.0,
-              "aggr": "sum"
-            }
-          ],
-          "groups": [],
-          "scatter": {
-            "xAxis": {
-              "name": "age",
-              "index": 0.0,
-              "aggr": "sum"
-            },
-            "yAxis": {
-              "name": "value",
-              "index": 1.0,
-              "aggr": "sum"
-            }
-          }
-        }
-      },
-      "settings": {
-        "params": {
-          "maxAge": "35"
-        },
-        "forms": {
-          "maxAge": {
-            "name": "maxAge",
-            "defaultValue": "30",
-            "hidden": false
-          }
-        }
-      },
-      "jobName": "paragraph_1423720444030_-1424110477",
-      "id": "20150212-145404_867439529",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "TABLE",
-            "data": "age\tvalue\n19\t4\n20\t3\n21\t7\n22\t9\n23\t20\n24\t24\n25\t44\n26\t77\n27\t94\n28\t103\n29\t97\n30\t150\n31\t199\n32\t224\n33\t186\n34\t231\n"
-          }
-        ]
-      },
-      "dateCreated": "Feb 12, 2015 2:54:04 PM",
-      "dateStarted": "Jul 3, 2015 1:43:28 PM",
-      "dateFinished": "Jul 3, 2015 1:43:29 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "text": "%sql \nselect age, count(1) value \nfrom bank \nwhere marital\u003d\"${marital\u003dsingle,single|divorced|married}\" \ngroup by age \norder by age",
-      "config": {
-        "colWidth": 4.0,
-        "graph": {
-          "mode": "multiBarChart",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [
-            {
-              "name": "age",
-              "index": 0.0,
-              "aggr": "sum"
-            }
-          ],
-          "values": [
-            {
-              "name": "value",
-              "index": 1.0,
-              "aggr": "sum"
-            }
-          ],
-          "groups": [],
-          "scatter": {
-            "xAxis": {
-              "name": "age",
-              "index": 0.0,
-              "aggr": "sum"
-            },
-            "yAxis": {
-              "name": "value",
-              "index": 1.0,
-              "aggr": "sum"
-            }
-          }
-        }
-      },
-      "settings": {
-        "params": {
-          "marital": "single"
-        },
-        "forms": {
-          "marital": {
-            "name": "marital",
-            "defaultValue": "single",
-            "options": [
-              {
-                "value": "single"
-              },
-              {
-                "value": "divorced"
-              },
-              {
-                "value": "married"
-              }
-            ],
-            "hidden": false
-          }
-        }
-      },
-      "jobName": "paragraph_1423836262027_-210588283",
-      "id": "20150213-230422_1600658137",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "TABLE",
-            "data": "age\tvalue\n19\t4\n20\t3\n21\t7\n22\t9\n23\t17\n24\t13\n25\t33\n26\t56\n27\t64\n28\t78\n29\t56\n30\t92\n31\t86\n32\t105\n33\t61\n34\t75\n35\t46\n36\t50\n37\t43\n38\t44\n39\t30\n40\t25\n41\t19\n42\t23\n43\t21\n44\t20\n45\t15\n46\t14\n47\t12\n48\t12\n49\t11\n50\t8\n51\t6\n52\t9\n53\t4\n55\t3\n56\t3\n57\t2\n58\t7\n59\t2\n60\t5\n66\t2\n69\t1\n"
-          }
-        ]
-      },
-      "dateCreated": "Feb 13, 2015 11:04:22 PM",
-      "dateStarted": "Jul 3, 2015 1:43:33 PM",
-      "dateFinished": "Jul 3, 2015 1:43:34 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "text": "%md\n## Congratulations, it\u0027s done.\n##### You can create your own notebook in \u0027Notebook\u0027 menu. Good luck!",
-      "config": {
-        "colWidth": 12.0,
-        "graph": {
-          "mode": "table",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [],
-          "values": [],
-          "groups": [],
-          "scatter": {}
-        },
-        "editorHide": true
-      },
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1423836268492_216498320",
-      "id": "20150213-230428_1231780373",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "HTML",
-            "data": "\u003ch2\u003eCongratulations, it\u0027s done.\u003c/h2\u003e\n\u003ch5\u003eYou can create your own notebook in \u0027Notebook\u0027 menu. Good luck!\u003c/h5\u003e\n"
-          }
-        ]
-      },
-      "dateCreated": "Feb 13, 2015 11:04:28 PM",
-      "dateStarted": "Apr 1, 2015 9:12:18 PM",
-      "dateFinished": "Apr 1, 2015 9:12:18 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "text": "%md\n\nAbout bank data\n\n```\nCitation Request:\n  This dataset is public available for research. The details are described in [Moro et al., 2011]. \n  Please include this citation if you plan to use this database:\n\n  [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n  In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, Guimarães, Portugal, October, 2011. EUROSIS.\n\n  Available at: [pdf] http://hdl.handle.net/1822/14838\n                [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n```",
-      "config": {
-        "colWidth": 12.0,
-        "graph": {
-          "mode": "table",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [],
-          "values": [],
-          "groups": [],
-          "scatter": {}
-        },
-        "editorHide": true
-      },
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1427420818407_872443482",
-      "id": "20150326-214658_12335843",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "HTML",
-            "data": "\u003cp\u003eAbout bank data\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eCitation Request:\n  This dataset is public available for research. The details are described in [Moro et al., 2011]. \n  Please include this citation if you plan to use this database:\n\n  [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n  In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, Guimarães, Portugal, October, 2011. EUROSIS.\n\n  Available at: [pdf] http://hdl.handle.net/1822/14838\n                [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n\u003c/code\u003e\u003c/pre\u003e\n"
-          }
-        ]
-      },
-      "dateCreated": "Mar 26, 2015 9:46:58 PM",
-      "dateStarted": "Jul 3, 2015 1:44:56 PM",
-      "dateFinished": "Jul 3, 2015 1:44:56 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "config": {},
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1435955447812_-158639899",
-      "id": "20150703-133047_853701097",
-      "dateCreated": "Jul 3, 2015 1:30:47 PM",
-      "status": "READY",
-      "progressUpdateIntervalMs": 500
-    }
-  ],
-  "name": "Zeppelin Tutorial",
-  "id": "2A94M5J1Z",
-  "angularObjects": {},
-  "config": {
-    "looknfeel": "default"
-  },
-  "info": {}
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/085efeb6/zeppelin-plugins/notebookrepo/git/src/test/resources/2A94M5J2Z/note.json
----------------------------------------------------------------------
diff --git a/zeppelin-plugins/notebookrepo/git/src/test/resources/2A94M5J2Z/note.json b/zeppelin-plugins/notebookrepo/git/src/test/resources/2A94M5J2Z/note.json
deleted file mode 100644
index 615c29c..0000000
--- a/zeppelin-plugins/notebookrepo/git/src/test/resources/2A94M5J2Z/note.json
+++ /dev/null
@@ -1,95 +0,0 @@
-{
-  "paragraphs": [
-    {
-      "text": "%md\n## Congratulations, it\u0027s done.\n##### You can create your own notebook in \u0027Notebook\u0027 menu. Good luck!",
-      "config": {
-        "colWidth": 12.0,
-        "graph": {
-          "mode": "table",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [],
-          "values": [],
-          "groups": [],
-          "scatter": {}
-        },
-        "editorHide": true
-      },
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1423836268492_216498320",
-      "id": "20150213-230428_1231780373",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "HTML",
-            "data": "\u003ch2\u003eCongratulations, it\u0027s done.\u003c/h2\u003e\n\u003ch5\u003eYou can create your own notebook in \u0027Notebook\u0027 menu. Good luck!\u003c/h5\u003e\n"
-          }
-        ]
-      },
-      "dateCreated": "Feb 13, 2015 11:04:28 PM",
-      "dateStarted": "Apr 1, 2015 9:12:18 PM",
-      "dateFinished": "Apr 1, 2015 9:12:18 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "text": "%md\n\nAbout bank data\n\n```\nCitation Request:\n  This dataset is public available for research. The details are described in [Moro et al., 2011]. \n  Please include this citation if you plan to use this database:\n\n  [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n  In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, Guimarães, Portugal, October, 2011. EUROSIS.\n\n  Available at: [pdf] http://hdl.handle.net/1822/14838\n                [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n```",
-      "config": {
-        "colWidth": 12.0,
-        "graph": {
-          "mode": "table",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [],
-          "values": [],
-          "groups": [],
-          "scatter": {}
-        },
-        "editorHide": true
-      },
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1427420818407_872443482",
-      "id": "20150326-214658_12335843",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "HTML",
-            "data": "\u003cp\u003eAbout bank data\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eCitation Request:\n  This dataset is public available for research. The details are described in [Moro et al., 2011]. \n  Please include this citation if you plan to use this database:\n\n  [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n  In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, Guimarães, Portugal, October, 2011. EUROSIS.\n\n  Available at: [pdf] http://hdl.handle.net/1822/14838\n                [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n\u003c/code\u003e\u003c/pre\u003e\n"
-          }
-        ]
-      },
-      "dateCreated": "Mar 26, 2015 9:46:58 PM",
-      "dateStarted": "Jul 3, 2015 1:44:56 PM",
-      "dateFinished": "Jul 3, 2015 1:44:56 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "config": {},
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1435955447812_-158639899",
-      "id": "20150703-133047_853701097",
-      "dateCreated": "Jul 3, 2015 1:30:47 PM",
-      "status": "READY",
-      "progressUpdateIntervalMs": 500
-    }
-  ],
-  "name": "Sample note - excerpt from Zeppelin Tutorial",
-  "id": "2A94M5J2Z",
-  "angularObjects": {},
-  "config": {
-    "looknfeel": "default"
-  },
-  "info": {}
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/085efeb6/zeppelin-plugins/notebookrepo/git/src/test/resources/notebook/my_project/my_note1_2A94M5J1Z.zpln
----------------------------------------------------------------------
diff --git a/zeppelin-plugins/notebookrepo/git/src/test/resources/notebook/my_project/my_note1_2A94M5J1Z.zpln b/zeppelin-plugins/notebookrepo/git/src/test/resources/notebook/my_project/my_note1_2A94M5J1Z.zpln
new file mode 100644
index 0000000..8d7d2df
--- /dev/null
+++ b/zeppelin-plugins/notebookrepo/git/src/test/resources/notebook/my_project/my_note1_2A94M5J1Z.zpln
@@ -0,0 +1,369 @@
+{
+  "paragraphs": [
+    {
+      "text": "%md\n## Welcome to Zeppelin.\n##### This is a live tutorial, you can run the code yourself. (Shift-Enter to Run)",
+      "config": {
+        "colWidth": 12.0,
+        "graph": {
+          "mode": "table",
+          "height": 300.0,
+          "optionOpen": false,
+          "keys": [],
+          "values": [],
+          "groups": [],
+          "scatter": {}
+        },
+        "editorHide": true
+      },
+      "settings": {
+        "params": {},
+        "forms": {}
+      },
+      "jobName": "paragraph_1423836981412_-1007008116",
+      "id": "20150213-231621_168813393",
+      "results": {
+        "code": "SUCCESS",
+        "msg": [
+          {
+            "type": "HTML",
+            "data": "\u003ch2\u003eWelcome to Zeppelin.\u003c/h2\u003e\n\u003ch5\u003eThis is a live tutorial, you can run the code yourself. (Shift-Enter to Run)\u003c/h5\u003e\n"
+          }
+        ]
+      },
+      "dateCreated": "Feb 13, 2015 11:16:21 PM",
+      "dateStarted": "Apr 1, 2015 9:11:09 PM",
+      "dateFinished": "Apr 1, 2015 9:11:10 PM",
+      "status": "FINISHED",
+      "progressUpdateIntervalMs": 500
+    },
+    {
+      "title": "Load data into table",
+      "text": "import org.apache.commons.io.IOUtils\nimport java.net.URL\nimport java.nio.charset.Charset\n\n// Zeppelin creates and injects sc (SparkContext) and sqlContext (HiveContext or SqlContext)\n// So you don\u0027t need create them manually\n\n// load bank data\nval bankText \u003d sc.parallelize(\n    IOUtils.toString(\n        new URL(\"https://s3.amazonaws.com/apache-zeppelin/tutorial/bank/bank.csv\"),\n        Charset.forName(\"utf8\")).split(\"\\n\"))\n\ncase class Bank(age: Integer, job: String, marital: String, education: String, balance: Integer)\n\nval bank \u003d bankText.map(s \u003d\u003e s.split(\";\")).filter(s \u003d\u003e s(0) !\u003d \"\\\"age\\\"\").map(\n    s \u003d\u003e Bank(s(0).toInt, \n            s(1).replaceAll(\"\\\"\", \"\"),\n            s(2).replaceAll(\"\\\"\", \"\"),\n            s(3).replaceAll(\"\\\"\", \"\"),\n            s(5).replaceAll(\"\\\"\", \"\").toInt\n        )\n).toDF()\nbank.registerTempTable(\"bank\")",
+      "config": {
+        "colWidth": 12.0,
+        "graph": {
+          "mode": "table",
+          "height": 300.0,
+          "optionOpen": false,
+          "keys": [],
+          "values": [],
+          "groups": [],
+          "scatter": {}
+        },
+        "title": true
+      },
+      "settings": {
+        "params": {},
+        "forms": {}
+      },
+      "jobName": "paragraph_1423500779206_-1502780787",
+      "id": "20150210-015259_1403135953",
+      "results": {
+        "code": "SUCCESS",
+        "msg": [
+          {
+            "type": "TEXT",
+            "data": "import org.apache.commons.io.IOUtils\nimport java.net.URL\nimport java.nio.charset.Charset\nbankText: org.apache.spark.rdd.RDD[String] \u003d ParallelCollectionRDD[32] at parallelize at \u003cconsole\u003e:65\ndefined class Bank\nbank: org.apache.spark.sql.DataFrame \u003d [age: int, job: string, marital: string, education: string, balance: int]\n"
+          }
+        ]
+      },
+      "dateCreated": "Feb 10, 2015 1:52:59 AM",
+      "dateStarted": "Jul 3, 2015 1:43:40 PM",
+      "dateFinished": "Jul 3, 2015 1:43:45 PM",
+      "status": "FINISHED",
+      "progressUpdateIntervalMs": 500
+    },
+    {
+      "text": "%sql \nselect age, count(1) value\nfrom bank \nwhere age \u003c 30 \ngroup by age \norder by age",
+      "config": {
+        "colWidth": 4.0,
+        "graph": {
+          "mode": "multiBarChart",
+          "height": 300.0,
+          "optionOpen": false,
+          "keys": [
+            {
+              "name": "age",
+              "index": 0.0,
+              "aggr": "sum"
+            }
+          ],
+          "values": [
+            {
+              "name": "value",
+              "index": 1.0,
+              "aggr": "sum"
+            }
+          ],
+          "groups": [],
+          "scatter": {
+            "xAxis": {
+              "name": "age",
+              "index": 0.0,
+              "aggr": "sum"
+            },
+            "yAxis": {
+              "name": "value",
+              "index": 1.0,
+              "aggr": "sum"
+            }
+          }
+        }
+      },
+      "settings": {
+        "params": {},
+        "forms": {}
+      },
+      "jobName": "paragraph_1423500782552_-1439281894",
+      "id": "20150210-015302_1492795503",
+      "results": {
+        "code": "SUCCESS",
+        "msg": [
+          {
+            "type": "TABLE",
+            "data": "age\tvalue\n19\t4\n20\t3\n21\t7\n22\t9\n23\t20\n24\t24\n25\t44\n26\t77\n27\t94\n28\t103\n29\t97\n"
+          }
+        ]
+      },
+      "dateCreated": "Feb 10, 2015 1:53:02 AM",
+      "dateStarted": "Jul 3, 2015 1:43:17 PM",
+      "dateFinished": "Jul 3, 2015 1:43:23 PM",
+      "status": "FINISHED",
+      "progressUpdateIntervalMs": 500
+    },
+    {
+      "text": "%sql \nselect age, count(1) value \nfrom bank \nwhere age \u003c ${maxAge\u003d30} \ngroup by age \norder by age",
+      "config": {
+        "colWidth": 4.0,
+        "graph": {
+          "mode": "multiBarChart",
+          "height": 300.0,
+          "optionOpen": false,
+          "keys": [
+            {
+              "name": "age",
+              "index": 0.0,
+              "aggr": "sum"
+            }
+          ],
+          "values": [
+            {
+              "name": "value",
+              "index": 1.0,
+              "aggr": "sum"
+            }
+          ],
+          "groups": [],
+          "scatter": {
+            "xAxis": {
+              "name": "age",
+              "index": 0.0,
+              "aggr": "sum"
+            },
+            "yAxis": {
+              "name": "value",
+              "index": 1.0,
+              "aggr": "sum"
+            }
+          }
+        }
+      },
+      "settings": {
+        "params": {
+          "maxAge": "35"
+        },
+        "forms": {
+          "maxAge": {
+            "name": "maxAge",
+            "defaultValue": "30",
+            "hidden": false
+          }
+        }
+      },
+      "jobName": "paragraph_1423720444030_-1424110477",
+      "id": "20150212-145404_867439529",
+      "results": {
+        "code": "SUCCESS",
+        "msg": [
+          {
+            "type": "TABLE",
+            "data": "age\tvalue\n19\t4\n20\t3\n21\t7\n22\t9\n23\t20\n24\t24\n25\t44\n26\t77\n27\t94\n28\t103\n29\t97\n30\t150\n31\t199\n32\t224\n33\t186\n34\t231\n"
+          }
+        ]
+      },
+      "dateCreated": "Feb 12, 2015 2:54:04 PM",
+      "dateStarted": "Jul 3, 2015 1:43:28 PM",
+      "dateFinished": "Jul 3, 2015 1:43:29 PM",
+      "status": "FINISHED",
+      "progressUpdateIntervalMs": 500
+    },
+    {
+      "text": "%sql \nselect age, count(1) value \nfrom bank \nwhere marital\u003d\"${marital\u003dsingle,single|divorced|married}\" \ngroup by age \norder by age",
+      "config": {
+        "colWidth": 4.0,
+        "graph": {
+          "mode": "multiBarChart",
+          "height": 300.0,
+          "optionOpen": false,
+          "keys": [
+            {
+              "name": "age",
+              "index": 0.0,
+              "aggr": "sum"
+            }
+          ],
+          "values": [
+            {
+              "name": "value",
+              "index": 1.0,
+              "aggr": "sum"
+            }
+          ],
+          "groups": [],
+          "scatter": {
+            "xAxis": {
+              "name": "age",
+              "index": 0.0,
+              "aggr": "sum"
+            },
+            "yAxis": {
+              "name": "value",
+              "index": 1.0,
+              "aggr": "sum"
+            }
+          }
+        }
+      },
+      "settings": {
+        "params": {
+          "marital": "single"
+        },
+        "forms": {
+          "marital": {
+            "name": "marital",
+            "defaultValue": "single",
+            "options": [
+              {
+                "value": "single"
+              },
+              {
+                "value": "divorced"
+              },
+              {
+                "value": "married"
+              }
+            ],
+            "hidden": false
+          }
+        }
+      },
+      "jobName": "paragraph_1423836262027_-210588283",
+      "id": "20150213-230422_1600658137",
+      "results": {
+        "code": "SUCCESS",
+        "msg": [
+          {
+            "type": "TABLE",
+            "data": "age\tvalue\n19\t4\n20\t3\n21\t7\n22\t9\n23\t17\n24\t13\n25\t33\n26\t56\n27\t64\n28\t78\n29\t56\n30\t92\n31\t86\n32\t105\n33\t61\n34\t75\n35\t46\n36\t50\n37\t43\n38\t44\n39\t30\n40\t25\n41\t19\n42\t23\n43\t21\n44\t20\n45\t15\n46\t14\n47\t12\n48\t12\n49\t11\n50\t8\n51\t6\n52\t9\n53\t4\n55\t3\n56\t3\n57\t2\n58\t7\n59\t2\n60\t5\n66\t2\n69\t1\n"
+          }
+        ]
+      },
+      "dateCreated": "Feb 13, 2015 11:04:22 PM",
+      "dateStarted": "Jul 3, 2015 1:43:33 PM",
+      "dateFinished": "Jul 3, 2015 1:43:34 PM",
+      "status": "FINISHED",
+      "progressUpdateIntervalMs": 500
+    },
+    {
+      "text": "%md\n## Congratulations, it\u0027s done.\n##### You can create your own notebook in \u0027Notebook\u0027 menu. Good luck!",
+      "config": {
+        "colWidth": 12.0,
+        "graph": {
+          "mode": "table",
+          "height": 300.0,
+          "optionOpen": false,
+          "keys": [],
+          "values": [],
+          "groups": [],
+          "scatter": {}
+        },
+        "editorHide": true
+      },
+      "settings": {
+        "params": {},
+        "forms": {}
+      },
+      "jobName": "paragraph_1423836268492_216498320",
+      "id": "20150213-230428_1231780373",
+      "results": {
+        "code": "SUCCESS",
+        "msg": [
+          {
+            "type": "HTML",
+            "data": "\u003ch2\u003eCongratulations, it\u0027s done.\u003c/h2\u003e\n\u003ch5\u003eYou can create your own notebook in \u0027Notebook\u0027 menu. Good luck!\u003c/h5\u003e\n"
+          }
+        ]
+      },
+      "dateCreated": "Feb 13, 2015 11:04:28 PM",
+      "dateStarted": "Apr 1, 2015 9:12:18 PM",
+      "dateFinished": "Apr 1, 2015 9:12:18 PM",
+      "status": "FINISHED",
+      "progressUpdateIntervalMs": 500
+    },
+    {
+      "text": "%md\n\nAbout bank data\n\n```\nCitation Request:\n  This dataset is public available for research. The details are described in [Moro et al., 2011]. \n  Please include this citation if you plan to use this database:\n\n  [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n  In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, Guimarães, Portugal, October, 2011. EUROSIS.\n\n  Available at: [pdf] http://hdl.handle.net/1822/14838\n                [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n```",
+      "config": {
+        "colWidth": 12.0,
+        "graph": {
+          "mode": "table",
+          "height": 300.0,
+          "optionOpen": false,
+          "keys": [],
+          "values": [],
+          "groups": [],
+          "scatter": {}
+        },
+        "editorHide": true
+      },
+      "settings": {
+        "params": {},
+        "forms": {}
+      },
+      "jobName": "paragraph_1427420818407_872443482",
+      "id": "20150326-214658_12335843",
+      "results": {
+        "code": "SUCCESS",
+        "msg": [
+          {
+            "type": "HTML",
+            "data": "\u003cp\u003eAbout bank data\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eCitation Request:\n  This dataset is public available for research. The details are described in [Moro et al., 2011]. \n  Please include this citation if you plan to use this database:\n\n  [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n  In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, Guimarães, Portugal, October, 2011. EUROSIS.\n\n  Available at: [pdf] http://hdl.handle.net/1822/14838\n                [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n\u003c/code\u003e\u003c/pre\u003e\n"
+          }
+        ]
+      },
+      "dateCreated": "Mar 26, 2015 9:46:58 PM",
+      "dateStarted": "Jul 3, 2015 1:44:56 PM",
+      "dateFinished": "Jul 3, 2015 1:44:56 PM",
+      "status": "FINISHED",
+      "progressUpdateIntervalMs": 500
+    },
+    {
+      "config": {},
+      "settings": {
+        "params": {},
+        "forms": {}
+      },
+      "jobName": "paragraph_1435955447812_-158639899",
+      "id": "20150703-133047_853701097",
+      "dateCreated": "Jul 3, 2015 1:30:47 PM",
+      "status": "READY",
+      "progressUpdateIntervalMs": 500
+    }
+  ],
+  "id": "2A94M5J1Z",
+  "name": "my_note1",
+  "angularObjects": {},
+  "config": {
+    "looknfeel": "default"
+  },
+  "info": {}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/085efeb6/zeppelin-plugins/notebookrepo/git/src/test/resources/notebook/my_project/my_note2_2A94M5J2Z.zpln
----------------------------------------------------------------------
diff --git a/zeppelin-plugins/notebookrepo/git/src/test/resources/notebook/my_project/my_note2_2A94M5J2Z.zpln b/zeppelin-plugins/notebookrepo/git/src/test/resources/notebook/my_project/my_note2_2A94M5J2Z.zpln
new file mode 100644
index 0000000..f7b1b7e
--- /dev/null
+++ b/zeppelin-plugins/notebookrepo/git/src/test/resources/notebook/my_project/my_note2_2A94M5J2Z.zpln
@@ -0,0 +1,95 @@
+{
+  "paragraphs": [
+    {
+      "text": "%md\n## Congratulations, it\u0027s done.\n##### You can create your own notebook in \u0027Notebook\u0027 menu. Good luck!",
+      "config": {
+        "colWidth": 12.0,
+        "graph": {
+          "mode": "table",
+          "height": 300.0,
+          "optionOpen": false,
+          "keys": [],
+          "values": [],
+          "groups": [],
+          "scatter": {}
+        },
+        "editorHide": true
+      },
+      "settings": {
+        "params": {},
+        "forms": {}
+      },
+      "jobName": "paragraph_1423836268492_216498320",
+      "id": "20150213-230428_1231780373",
+      "results": {
+        "code": "SUCCESS",
+        "msg": [
+          {
+            "type": "HTML",
+            "data": "\u003ch2\u003eCongratulations, it\u0027s done.\u003c/h2\u003e\n\u003ch5\u003eYou can create your own notebook in \u0027Notebook\u0027 menu. Good luck!\u003c/h5\u003e\n"
+          }
+        ]
+      },
+      "dateCreated": "Feb 13, 2015 11:04:28 PM",
+      "dateStarted": "Apr 1, 2015 9:12:18 PM",
+      "dateFinished": "Apr 1, 2015 9:12:18 PM",
+      "status": "FINISHED",
+      "progressUpdateIntervalMs": 500
+    },
+    {
+      "text": "%md\n\nAbout bank data\n\n```\nCitation Request:\n  This dataset is public available for research. The details are described in [Moro et al., 2011]. \n  Please include this citation if you plan to use this database:\n\n  [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n  In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, Guimarães, Portugal, October, 2011. EUROSIS.\n\n  Available at: [pdf] http://hdl.handle.net/1822/14838\n                [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n```",
+      "config": {
+        "colWidth": 12.0,
+        "graph": {
+          "mode": "table",
+          "height": 300.0,
+          "optionOpen": false,
+          "keys": [],
+          "values": [],
+          "groups": [],
+          "scatter": {}
+        },
+        "editorHide": true
+      },
+      "settings": {
+        "params": {},
+        "forms": {}
+      },
+      "jobName": "paragraph_1427420818407_872443482",
+      "id": "20150326-214658_12335843",
+      "results": {
+        "code": "SUCCESS",
+        "msg": [
+          {
+            "type": "HTML",
+            "data": "\u003cp\u003eAbout bank data\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eCitation Request:\n  This dataset is public available for research. The details are described in [Moro et al., 2011]. \n  Please include this citation if you plan to use this database:\n\n  [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n  In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, Guimarães, Portugal, October, 2011. EUROSIS.\n\n  Available at: [pdf] http://hdl.handle.net/1822/14838\n                [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n\u003c/code\u003e\u003c/pre\u003e\n"
+          }
+        ]
+      },
+      "dateCreated": "Mar 26, 2015 9:46:58 PM",
+      "dateStarted": "Jul 3, 2015 1:44:56 PM",
+      "dateFinished": "Jul 3, 2015 1:44:56 PM",
+      "status": "FINISHED",
+      "progressUpdateIntervalMs": 500
+    },
+    {
+      "config": {},
+      "settings": {
+        "params": {},
+        "forms": {}
+      },
+      "jobName": "paragraph_1435955447812_-158639899",
+      "id": "20150703-133047_853701097",
+      "dateCreated": "Jul 3, 2015 1:30:47 PM",
+      "status": "READY",
+      "progressUpdateIntervalMs": 500
+    }
+  ],
+  "id": "2A94M5J2Z",
+  "name": "my_note2",
+  "angularObjects": {},
+  "config": {
+    "looknfeel": "default"
+  },
+  "info": {}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/085efeb6/zeppelin-plugins/notebookrepo/github/src/main/java/org/apache/zeppelin/notebook/repo/GitHubNotebookRepo.java
----------------------------------------------------------------------
diff --git a/zeppelin-plugins/notebookrepo/github/src/main/java/org/apache/zeppelin/notebook/repo/GitHubNotebookRepo.java b/zeppelin-plugins/notebookrepo/github/src/main/java/org/apache/zeppelin/notebook/repo/GitHubNotebookRepo.java
index 7d0415b..48131c6 100644
--- a/zeppelin-plugins/notebookrepo/github/src/main/java/org/apache/zeppelin/notebook/repo/GitHubNotebookRepo.java
+++ b/zeppelin-plugins/notebookrepo/github/src/main/java/org/apache/zeppelin/notebook/repo/GitHubNotebookRepo.java
@@ -64,8 +64,11 @@ public class GitHubNotebookRepo extends GitNotebookRepo {
   }
 
   @Override
-  public Revision checkpoint(String pattern, String commitMessage, AuthenticationInfo subject) {
-    Revision revision = super.checkpoint(pattern, commitMessage, subject);
+  public Revision checkpoint(String noteId,
+                             String notePath,
+                             String commitMessage,
+                             AuthenticationInfo subject) throws IOException {
+    Revision revision = super.checkpoint(noteId, notePath, commitMessage, subject);
 
     updateRemoteStream();
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/085efeb6/zeppelin-plugins/notebookrepo/github/src/test/java/org/apache/zeppelin/notebook/repo/GitHubNotebookRepoTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-plugins/notebookrepo/github/src/test/java/org/apache/zeppelin/notebook/repo/GitHubNotebookRepoTest.java b/zeppelin-plugins/notebookrepo/github/src/test/java/org/apache/zeppelin/notebook/repo/GitHubNotebookRepoTest.java
index e331714..071ce47 100644
--- a/zeppelin-plugins/notebookrepo/github/src/test/java/org/apache/zeppelin/notebook/repo/GitHubNotebookRepoTest.java
+++ b/zeppelin-plugins/notebookrepo/github/src/test/java/org/apache/zeppelin/notebook/repo/GitHubNotebookRepoTest.java
@@ -53,6 +53,7 @@ public class GitHubNotebookRepoTest {
   private static final Logger LOG = LoggerFactory.getLogger(GitHubNotebookRepoTest.class);
 
   private static final String TEST_NOTE_ID = "2A94M5J1Z";
+  private static final String TEST_NOTE_PATH = "/my_project/my_note1";
 
   private File remoteZeppelinDir;
   private File localZeppelinDir;
@@ -86,16 +87,10 @@ public class GitHubNotebookRepoTest {
 
     File notebookDir = new File(localNotebooksDir);
     notebookDir.mkdirs();
-
-    // Copy the test notebook directory from the test/resources/2A94M5J1Z folder to the fake remote Git directory
-    String remoteTestNoteDir = Joiner.on(File.separator).join(remoteNotebooksDir, TEST_NOTE_ID);
+    
     FileUtils.copyDirectory(
-            new File(
-              GitHubNotebookRepoTest.class.getResource(
-                Joiner.on(File.separator).join("", TEST_NOTE_ID)
-              ).getFile()
-            ), new File(remoteTestNoteDir)
-    );
+        new File(GitHubNotebookRepoTest.class.getResource("/notebook").getFile()),
+        new File(remoteNotebooksDir));
 
     // Create the fake remote Git repository
     Repository remoteRepository = new FileRepository(Joiner.on(File.separator).join(remoteNotebooksDir, ".git"));
@@ -140,7 +135,7 @@ public class GitHubNotebookRepoTest {
    * Test the case when the Notebook repository is created, it pulls the latest changes from the remote repository
    */
   public void pullChangesFromRemoteRepositoryOnLoadingNotebook() throws IOException, GitAPIException {
-    NotebookRepoWithVersionControl.Revision firstHistoryRevision = gitHubNotebookRepo.revisionHistory(TEST_NOTE_ID, null).get(0);
+    NotebookRepoWithVersionControl.Revision firstHistoryRevision = gitHubNotebookRepo.revisionHistory(TEST_NOTE_ID, TEST_NOTE_PATH, null).get(0);
 
     assert(this.firstCommitRevision.getName().equals(firstHistoryRevision.id));
   }
@@ -155,11 +150,11 @@ public class GitHubNotebookRepoTest {
     RevCommit secondCommitRevision = remoteGit.commit().setMessage("Second commit from remote repository").call();
 
     // Add a new paragraph to the local repository
-    addParagraphToNotebook(TEST_NOTE_ID);
+    addParagraphToNotebook();
 
     // Commit and push the changes to remote repository
     NotebookRepoWithVersionControl.Revision thirdCommitRevision = gitHubNotebookRepo.checkpoint(
-            TEST_NOTE_ID, "Third commit from local repository", null);
+            TEST_NOTE_ID, TEST_NOTE_PATH, "Third commit from local repository", null);
 
     // Check all the commits as seen from the local repository. The commits are ordered chronologically. The last
     // commit is the first in the commit logs.
@@ -183,11 +178,11 @@ public class GitHubNotebookRepoTest {
    */
   public void pushLocalChangesToRemoteRepositoryOnCheckpointing() throws IOException, GitAPIException {
     // Add a new paragraph to the local repository
-    addParagraphToNotebook(TEST_NOTE_ID);
+    addParagraphToNotebook();
 
     // Commit and push the changes to remote repository
     NotebookRepoWithVersionControl.Revision secondCommitRevision = gitHubNotebookRepo.checkpoint(
-            TEST_NOTE_ID, "Second commit from local repository", null);
+            TEST_NOTE_ID, TEST_NOTE_PATH, "Second commit from local repository", null);
 
     // Check all the commits as seen from the remote repository. The commits are ordered chronologically. The last
     // commit is the first in the commit logs.
@@ -199,8 +194,8 @@ public class GitHubNotebookRepoTest {
     assert(firstCommitRevision.getName().equals(revisions.next().getName()));
   }
 
-  private void addParagraphToNotebook(String noteId) throws IOException {
-    Note note = gitHubNotebookRepo.get(TEST_NOTE_ID, null);
+  private void addParagraphToNotebook() throws IOException {
+    Note note = gitHubNotebookRepo.get(TEST_NOTE_ID, TEST_NOTE_PATH, null);
     note.setInterpreterFactory(mock(InterpreterFactory.class));
     Paragraph paragraph = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
     paragraph.setText("%md text");

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/085efeb6/zeppelin-plugins/notebookrepo/github/src/test/resources/2A94M5J1Z/note.json
----------------------------------------------------------------------
diff --git a/zeppelin-plugins/notebookrepo/github/src/test/resources/2A94M5J1Z/note.json b/zeppelin-plugins/notebookrepo/github/src/test/resources/2A94M5J1Z/note.json
deleted file mode 100644
index ff3d52d..0000000
--- a/zeppelin-plugins/notebookrepo/github/src/test/resources/2A94M5J1Z/note.json
+++ /dev/null
@@ -1,369 +0,0 @@
-{
-  "paragraphs": [
-    {
-      "text": "%md\n## Welcome to Zeppelin.\n##### This is a live tutorial, you can run the code yourself. (Shift-Enter to Run)",
-      "config": {
-        "colWidth": 12.0,
-        "graph": {
-          "mode": "table",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [],
-          "values": [],
-          "groups": [],
-          "scatter": {}
-        },
-        "editorHide": true
-      },
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1423836981412_-1007008116",
-      "id": "20150213-231621_168813393",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "HTML",
-            "data": "\u003ch2\u003eWelcome to Zeppelin.\u003c/h2\u003e\n\u003ch5\u003eThis is a live tutorial, you can run the code yourself. (Shift-Enter to Run)\u003c/h5\u003e\n"
-          }
-        ]
-      },
-      "dateCreated": "Feb 13, 2015 11:16:21 PM",
-      "dateStarted": "Apr 1, 2015 9:11:09 PM",
-      "dateFinished": "Apr 1, 2015 9:11:10 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "title": "Load data into table",
-      "text": "import org.apache.commons.io.IOUtils\nimport java.net.URL\nimport java.nio.charset.Charset\n\n// Zeppelin creates and injects sc (SparkContext) and sqlContext (HiveContext or SqlContext)\n// So you don\u0027t need create them manually\n\n// load bank data\nval bankText \u003d sc.parallelize(\n    IOUtils.toString(\n        new URL(\"https://s3.amazonaws.com/apache-zeppelin/tutorial/bank/bank.csv\"),\n        Charset.forName(\"utf8\")).split(\"\\n\"))\n\ncase class Bank(age: Integer, job: String, marital: String, education: String, balance: Integer)\n\nval bank \u003d bankText.map(s \u003d\u003e s.split(\";\")).filter(s \u003d\u003e s(0) !\u003d \"\\\"age\\\"\").map(\n    s \u003d\u003e Bank(s(0).toInt, \n            s(1).replaceAll(\"\\\"\", \"\"),\n            s(2).replaceAll(\"\\\"\", \"\"),\n            s(3).replaceAll(\"\\\"\", \"\"),\n            s(5).replaceAll(\"\\\"\", \"\").toInt\n        )\n).toDF()\nbank.registerTempTable(\"bank\")",
-      "config": {
-        "colWidth": 12.0,
-        "graph": {
-          "mode": "table",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [],
-          "values": [],
-          "groups": [],
-          "scatter": {}
-        },
-        "title": true
-      },
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1423500779206_-1502780787",
-      "id": "20150210-015259_1403135953",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "TEXT",
-            "data": "import org.apache.commons.io.IOUtils\nimport java.net.URL\nimport java.nio.charset.Charset\nbankText: org.apache.spark.rdd.RDD[String] \u003d ParallelCollectionRDD[32] at parallelize at \u003cconsole\u003e:65\ndefined class Bank\nbank: org.apache.spark.sql.DataFrame \u003d [age: int, job: string, marital: string, education: string, balance: int]\n"
-          }
-        ]
-      },
-      "dateCreated": "Feb 10, 2015 1:52:59 AM",
-      "dateStarted": "Jul 3, 2015 1:43:40 PM",
-      "dateFinished": "Jul 3, 2015 1:43:45 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "text": "%sql \nselect age, count(1) value\nfrom bank \nwhere age \u003c 30 \ngroup by age \norder by age",
-      "config": {
-        "colWidth": 4.0,
-        "graph": {
-          "mode": "multiBarChart",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [
-            {
-              "name": "age",
-              "index": 0.0,
-              "aggr": "sum"
-            }
-          ],
-          "values": [
-            {
-              "name": "value",
-              "index": 1.0,
-              "aggr": "sum"
-            }
-          ],
-          "groups": [],
-          "scatter": {
-            "xAxis": {
-              "name": "age",
-              "index": 0.0,
-              "aggr": "sum"
-            },
-            "yAxis": {
-              "name": "value",
-              "index": 1.0,
-              "aggr": "sum"
-            }
-          }
-        }
-      },
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1423500782552_-1439281894",
-      "id": "20150210-015302_1492795503",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "TABLE",
-            "data": "age\tvalue\n19\t4\n20\t3\n21\t7\n22\t9\n23\t20\n24\t24\n25\t44\n26\t77\n27\t94\n28\t103\n29\t97\n"
-          }
-        ]
-      },
-      "dateCreated": "Feb 10, 2015 1:53:02 AM",
-      "dateStarted": "Jul 3, 2015 1:43:17 PM",
-      "dateFinished": "Jul 3, 2015 1:43:23 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "text": "%sql \nselect age, count(1) value \nfrom bank \nwhere age \u003c ${maxAge\u003d30} \ngroup by age \norder by age",
-      "config": {
-        "colWidth": 4.0,
-        "graph": {
-          "mode": "multiBarChart",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [
-            {
-              "name": "age",
-              "index": 0.0,
-              "aggr": "sum"
-            }
-          ],
-          "values": [
-            {
-              "name": "value",
-              "index": 1.0,
-              "aggr": "sum"
-            }
-          ],
-          "groups": [],
-          "scatter": {
-            "xAxis": {
-              "name": "age",
-              "index": 0.0,
-              "aggr": "sum"
-            },
-            "yAxis": {
-              "name": "value",
-              "index": 1.0,
-              "aggr": "sum"
-            }
-          }
-        }
-      },
-      "settings": {
-        "params": {
-          "maxAge": "35"
-        },
-        "forms": {
-          "maxAge": {
-            "name": "maxAge",
-            "defaultValue": "30",
-            "hidden": false
-          }
-        }
-      },
-      "jobName": "paragraph_1423720444030_-1424110477",
-      "id": "20150212-145404_867439529",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "TABLE",
-            "data": "age\tvalue\n19\t4\n20\t3\n21\t7\n22\t9\n23\t20\n24\t24\n25\t44\n26\t77\n27\t94\n28\t103\n29\t97\n30\t150\n31\t199\n32\t224\n33\t186\n34\t231\n"
-          }
-        ]
-      },
-      "dateCreated": "Feb 12, 2015 2:54:04 PM",
-      "dateStarted": "Jul 3, 2015 1:43:28 PM",
-      "dateFinished": "Jul 3, 2015 1:43:29 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "text": "%sql \nselect age, count(1) value \nfrom bank \nwhere marital\u003d\"${marital\u003dsingle,single|divorced|married}\" \ngroup by age \norder by age",
-      "config": {
-        "colWidth": 4.0,
-        "graph": {
-          "mode": "multiBarChart",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [
-            {
-              "name": "age",
-              "index": 0.0,
-              "aggr": "sum"
-            }
-          ],
-          "values": [
-            {
-              "name": "value",
-              "index": 1.0,
-              "aggr": "sum"
-            }
-          ],
-          "groups": [],
-          "scatter": {
-            "xAxis": {
-              "name": "age",
-              "index": 0.0,
-              "aggr": "sum"
-            },
-            "yAxis": {
-              "name": "value",
-              "index": 1.0,
-              "aggr": "sum"
-            }
-          }
-        }
-      },
-      "settings": {
-        "params": {
-          "marital": "single"
-        },
-        "forms": {
-          "marital": {
-            "name": "marital",
-            "defaultValue": "single",
-            "options": [
-              {
-                "value": "single"
-              },
-              {
-                "value": "divorced"
-              },
-              {
-                "value": "married"
-              }
-            ],
-            "hidden": false
-          }
-        }
-      },
-      "jobName": "paragraph_1423836262027_-210588283",
-      "id": "20150213-230422_1600658137",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "TABLE",
-            "data": "age\tvalue\n19\t4\n20\t3\n21\t7\n22\t9\n23\t17\n24\t13\n25\t33\n26\t56\n27\t64\n28\t78\n29\t56\n30\t92\n31\t86\n32\t105\n33\t61\n34\t75\n35\t46\n36\t50\n37\t43\n38\t44\n39\t30\n40\t25\n41\t19\n42\t23\n43\t21\n44\t20\n45\t15\n46\t14\n47\t12\n48\t12\n49\t11\n50\t8\n51\t6\n52\t9\n53\t4\n55\t3\n56\t3\n57\t2\n58\t7\n59\t2\n60\t5\n66\t2\n69\t1\n"
-          }
-        ]
-      },
-      "dateCreated": "Feb 13, 2015 11:04:22 PM",
-      "dateStarted": "Jul 3, 2015 1:43:33 PM",
-      "dateFinished": "Jul 3, 2015 1:43:34 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "text": "%md\n## Congratulations, it\u0027s done.\n##### You can create your own notebook in \u0027Notebook\u0027 menu. Good luck!",
-      "config": {
-        "colWidth": 12.0,
-        "graph": {
-          "mode": "table",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [],
-          "values": [],
-          "groups": [],
-          "scatter": {}
-        },
-        "editorHide": true
-      },
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1423836268492_216498320",
-      "id": "20150213-230428_1231780373",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "HTML",
-            "data": "\u003ch2\u003eCongratulations, it\u0027s done.\u003c/h2\u003e\n\u003ch5\u003eYou can create your own notebook in \u0027Notebook\u0027 menu. Good luck!\u003c/h5\u003e\n"
-          }
-        ]
-      },
-      "dateCreated": "Feb 13, 2015 11:04:28 PM",
-      "dateStarted": "Apr 1, 2015 9:12:18 PM",
-      "dateFinished": "Apr 1, 2015 9:12:18 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "text": "%md\n\nAbout bank data\n\n```\nCitation Request:\n  This dataset is public available for research. The details are described in [Moro et al., 2011]. \n  Please include this citation if you plan to use this database:\n\n  [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n  In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, Guimarães, Portugal, October, 2011. EUROSIS.\n\n  Available at: [pdf] http://hdl.handle.net/1822/14838\n                [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n```",
-      "config": {
-        "colWidth": 12.0,
-        "graph": {
-          "mode": "table",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [],
-          "values": [],
-          "groups": [],
-          "scatter": {}
-        },
-        "editorHide": true
-      },
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1427420818407_872443482",
-      "id": "20150326-214658_12335843",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "HTML",
-            "data": "\u003cp\u003eAbout bank data\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eCitation Request:\n  This dataset is public available for research. The details are described in [Moro et al., 2011]. \n  Please include this citation if you plan to use this database:\n\n  [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n  In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, Guimarães, Portugal, October, 2011. EUROSIS.\n\n  Available at: [pdf] http://hdl.handle.net/1822/14838\n                [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n\u003c/code\u003e\u003c/pre\u003e\n"
-          }
-        ]
-      },
-      "dateCreated": "Mar 26, 2015 9:46:58 PM",
-      "dateStarted": "Jul 3, 2015 1:44:56 PM",
-      "dateFinished": "Jul 3, 2015 1:44:56 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "config": {},
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1435955447812_-158639899",
-      "id": "20150703-133047_853701097",
-      "dateCreated": "Jul 3, 2015 1:30:47 PM",
-      "status": "READY",
-      "progressUpdateIntervalMs": 500
-    }
-  ],
-  "name": "Zeppelin Tutorial",
-  "id": "2A94M5J1Z",
-  "angularObjects": {},
-  "config": {
-    "looknfeel": "default"
-  },
-  "info": {}
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/085efeb6/zeppelin-plugins/notebookrepo/github/src/test/resources/2A94M5J2Z/note.json
----------------------------------------------------------------------
diff --git a/zeppelin-plugins/notebookrepo/github/src/test/resources/2A94M5J2Z/note.json b/zeppelin-plugins/notebookrepo/github/src/test/resources/2A94M5J2Z/note.json
deleted file mode 100644
index 615c29c..0000000
--- a/zeppelin-plugins/notebookrepo/github/src/test/resources/2A94M5J2Z/note.json
+++ /dev/null
@@ -1,95 +0,0 @@
-{
-  "paragraphs": [
-    {
-      "text": "%md\n## Congratulations, it\u0027s done.\n##### You can create your own notebook in \u0027Notebook\u0027 menu. Good luck!",
-      "config": {
-        "colWidth": 12.0,
-        "graph": {
-          "mode": "table",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [],
-          "values": [],
-          "groups": [],
-          "scatter": {}
-        },
-        "editorHide": true
-      },
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1423836268492_216498320",
-      "id": "20150213-230428_1231780373",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "HTML",
-            "data": "\u003ch2\u003eCongratulations, it\u0027s done.\u003c/h2\u003e\n\u003ch5\u003eYou can create your own notebook in \u0027Notebook\u0027 menu. Good luck!\u003c/h5\u003e\n"
-          }
-        ]
-      },
-      "dateCreated": "Feb 13, 2015 11:04:28 PM",
-      "dateStarted": "Apr 1, 2015 9:12:18 PM",
-      "dateFinished": "Apr 1, 2015 9:12:18 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "text": "%md\n\nAbout bank data\n\n```\nCitation Request:\n  This dataset is public available for research. The details are described in [Moro et al., 2011]. \n  Please include this citation if you plan to use this database:\n\n  [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n  In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, Guimarães, Portugal, October, 2011. EUROSIS.\n\n  Available at: [pdf] http://hdl.handle.net/1822/14838\n                [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n```",
-      "config": {
-        "colWidth": 12.0,
-        "graph": {
-          "mode": "table",
-          "height": 300.0,
-          "optionOpen": false,
-          "keys": [],
-          "values": [],
-          "groups": [],
-          "scatter": {}
-        },
-        "editorHide": true
-      },
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1427420818407_872443482",
-      "id": "20150326-214658_12335843",
-      "results": {
-        "code": "SUCCESS",
-        "msg": [
-          {
-            "type": "HTML",
-            "data": "\u003cp\u003eAbout bank data\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003eCitation Request:\n  This dataset is public available for research. The details are described in [Moro et al., 2011]. \n  Please include this citation if you plan to use this database:\n\n  [Moro et al., 2011] S. Moro, R. Laureano and P. Cortez. Using Data Mining for Bank Direct Marketing: An Application of the CRISP-DM Methodology. \n  In P. Novais et al. (Eds.), Proceedings of the European Simulation and Modelling Conference - ESM\u00272011, pp. 117-121, Guimarães, Portugal, October, 2011. EUROSIS.\n\n  Available at: [pdf] http://hdl.handle.net/1822/14838\n                [bib] http://www3.dsi.uminho.pt/pcortez/bib/2011-esm-1.txt\n\u003c/code\u003e\u003c/pre\u003e\n"
-          }
-        ]
-      },
-      "dateCreated": "Mar 26, 2015 9:46:58 PM",
-      "dateStarted": "Jul 3, 2015 1:44:56 PM",
-      "dateFinished": "Jul 3, 2015 1:44:56 PM",
-      "status": "FINISHED",
-      "progressUpdateIntervalMs": 500
-    },
-    {
-      "config": {},
-      "settings": {
-        "params": {},
-        "forms": {}
-      },
-      "jobName": "paragraph_1435955447812_-158639899",
-      "id": "20150703-133047_853701097",
-      "dateCreated": "Jul 3, 2015 1:30:47 PM",
-      "status": "READY",
-      "progressUpdateIntervalMs": 500
-    }
-  ],
-  "name": "Sample note - excerpt from Zeppelin Tutorial",
-  "id": "2A94M5J2Z",
-  "angularObjects": {},
-  "config": {
-    "looknfeel": "default"
-  },
-  "info": {}
-}
\ No newline at end of file


Mime
View raw message