You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by pr...@apache.org on 2018/02/14 08:59:38 UTC

zeppelin git commit: [ZEPPELIN-3198] UI should not show Version/GIT Control if the same if not supported

Repository: zeppelin
Updated Branches:
  refs/heads/master fffdf2587 -> 0605aae24


[ZEPPELIN-3198] UI should not show Version/GIT Control if the same if not supported

Currently, UI shows an option for version/GIT Control even when it is not supported by the underlying implementing storage configuration.

It is only after users try to save a commit and get an error "Couldn't checkpoint note revision: possibly storage doesn't support versioning. Please check the logs for more details.".

So, if implementing storage configuration doesn't support git storage, UI should not show those options.

[Improvement]

* [ZEPPELIN-3198](https://issues.apache.org/jira/projects/ZEPPELIN/issues/ZEPPELIN-3198)

On using "org.apache.zeppelin.notebook.repo.GitNotebookRepo"  for `zeppelin.notebook.storage`  user should see revision/version control option, for rest of the others e.g. "FileSystemNotebookRepo" user should not see that option

* Does the licenses files need update? N/A
* Is there breaking changes for older versions? N/A
* Does this needs documentation? N/A

Author: Prabhjyot Singh <pr...@gmail.com>

Closes #2757 from prabhjyotsingh/ZEPPELIN-3198 and squashes the following commits:

1f854e80c [Prabhjyot Singh] check for NotebookRepoSync and fall back
d2e19094d [Prabhjyot Singh] rename isDefaultRepoGit to isRevisionSupportedInDefaultRepo
70abc4420 [Prabhjyot Singh] revert NotebookRepoCommon
e152ec194 [Prabhjyot Singh] rename NotebookGitRepo to NotebookRepoWithVersionControl
987edf05d [Prabhjyot Singh] fix test
580674d9c [Prabhjyot Singh] use {{isRepoGit(0)}}
11baf6f2d [Prabhjyot Singh] refactor into NotebookRepo and NotebookGitRepo
c1d34df26 [Prabhjyot Singh] revert imports
cd7fde105 [Prabhjyot Singh] ZEPPELIN-3198: add isRevisionSupported for NotebookRepo

Change-Id: Ib464af447af49ee9e70da86e0e0f293ef38dd3a1


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

Branch: refs/heads/master
Commit: 0605aae240f00c1c04667756599c0e61e4d8e48a
Parents: fffdf25
Author: Prabhjyot Singh <pr...@gmail.com>
Authored: Mon Feb 12 14:47:44 2018 +0530
Committer: Prabhjyot Singh <pr...@gmail.com>
Committed: Wed Feb 14 14:29:28 2018 +0530

----------------------------------------------------------------------
 .../apache/zeppelin/socket/NotebookServer.java  |  2 +-
 .../src/app/notebook/notebook-actionBar.html    |  2 +-
 .../java/org/apache/zeppelin/notebook/Note.java | 13 +++
 .../org/apache/zeppelin/notebook/Notebook.java  | 34 +++++--
 .../notebook/repo/AzureNotebookRepo.java        | 26 ------
 .../notebook/repo/FileSystemNotebookRepo.java   | 27 +-----
 .../zeppelin/notebook/repo/GitNotebookRepo.java |  3 +-
 .../notebook/repo/MongoNotebookRepo.java        | 28 +-----
 .../zeppelin/notebook/repo/NotebookRepo.java    | 62 -------------
 .../notebook/repo/NotebookRepoSync.java         | 54 +++++++----
 .../repo/NotebookRepoWithVersionControl.java    | 97 ++++++++++++++++++++
 .../zeppelin/notebook/repo/S3NotebookRepo.java  | 26 ------
 .../zeppelin/notebook/repo/VFSNotebookRepo.java | 28 +-----
 .../repo/zeppelinhub/ZeppelinHubRepo.java       |  4 +-
 .../notebook/repo/GitNotebookRepoTest.java      |  2 +-
 .../NotebookRepoSyncInitializationTest.java     |  4 +-
 16 files changed, 184 insertions(+), 228 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/zeppelin-server/src/main/java/org/apache/zeppelin/socket/NotebookServer.java
----------------------------------------------------------------------
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 20d5ba9..d1cf9e5 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
@@ -49,7 +49,7 @@ import org.apache.zeppelin.notebook.NotebookEventListener;
 import org.apache.zeppelin.notebook.NotebookImportDeserializer;
 import org.apache.zeppelin.notebook.Paragraph;
 import org.apache.zeppelin.notebook.ParagraphJobListener;
-import org.apache.zeppelin.notebook.repo.NotebookRepo.Revision;
+import org.apache.zeppelin.notebook.repo.NotebookRepoWithVersionControl.Revision;
 import org.apache.zeppelin.notebook.socket.Message;
 import org.apache.zeppelin.notebook.socket.Message.OP;
 import org.apache.zeppelin.notebook.socket.WatcherMessage;

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/zeppelin-web/src/app/notebook/notebook-actionBar.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/notebook-actionBar.html b/zeppelin-web/src/app/notebook/notebook-actionBar.html
index 9b50e81..f8ff830 100644
--- a/zeppelin-web/src/app/notebook/notebook-actionBar.html
+++ b/zeppelin-web/src/app/notebook/notebook-actionBar.html
@@ -100,7 +100,7 @@ limitations under the License.
       </button>
     </span>
 
-    <span class="labelBtn btn-group" role="group">
+    <span class="labelBtn btn-group" role="group" ng-if="note.config.isRevisionSupported">
       <div class="btn-group" role="group">
         <button type="button"
                 class="btn btn-default btn-xs dropdown-toggle"

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/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 0a8fb12..47aa858 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
@@ -47,6 +47,8 @@ import org.apache.zeppelin.interpreter.InterpreterSetting;
 import org.apache.zeppelin.interpreter.InterpreterSettingManager;
 import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry;
 import org.apache.zeppelin.interpreter.thrift.InterpreterCompletion;
+import org.apache.zeppelin.notebook.repo.NotebookRepoSync;
+import org.apache.zeppelin.notebook.repo.NotebookRepoWithVersionControl;
 import org.apache.zeppelin.notebook.repo.NotebookRepo;
 import org.apache.zeppelin.notebook.utility.IdHashes;
 import org.apache.zeppelin.scheduler.Job;
@@ -301,6 +303,17 @@ public class Note implements ParagraphJobListener, JsonSerializable {
     this.repo = repo;
   }
 
+  void setRevisionSupported(NotebookRepo repo) {
+    if (repo instanceof NotebookRepoSync) {
+      getConfig()
+          .put("isRevisionSupported", ((NotebookRepoSync) repo).isRevisionSupportedInDefaultRepo());
+    } else if (repo instanceof NotebookRepoWithVersionControl) {
+      getConfig().put("isRevisionSupported", true);
+    } else {
+      getConfig().put("isRevisionSupported", false);
+    }
+  }
+
   public void setIndex(SearchService index) {
     this.index = index;
   }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/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 72ea2ac..b500e71 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
@@ -28,7 +28,8 @@ import org.apache.zeppelin.display.AngularObjectRegistry;
 import org.apache.zeppelin.interpreter.*;
 import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry;
 import org.apache.zeppelin.notebook.repo.NotebookRepo;
-import org.apache.zeppelin.notebook.repo.NotebookRepo.Revision;
+import org.apache.zeppelin.notebook.repo.NotebookRepoWithVersionControl;
+import org.apache.zeppelin.notebook.repo.NotebookRepoWithVersionControl.Revision;
 import org.apache.zeppelin.notebook.repo.NotebookRepoSync;
 import org.apache.zeppelin.scheduler.Job;
 import org.apache.zeppelin.scheduler.SchedulerFactory;
@@ -367,22 +368,38 @@ public class Notebook implements NoteEventListener {
 
   public Revision checkpointNote(String noteId, String checkpointMessage,
       AuthenticationInfo subject) throws IOException {
-    return notebookRepo.checkpoint(noteId, checkpointMessage, subject);
+    if (((NotebookRepoSync) notebookRepo).isRevisionSupportedInDefaultRepo()) {
+      return ((NotebookRepoWithVersionControl) notebookRepo).checkpoint(noteId, checkpointMessage, subject);
+    } else {
+      return null;
+
+    }
   }
 
-  public List<Revision> listRevisionHistory(String noteId,
-      AuthenticationInfo subject) {
-    return notebookRepo.revisionHistory(noteId, subject);
+  public List<Revision> listRevisionHistory(String noteId, AuthenticationInfo subject) {
+    if (((NotebookRepoSync) notebookRepo).isRevisionSupportedInDefaultRepo()) {
+      return ((NotebookRepoWithVersionControl) notebookRepo).revisionHistory(noteId, subject);
+    } else {
+      return null;
+    }
   }
 
   public Note setNoteRevision(String noteId, String revisionId, AuthenticationInfo subject)
       throws IOException {
-    return notebookRepo.setNoteRevision(noteId, revisionId, subject);
+    if (((NotebookRepoSync) notebookRepo).isRevisionSupportedInDefaultRepo()) {
+      return ((NotebookRepoWithVersionControl) notebookRepo).setNoteRevision(noteId, revisionId, subject);
+    } else {
+      return null;
+    }
   }
-  
+
   public Note getNoteByRevision(String noteId, String revisionId, AuthenticationInfo subject)
       throws IOException {
-    return notebookRepo.get(noteId, revisionId, subject);
+    if (((NotebookRepoSync) notebookRepo).isRevisionSupportedInDefaultRepo()) {
+      return ((NotebookRepoWithVersionControl) notebookRepo).get(noteId, revisionId, subject);
+    } else {
+      return null;
+    }
   }
 
   public void convertFromSingleResultToMultipleResultsFormat(Note note) {
@@ -478,6 +495,7 @@ public class Notebook implements NoteEventListener {
 
     note.setJobListenerFactory(jobListenerFactory);
     note.setNotebookRepo(notebookRepo);
+    note.setRevisionSupported(notebookRepo);
 
     Map<String, SnapshotAngularObject> angularObjectSnapshot = new HashMap<>();
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java
index 731a3e8..3b01088 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/AzureNotebookRepo.java
@@ -196,26 +196,6 @@ public class AzureNotebookRepo implements NotebookRepo {
   }
 
   @Override
-  public Revision checkpoint(String noteId, String checkpointMsg, AuthenticationInfo subject)
-      throws IOException {
-    // no-op
-    LOG.warn("Checkpoint feature isn't supported in {}", this.getClass().toString());
-    return Revision.EMPTY;
-  }
-
-  @Override
-  public Note get(String noteId, String revId, AuthenticationInfo subject) throws IOException {
-    LOG.warn("Get note revision feature isn't supported in {}", this.getClass().toString());
-    return null;
-  }
-
-  @Override
-  public List<Revision> revisionHistory(String noteId, AuthenticationInfo subject) {
-    LOG.warn("Get Note revisions feature isn't supported in {}", this.getClass().toString());
-    return Collections.emptyList();
-  }
-
-  @Override
   public List<NotebookRepoSettingsInfo> getSettings(AuthenticationInfo subject) {
     LOG.warn("Method not implemented");
     return Collections.emptyList();
@@ -226,10 +206,4 @@ public class AzureNotebookRepo implements NotebookRepo {
     LOG.warn("Method not implemented");
   }
 
-  @Override
-  public Note setNoteRevision(String noteId, String revId, AuthenticationInfo subject)
-      throws IOException {
-    // Auto-generated method stub
-    return null;
-  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/FileSystemNotebookRepo.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/FileSystemNotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/FileSystemNotebookRepo.java
index 32bde37..bfc1178 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/FileSystemNotebookRepo.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/FileSystemNotebookRepo.java
@@ -86,32 +86,6 @@ public class FileSystemNotebookRepo implements NotebookRepo {
   }
 
   @Override
-  public Revision checkpoint(String noteId, String checkpointMsg, AuthenticationInfo subject)
-      throws IOException {
-    LOGGER.warn("checkpoint is not implemented for HdfsNotebookRepo");
-    return null;
-  }
-
-  @Override
-  public Note get(String noteId, String revId, AuthenticationInfo subject) throws IOException {
-    LOGGER.warn("get revId is not implemented for HdfsNotebookRepo");
-    return null;
-  }
-
-  @Override
-  public List<Revision> revisionHistory(String noteId, AuthenticationInfo subject) {
-    LOGGER.warn("revisionHistory is not implemented for HdfsNotebookRepo");
-    return null;
-  }
-
-  @Override
-  public Note setNoteRevision(String noteId, String revId, AuthenticationInfo subject)
-      throws IOException {
-    LOGGER.warn("setNoteRevision is not implemented for HdfsNotebookRepo");
-    return null;
-  }
-
-  @Override
   public List<NotebookRepoSettingsInfo> getSettings(AuthenticationInfo subject) {
     LOGGER.warn("getSettings is not implemented for HdfsNotebookRepo");
     return null;
@@ -121,4 +95,5 @@ public class FileSystemNotebookRepo implements NotebookRepo {
   public void updateSettings(Map<String, String> settings, AuthenticationInfo subject) {
     LOGGER.warn("updateSettings is not implemented for HdfsNotebookRepo");
   }
+
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/GitNotebookRepo.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/GitNotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/GitNotebookRepo.java
index 2ac4c72..829f2c1 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/GitNotebookRepo.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/GitNotebookRepo.java
@@ -52,7 +52,7 @@ import com.google.common.collect.Lists;
  *
  *   TODO(bzz): add default .gitignore
  */
-public class GitNotebookRepo extends VFSNotebookRepo {
+class GitNotebookRepo extends VFSNotebookRepo implements NotebookRepoWithVersionControl {
   private static final Logger LOG = LoggerFactory.getLogger(GitNotebookRepo.class);
 
   private String localPath;
@@ -187,3 +187,4 @@ public class GitNotebookRepo extends VFSNotebookRepo {
   }
 
 }
+

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java
index 376a986..03a0f16 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/MongoNotebookRepo.java
@@ -204,33 +204,6 @@ public class MongoNotebookRepo implements NotebookRepo {
   }
 
   @Override
-  public Revision checkpoint(String noteId, String checkpointMsg, AuthenticationInfo subject)
-      throws IOException {
-    // no-op
-    LOG.warn("Checkpoint feature isn't supported in {}", this.getClass().toString());
-    return Revision.EMPTY;
-  }
-
-  @Override
-  public Note get(String noteId, String revId, AuthenticationInfo subject) throws IOException {
-    LOG.warn("Get note revision feature isn't supported in {}", this.getClass().toString());
-    return null;
-  }
-
-  @Override
-  public List<Revision> revisionHistory(String noteId, AuthenticationInfo subject) {
-    LOG.warn("Get Note revisions feature isn't supported in {}", this.getClass().toString());
-    return Collections.emptyList();
-  }
-
-  @Override
-  public Note setNoteRevision(String noteId, String revId, AuthenticationInfo subject)
-      throws IOException {
-    // Auto-generated method stub
-    return null;
-  }
-
-  @Override
   public List<NotebookRepoSettingsInfo> getSettings(AuthenticationInfo subject) {
     LOG.warn("Method not implemented");
     return Collections.emptyList();
@@ -240,4 +213,5 @@ public class MongoNotebookRepo implements NotebookRepo {
   public void updateSettings(Map<String, String> settings, AuthenticationInfo subject) {
     LOG.warn("Method not implemented");
   }
+
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepo.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepo.java
index 6599d08..3f25dbf 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepo.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepo.java
@@ -74,47 +74,6 @@ public interface NotebookRepo {
    */
 
   /**
-   * chekpoint (set revision) for notebook.
-   * @param noteId Id of the Notebook
-   * @param checkpointMsg message description of the checkpoint
-   * @return Rev
-   * @throws IOException
-   */
-  @ZeppelinApi public Revision checkpoint(String noteId, String checkpointMsg, 
-      AuthenticationInfo subject) throws IOException;
-
-  /**
-   * Get particular revision of the Notebook.
-   * 
-   * @param noteId Id of the Notebook
-   * @param rev revision of the Notebook
-   * @return a Notebook
-   * @throws IOException
-   */
-  @ZeppelinApi public Note get(String noteId, String revId, AuthenticationInfo subject)
-      throws IOException;
-
-  /**
-   * List of revisions of the given Notebook.
-   * 
-   * @param noteId id of the Notebook
-   * @return list of revisions
-   */
-  @ZeppelinApi public List<Revision> revisionHistory(String noteId, AuthenticationInfo subject);
-
-  /**
-   * Set note to particular revision.
-   * 
-   * @param noteId Id of the Notebook
-   * @param rev revision of the Notebook
-   * @return a Notebook
-   * @throws IOException
-   */
-  @ZeppelinApi
-  public Note setNoteRevision(String noteId, String revId, AuthenticationInfo subject)
-      throws IOException;
-
-  /**
    * Get NotebookRepo settings got the given user.
    *
    * @param subject
@@ -130,25 +89,4 @@ public interface NotebookRepo {
    */
   @ZeppelinApi public void updateSettings(Map<String, String> settings, AuthenticationInfo subject);
 
-  /**
-   * Represents the 'Revision' a point in life of the notebook
-   */
-  static class Revision {
-    public static final Revision EMPTY = new Revision(StringUtils.EMPTY, StringUtils.EMPTY, 0);
-    
-    public String id;
-    public String message;
-    public int time;
-    
-    public Revision(String revId, String message, int time) {
-      this.id = revId;
-      this.message = message;
-      this.time = time;
-    }
-
-    public static boolean isEmpty(Revision revision) {
-      return revision == null || EMPTY.equals(revision);
-    }
-  }
-
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java
index 30af83f..a2c9da8 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoSync.java
@@ -17,17 +17,7 @@
 
 package org.apache.zeppelin.notebook.repo;
 
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
+import com.google.common.collect.Lists;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
 import org.apache.zeppelin.notebook.Note;
@@ -38,12 +28,15 @@ import org.apache.zeppelin.user.AuthenticationInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.collect.Lists;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
 
 /**
  * Notebook repository sync with remote storage
  */
-public class NotebookRepoSync implements NotebookRepo {
+public class NotebookRepoSync implements NotebookRepoWithVersionControl {
   private static final Logger LOG = LoggerFactory.getLogger(NotebookRepoSync.class);
   private static final int maxRepoNum = 2;
   private static final String pushKey = "pushNoteIds";
@@ -324,7 +317,7 @@ public class NotebookRepoSync implements NotebookRepo {
     return maxRepoNum;
   }
 
-  NotebookRepo getRepo(int repoIndex) throws IOException {
+  public NotebookRepo getRepo(int repoIndex) throws IOException {
     if (repoIndex < 0 || repoIndex >= getRepoCount()) {
       throw new IOException("Requested storage index " + repoIndex
           + " isn't initialized," + " repository count is " + getRepoCount());
@@ -438,6 +431,21 @@ public class NotebookRepoSync implements NotebookRepo {
     }
   }
 
+  public Boolean isRevisionSupportedInDefaultRepo() {
+    return isRevisionSupportedInRepo(0);
+  }
+
+  public Boolean isRevisionSupportedInRepo(int repoIndex) {
+    try {
+      if (getRepo(repoIndex) instanceof NotebookRepoWithVersionControl) {
+        return true;
+      }
+    } catch (IOException e) {
+      LOG.error("Error getting default repo", e);
+    }
+    return false;
+  }
+
   //checkpoint to all available storages
   @Override
   public Revision checkpoint(String noteId, String checkpointMsg, AuthenticationInfo subject)
@@ -450,7 +458,10 @@ public class NotebookRepoSync implements NotebookRepo {
     Revision rev = null;
     for (int i = 0; i < repoBound; i++) {
       try {
-        allRepoCheckpoints.add(getRepo(i).checkpoint(noteId, checkpointMsg, subject));
+        if (isRevisionSupportedInRepo(i)) {
+          allRepoCheckpoints
+              .add(((NotebookRepoWithVersionControl) getRepo(i)).checkpoint(noteId, checkpointMsg, subject));
+        }
       } catch (IOException e) {
         LOG.warn("Couldn't checkpoint in {} storage with index {} for note {}",
           getRepo(i).getClass().toString(), i, noteId);
@@ -477,7 +488,9 @@ public class NotebookRepoSync implements NotebookRepo {
   public Note get(String noteId, String revId, AuthenticationInfo subject) {
     Note revisionNote = null;
     try {
-      revisionNote = getRepo(0).get(noteId, revId, subject);
+      if (isRevisionSupportedInDefaultRepo()) {
+        revisionNote = ((NotebookRepoWithVersionControl) getRepo(0)).get(noteId, revId, subject);
+      }
     } catch (IOException e) {
       LOG.error("Failed to get revision {} of note {}", revId, noteId, e);
     }
@@ -488,7 +501,9 @@ public class NotebookRepoSync implements NotebookRepo {
   public List<Revision> revisionHistory(String noteId, AuthenticationInfo subject) {
     List<Revision> revisions = Collections.emptyList();
     try {
-      revisions = getRepo(0).revisionHistory(noteId, subject);
+      if (isRevisionSupportedInDefaultRepo()) {
+        revisions = ((NotebookRepoWithVersionControl) getRepo(0)).revisionHistory(noteId, subject);
+      }
     } catch (IOException e) {
       LOG.error("Failed to list revision history", e);
     }
@@ -523,7 +538,9 @@ public class NotebookRepoSync implements NotebookRepo {
     Note currentNote = null, revisionNote = null;
     for (int i = 0; i < repoBound; i++) {
       try {
-        currentNote = getRepo(i).setNoteRevision(noteId, revId, subject);
+        if (isRevisionSupportedInRepo(i)) {
+          currentNote = ((NotebookRepoWithVersionControl) getRepo(i)).setNoteRevision(noteId, revId, subject);
+        }
       } catch (IOException e) {
         // already logged
         currentNote = null;
@@ -535,4 +552,5 @@ public class NotebookRepoSync implements NotebookRepo {
     }
     return revisionNote;
   }
+
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoWithVersionControl.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoWithVersionControl.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoWithVersionControl.java
new file mode 100644
index 0000000..05c846e
--- /dev/null
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/NotebookRepoWithVersionControl.java
@@ -0,0 +1,97 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zeppelin.notebook.repo;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.zeppelin.annotation.ZeppelinApi;
+import org.apache.zeppelin.notebook.Note;
+import org.apache.zeppelin.notebook.NoteInfo;
+import org.apache.zeppelin.user.AuthenticationInfo;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Notebook repository (persistence layer) abstraction
+ */
+public interface NotebookRepoWithVersionControl extends NotebookRepo {
+
+  /**
+   * chekpoint (set revision) for notebook.
+   * @param noteId Id of the Notebook
+   * @param checkpointMsg message description of the checkpoint
+   * @return Rev
+   * @throws IOException
+   */
+  @ZeppelinApi public Revision checkpoint(String noteId, String checkpointMsg,
+                                          AuthenticationInfo subject) throws IOException;
+
+  /**
+   * Get particular revision of the Notebook.
+   * 
+   * @param noteId Id of the Notebook
+   * @param revId revision of the Notebook
+   * @return a Notebook
+   * @throws IOException
+   */
+  @ZeppelinApi public Note get(String noteId, String revId, AuthenticationInfo subject)
+      throws IOException;
+
+  /**
+   * List of revisions of the given Notebook.
+   * 
+   * @param noteId id of the Notebook
+   * @return list of revisions
+   */
+  @ZeppelinApi public List<Revision> revisionHistory(String noteId, AuthenticationInfo subject);
+
+  /**
+   * Set note to particular revision.
+   * 
+   * @param noteId Id of the Notebook
+   * @param revId revision of the Notebook
+   * @return a Notebook
+   * @throws IOException
+   */
+  @ZeppelinApi
+  public Note setNoteRevision(String noteId, String revId, AuthenticationInfo subject)
+      throws IOException;
+
+  /**
+   * Represents the 'Revision' a point in life of the notebook
+   */
+  static class Revision {
+    public static final Revision EMPTY = new Revision(StringUtils.EMPTY, StringUtils.EMPTY, 0);
+    
+    public String id;
+    public String message;
+    public int time;
+    
+    public Revision(String revId, String message, int time) {
+      this.id = revId;
+      this.message = message;
+      this.time = time;
+    }
+
+    public static boolean isEmpty(Revision revision) {
+      return revision == null || EMPTY.equals(revision);
+    }
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java
index 7d64702..c54c48b 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/S3NotebookRepo.java
@@ -277,26 +277,6 @@ public class S3NotebookRepo implements NotebookRepo {
   }
 
   @Override
-  public Revision checkpoint(String noteId, String checkpointMsg, AuthenticationInfo subject)
-      throws IOException {
-    // no-op
-    LOG.warn("Checkpoint feature isn't supported in {}", this.getClass().toString());
-    return Revision.EMPTY;
-  }
-
-  @Override
-  public Note get(String noteId, String revId, AuthenticationInfo subject) throws IOException {
-    LOG.warn("Get note revision feature isn't supported in {}", this.getClass().toString());
-    return null;
-  }
-
-  @Override
-  public List<Revision> revisionHistory(String noteId, AuthenticationInfo subject) {
-    LOG.warn("Get Note revisions feature isn't supported in {}", this.getClass().toString());
-    return Collections.emptyList();
-  }
-
-  @Override
   public List<NotebookRepoSettingsInfo> getSettings(AuthenticationInfo subject) {
     LOG.warn("Method not implemented");
     return Collections.emptyList();
@@ -307,10 +287,4 @@ public class S3NotebookRepo implements NotebookRepo {
     LOG.warn("Method not implemented");
   }
 
-  @Override
-  public Note setNoteRevision(String noteId, String revId, AuthenticationInfo subject)
-      throws IOException {
-    // Auto-generated method stub
-    return null;
-  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java
index 481ea3d..bd0d4b2 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/VFSNotebookRepo.java
@@ -239,26 +239,6 @@ public class VFSNotebookRepo implements NotebookRepo {
   }
 
   @Override
-  public Revision checkpoint(String noteId, String checkpointMsg, AuthenticationInfo subject)
-      throws IOException {
-    // no-op
-    LOG.warn("Checkpoint feature isn't supported in {}", this.getClass().toString());
-    return Revision.EMPTY;
-  }
-
-  @Override
-  public Note get(String noteId, String revId, AuthenticationInfo subject) throws IOException {
-    LOG.warn("Get note revision feature isn't supported in {}", this.getClass().toString());
-    return null;
-  }
-
-  @Override
-  public List<Revision> revisionHistory(String noteId, AuthenticationInfo subject) {
-    LOG.warn("Get Note revisions feature isn't supported in {}", this.getClass().toString());
-    return Collections.emptyList();
-  }
-
-  @Override
   public List<NotebookRepoSettingsInfo> getSettings(AuthenticationInfo subject) {
     NotebookRepoSettingsInfo repoSetting = NotebookRepoSettingsInfo.newInstance();
     List<NotebookRepoSettingsInfo> settings = Lists.newArrayList();
@@ -296,11 +276,5 @@ public class VFSNotebookRepo implements NotebookRepo {
     }
   }
 
-  @Override
-  public Note setNoteRevision(String noteId, String revId, AuthenticationInfo subject)
-      throws IOException {
-    // Auto-generated method stub
-    return null;
-  }
-
 }
+

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/ZeppelinHubRepo.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/ZeppelinHubRepo.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/ZeppelinHubRepo.java
index 89c1dd1..7c6bd35 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/ZeppelinHubRepo.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/repo/zeppelinhub/ZeppelinHubRepo.java
@@ -27,7 +27,7 @@ import org.apache.commons.lang.StringUtils;
 import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.notebook.Note;
 import org.apache.zeppelin.notebook.NoteInfo;
-import org.apache.zeppelin.notebook.repo.NotebookRepo;
+import org.apache.zeppelin.notebook.repo.NotebookRepoWithVersionControl;
 import org.apache.zeppelin.notebook.repo.NotebookRepoSettingsInfo;
 import org.apache.zeppelin.notebook.repo.zeppelinhub.model.Instance;
 import org.apache.zeppelin.notebook.repo.zeppelinhub.model.UserTokenContainer;
@@ -48,7 +48,7 @@ import com.google.gson.reflect.TypeToken;
 /**
  * ZeppelinHub repo class.
  */
-public class ZeppelinHubRepo implements NotebookRepo {
+public class ZeppelinHubRepo implements NotebookRepoWithVersionControl {
   private static final Logger LOG = LoggerFactory.getLogger(ZeppelinHubRepo.class);
   private static final String DEFAULT_SERVER = "https://www.zeppelinhub.com";
   static final String ZEPPELIN_CONF_PROP_NAME_SERVER = "zeppelinhub.api.address";

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/GitNotebookRepoTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/GitNotebookRepoTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/GitNotebookRepoTest.java
index 72ea439..0ce2a27 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/GitNotebookRepoTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/GitNotebookRepoTest.java
@@ -33,7 +33,7 @@ import org.apache.zeppelin.interpreter.InterpreterFactory;
 import org.apache.zeppelin.notebook.Note;
 import org.apache.zeppelin.notebook.NoteInfo;
 import org.apache.zeppelin.notebook.Paragraph;
-import org.apache.zeppelin.notebook.repo.NotebookRepo.Revision;
+import org.apache.zeppelin.notebook.repo.NotebookRepoWithVersionControl.Revision;
 import org.apache.zeppelin.user.AuthenticationInfo;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.api.errors.GitAPIException;

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/0605aae2/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncInitializationTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncInitializationTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncInitializationTest.java
index 53c052a..a91b196 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncInitializationTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/repo/NotebookRepoSyncInitializationTest.java
@@ -142,7 +142,7 @@ public class NotebookRepoSyncInitializationTest {
     NotebookRepoSync notebookRepoSync = new NotebookRepoSync(conf);
     // check initialization of one default storage
     assertEquals(notebookRepoSync.getRepoCount(), 1);
-    assertTrue(notebookRepoSync.getRepo(0) instanceof VFSNotebookRepo);
+    assertTrue(notebookRepoSync.getRepo(0) instanceof NotebookRepoWithVersionControl);
   }
   
   @Test
@@ -154,6 +154,6 @@ public class NotebookRepoSyncInitializationTest {
     NotebookRepoSync notebookRepoSync = new NotebookRepoSync(conf);
     // check initialization of one default storage instead of invalid one
     assertEquals(notebookRepoSync.getRepoCount(), 1);
-    assertTrue(notebookRepoSync.getRepo(0) instanceof VFSNotebookRepo);
+    assertTrue(notebookRepoSync.getRepo(0) instanceof NotebookRepo);
   }
 }
\ No newline at end of file