You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by zj...@apache.org on 2018/08/09 03:25:11 UTC

[2/2] zeppelin git commit: ZEPPELIN-3595. Remove interpreter binding in backend

ZEPPELIN-3595. Remove interpreter binding in backend

### What is this PR for?

This PR is trying to remove backend of interpreter binding related code in zeppelin server side. The next step is to put default interpreterSetting into note.json.

### What type of PR is it?
[Refactoring]

### Todos
* [ ] - Task

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

### How should this be tested?
* CI pass

### Screenshots (if appropriate)

### Questions:
* Does the licenses files need update? No
* Is there breaking changes for older versions? No
* Does this needs documentation? No

Author: Jeff Zhang <zj...@apache.org>

Closes #3059 from zjffdu/ZEPPELIN-3595 and squashes the following commits:

523a694b4 [Jeff Zhang] ZEPPELIN-3595. Remove interpreter binding in backend


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

Branch: refs/heads/master
Commit: b89666374b3e7c34566bd7f9b530ef9ccc53c6e6
Parents: 1c5b38a
Author: Jeff Zhang <zj...@apache.org>
Authored: Mon Jul 9 17:22:18 2018 +0800
Committer: Jeff Zhang <zj...@apache.org>
Committed: Thu Aug 9 11:25:04 2018 +0800

----------------------------------------------------------------------
 .../notebook/repo/NotebookRepoSyncTest.java     |  10 +-
 .../apache/zeppelin/rest/NotebookRestApi.java   |  34 ------
 .../apache/zeppelin/socket/NotebookServer.java  |  74 +++---------
 .../zeppelin/types/InterpreterSettingsList.java |   8 +-
 .../zeppelin/utils/InterpreterBindingUtils.java |  24 +---
 .../zeppelin/rest/InterpreterRestApiTest.java   |  36 ++----
 .../zeppelin/socket/NotebookServerTest.java     |   2 +-
 .../src/app/notebook/notebook.controller.js     |  10 +-
 .../note-create/note-create.controller.js       |   6 +-
 .../websocket/websocket-message.service.js      |   8 +-
 .../interpreter/InterpreterFactory.java         |  70 ++++--------
 .../interpreter/InterpreterInfoSaving.java      |   1 -
 .../interpreter/InterpreterSettingManager.java  | 112 +++----------------
 .../interpreter/ManagedInterpreterGroup.java    |   1 +
 .../java/org/apache/zeppelin/notebook/Note.java |   8 +-
 .../org/apache/zeppelin/notebook/Notebook.java  |  84 +++++---------
 .../org/apache/zeppelin/notebook/Paragraph.java |   6 +-
 .../zeppelin/notebook/socket/Message.java       |   9 +-
 .../helium/HeliumApplicationFactoryTest.java    |  11 --
 .../interpreter/AbstractInterpreterTest.java    |   2 +-
 .../interpreter/ConfInterpreterTest.java        |  25 ++---
 .../interpreter/InterpreterFactoryTest.java     |  46 +++-----
 .../InterpreterSettingManagerTest.java          |  87 +-------------
 .../interpreter/SparkIntegrationTest.java       |  11 +-
 .../lifecycle/TimeoutLifecycleManagerTest.java  |  10 +-
 .../apache/zeppelin/notebook/FolderTest.java    |   8 +-
 .../zeppelin/notebook/FolderViewTest.java       |   2 +-
 .../org/apache/zeppelin/notebook/NoteTest.java  |  38 +++----
 .../apache/zeppelin/notebook/NotebookTest.java  |  65 +----------
 .../zeppelin/search/LuceneSearchTest.java       |   1 +
 .../src/test/resources/log4j.properties         |   4 +-
 31 files changed, 204 insertions(+), 609 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/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 274c08a..54ce606 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
@@ -139,7 +139,7 @@ public class NotebookRepoSyncTest implements JobListenerFactory {
     assertEquals(0, notebookRepoSync.list(1, anonymous).size());
 
     /* create note */
-    Note note = notebookSync.createNote(anonymous);
+    Note note = notebookSync.createNote("test", anonymous);
 
     // check that automatically saved on both storages
     assertEquals(1, notebookRepoSync.list(0, anonymous).size());
@@ -156,7 +156,7 @@ public class NotebookRepoSyncTest implements JobListenerFactory {
     assertEquals(0, notebookRepoSync.list(0, anonymous).size());
     assertEquals(0, notebookRepoSync.list(1, anonymous).size());
 
-    Note note = notebookSync.createNote(anonymous);
+    Note note = notebookSync.createNote("test", anonymous);
 
     /* check that created in both storage systems */
     assertEquals(1, notebookRepoSync.list(0, anonymous).size());
@@ -176,7 +176,7 @@ public class NotebookRepoSyncTest implements JobListenerFactory {
   public void testSyncUpdateMain() throws IOException {
 
     /* create note */
-    Note note = notebookSync.createNote(anonymous);
+    Note note = notebookSync.createNote("test", anonymous);
     Paragraph p1 = note.addNewParagraph(AuthenticationInfo.ANONYMOUS);
     Map config = p1.getConfig();
     config.put("enabled", true);
@@ -305,7 +305,7 @@ public class NotebookRepoSyncTest implements JobListenerFactory {
     // no notes
     assertThat(vRepoSync.list(anonymous).size()).isEqualTo(0);
     // create note
-    Note note = vNotebookSync.createNote(anonymous);
+    Note note = vNotebookSync.createNote("test", anonymous);
     assertThat(vRepoSync.list(anonymous).size()).isEqualTo(1);
 
     String noteId = vRepoSync.list(anonymous).get(0).getId();
@@ -331,7 +331,7 @@ public class NotebookRepoSyncTest implements JobListenerFactory {
   public void testSyncWithAcl() throws IOException {
     /* scenario 1 - note exists with acl on main storage */
     AuthenticationInfo user1 = new AuthenticationInfo("user1");
-    Note note = notebookSync.createNote(user1);
+    Note note = notebookSync.createNote("test", user1);
     assertEquals(0, note.getParagraphs().size());
 
     // saved on both storages

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
index 08fd637..f23ec0e 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/rest/NotebookRestApi.java
@@ -39,9 +39,7 @@ import org.apache.zeppelin.rest.message.UpdateParagraphRequest;
 import org.apache.zeppelin.search.SearchService;
 import org.apache.zeppelin.server.JsonResponse;
 import org.apache.zeppelin.socket.NotebookServer;
-import org.apache.zeppelin.types.InterpreterSettingsList;
 import org.apache.zeppelin.user.AuthenticationInfo;
-import org.apache.zeppelin.utils.InterpreterBindingUtils;
 import org.apache.zeppelin.utils.SecurityUtils;
 import org.quartz.CronExpression;
 import org.slf4j.Logger;
@@ -274,38 +272,6 @@ public class NotebookRestApi {
     return new JsonResponse<>(Status.OK).build();
   }
 
-  /**
-   * Bind a setting to note.
-   *
-   * @throws IOException
-   */
-  @PUT
-  @Path("interpreter/bind/{noteId}")
-  @ZeppelinApi
-  public Response bind(@PathParam("noteId") String noteId, String req) throws IOException {
-    checkIfUserCanWrite(noteId,
-        "Insufficient privileges you cannot bind any interpreters to this note");
-
-    List<String> settingIdList = gson.fromJson(req, new TypeToken<List<String>>() {}.getType());
-    notebook.bindInterpretersToNote(SecurityUtils.getPrincipal(), noteId, settingIdList);
-    return new JsonResponse<>(Status.OK).build();
-  }
-
-  /**
-   * list bound setting.
-   */
-  @GET
-  @Path("interpreter/bind/{noteId}")
-  @ZeppelinApi
-  public Response bind(@PathParam("noteId") String noteId) {
-    checkIfUserCanRead(noteId, "Insufficient privileges you cannot get any interpreters settings");
-
-    List<InterpreterSettingsList> settingList =
-        InterpreterBindingUtils.getInterpreterBindings(notebook, noteId);
-    notebookServer.broadcastInterpreterBindings(noteId, settingList);
-    return new JsonResponse<>(Status.OK, "", settingList).build();
-  }
-
   @GET
   @Path("/")
   @ZeppelinApi

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/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 e25ccb1..78ff078 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
@@ -367,9 +367,6 @@ public class NotebookServer extends WebSocketServlet
         case GET_INTERPRETER_BINDINGS:
           getInterpreterBindings(conn, messagereceived);
           break;
-        case SAVE_INTERPRETER_BINDINGS:
-          saveInterpreterBindings(conn, messagereceived);
-          break;
         case EDITOR_SETTING:
           getEditorSetting(conn, messagereceived);
           break;
@@ -511,20 +508,6 @@ public class NotebookServer extends WebSocketServlet
     return id;
   }
 
-  private void broadcastToNoteBindedInterpreter(String interpreterGroupId, Message m) {
-    Notebook notebook = notebook();
-    List<Note> notes = notebook.getAllNotes();
-    for (Note note : notes) {
-      List<String> ids = notebook.getInterpreterSettingManager()
-          .getInterpreterBinding(note.getId());
-      for (String id : ids) {
-        if (id.equals(interpreterGroupId)) {
-          broadcast(note.getId(), m);
-        }
-      }
-    }
-  }
-
   public void broadcast(Message m) {
     synchronized (connectedSockets) {
       for (NotebookSocket ns : connectedSockets) {
@@ -634,21 +617,6 @@ public class NotebookServer extends WebSocketServlet
     removeConnectionFromNote(JobManagerService.JOB_MANAGER_PAGE.getKey(), conn);
   }
 
-  public void saveInterpreterBindings(NotebookSocket conn, Message fromMessage) {
-    String noteId = (String) fromMessage.data.get("noteId");
-    try {
-      List<String> settingIdList =
-          gson.fromJson(String.valueOf(fromMessage.data.get("selectedSettingIds")),
-              new TypeToken<ArrayList<String>>() {}.getType());
-      AuthenticationInfo subject = new AuthenticationInfo(fromMessage.principal);
-      notebook().bindInterpretersToNote(subject.getUser(), noteId, settingIdList);
-      broadcastInterpreterBindings(noteId,
-          InterpreterBindingUtils.getInterpreterBindings(notebook(), noteId));
-    } catch (Exception e) {
-      LOG.error("Error while saving interpreter bindings", e);
-    }
-  }
-
   public void getInterpreterBindings(NotebookSocket conn, Message fromMessage) throws IOException {
     String noteId = (String) fromMessage.data.get("noteId");
     List<InterpreterSettingsList> settingList =
@@ -695,10 +663,6 @@ public class NotebookServer extends WebSocketServlet
     broadcast(note.getId(), new Message(OP.NOTE).put("note", note));
   }
 
-  public void broadcastInterpreterBindings(String noteId, List settingList) {
-    broadcast(noteId, new Message(OP.INTERPRETER_BINDINGS).put("interpreterBindings", settingList));
-  }
-
   public void unicastParagraph(Note note, Paragraph p, String user) {
     if (!note.isPersonalizedMode() || p == null || user == null) {
       return;
@@ -1068,19 +1032,10 @@ public class NotebookServer extends WebSocketServlet
     AuthenticationInfo subject = new AuthenticationInfo(message.principal);
 
     try {
-      Note note;
-
-      String defaultInterpreterId = (String) message.get("defaultInterpreterId");
-      if (!StringUtils.isEmpty(defaultInterpreterId)) {
-        List<String> interpreterSettingIds = new LinkedList<>();
-        interpreterSettingIds.add(defaultInterpreterId);
-        for (String interpreterSettingId : notebook.getInterpreterSettingManager().
-            getInterpreterSettingIds()) {
-          if (!interpreterSettingId.equals(defaultInterpreterId)) {
-            interpreterSettingIds.add(interpreterSettingId);
-          }
-        }
-        note = notebook.createNote(interpreterSettingIds, subject);
+      Note note = null;
+      String defaultInterpreterSettingId = (String) message.get("defaultInterpreterGroup");
+      if (defaultInterpreterSettingId != null) {
+        note = notebook.createNote(defaultInterpreterSettingId, subject);
       } else {
         note = notebook.createNote(subject);
       }
@@ -2326,14 +2281,14 @@ public class NotebookServer extends WebSocketServlet
 
     @Override
     public void onUnbindInterpreter(Note note, InterpreterSetting setting) {
-      Notebook notebook = notebookServer.notebook();
-      List<Map<String, Object>> notebookJobs = notebook.getJobListByNoteId(note.getId());
-      Map<String, Object> response = new HashMap<>();
-      response.put("lastResponseUnixTime", System.currentTimeMillis());
-      response.put("jobs", notebookJobs);
-
-      notebookServer.broadcast(JobManagerService.JOB_MANAGER_PAGE.getKey(),
-          new Message(OP.LIST_UPDATE_NOTE_JOBS).put("noteRunningJobs", response));
+//      Notebook notebook = notebookServer.notebook();
+//      List<Map<String, Object>> notebookJobs = notebook.getJobListByNoteId(note.getId());
+//      Map<String, Object> response = new HashMap<>();
+//      response.put("lastResponseUnixTime", System.currentTimeMillis());
+//      response.put("jobs", notebookJobs);
+//
+//      notebookServer.broadcast(JobManagerService.JOB_MANAGER_PAGE.getKey(),
+//          new Message(OP.LIST_UPDATE_NOTE_JOBS).put("noteRunningJobs", response));
     }
   }
 
@@ -2495,7 +2450,7 @@ public class NotebookServer extends WebSocketServlet
       }
 
       List<String> settingIds =
-          notebook.getInterpreterSettingManager().getInterpreterBinding(note.getId());
+          notebook.getInterpreterSettingManager().getSettingIds();
       for (String id : settingIds) {
         if (interpreterGroupId.contains(id)) {
           broadcast(note.getId(),
@@ -2517,7 +2472,8 @@ public class NotebookServer extends WebSocketServlet
     Interpreter interpreter;
 
     try {
-      interpreter = notebook().getInterpreterFactory().getInterpreter(user, noteId, replName);
+      interpreter = notebook().getInterpreterFactory().getInterpreter(user, noteId, replName,
+          notebook().getNote(noteId).getDefaultInterpreterGroup());
       LOG.debug("getEditorSetting for interpreter: {} for paragraph {}", replName, paragraphId);
       resp.put("editor", notebook().getInterpreterSettingManager().
           getEditorSetting(interpreter, user, noteId, replName));

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-server/src/main/java/org/apache/zeppelin/types/InterpreterSettingsList.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/types/InterpreterSettingsList.java b/zeppelin-server/src/main/java/org/apache/zeppelin/types/InterpreterSettingsList.java
index 9f8380f..2e080ea 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/types/InterpreterSettingsList.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/types/InterpreterSettingsList.java
@@ -16,21 +16,21 @@
  */
 package org.apache.zeppelin.types;
 
-import java.util.List;
-
 import org.apache.zeppelin.interpreter.InterpreterInfo;
 
+import java.util.List;
+
 /**
  * InterpreterSetting information for binding.
  */
 public class InterpreterSettingsList {
   private String id;
   private String name;
-  private boolean selected;
   private List<InterpreterInfo> interpreters;
+  private boolean selected;
 
   public InterpreterSettingsList(String id, String name,
-      List<InterpreterInfo> interpreters, boolean selected) {
+                                 List<InterpreterInfo> interpreters, boolean selected) {
     this.id = id;
     this.name = name;
     this.interpreters = interpreters;

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-server/src/main/java/org/apache/zeppelin/utils/InterpreterBindingUtils.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/utils/InterpreterBindingUtils.java b/zeppelin-server/src/main/java/org/apache/zeppelin/utils/InterpreterBindingUtils.java
index a1b954e..3ea2f75 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/utils/InterpreterBindingUtils.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/utils/InterpreterBindingUtils.java
@@ -16,19 +16,19 @@
  */
 package org.apache.zeppelin.utils;
 
-import java.util.LinkedList;
-import java.util.List;
-
 import org.apache.zeppelin.interpreter.InterpreterSetting;
 import org.apache.zeppelin.notebook.Notebook;
 import org.apache.zeppelin.types.InterpreterSettingsList;
 
+import java.util.LinkedList;
+import java.util.List;
+
 /**
  * Utils for interpreter bindings.
  */
 public class InterpreterBindingUtils {
   public static List<InterpreterSettingsList> getInterpreterBindings(Notebook notebook,
-          String noteId) {
+                                                                     String noteId) {
     List<InterpreterSettingsList> settingList = new LinkedList<>();
     List<InterpreterSetting> selectedSettings =
         notebook.getBindedInterpreterSettings(noteId);
@@ -37,22 +37,6 @@ public class InterpreterBindingUtils {
           setting.getInterpreterInfos(), true));
     }
 
-    List<InterpreterSetting> availableSettings = notebook.getInterpreterSettingManager().get();
-    for (InterpreterSetting setting : availableSettings) {
-      boolean selected = false;
-      for (InterpreterSetting selectedSetting : selectedSettings) {
-        if (selectedSetting.getId().equals(setting.getId())) {
-          selected = true;
-          break;
-        }
-      }
-
-      if (!selected) {
-        settingList.add(new InterpreterSettingsList(setting.getId(), setting.getName(),
-            setting.getInterpreterInfos(), false));
-      }
-    }
-
     return settingList;
   }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-server/src/test/java/org/apache/zeppelin/rest/InterpreterRestApiTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/InterpreterRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/InterpreterRestApiTest.java
index 23ffed1..5a0dc9f 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/InterpreterRestApiTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/InterpreterRestApiTest.java
@@ -16,20 +16,22 @@
  */
 package org.apache.zeppelin.rest;
 
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
 import com.google.gson.Gson;
 import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.gson.reflect.TypeToken;
-
 import org.apache.commons.httpclient.methods.DeleteMethod;
 import org.apache.commons.httpclient.methods.GetMethod;
 import org.apache.commons.httpclient.methods.PostMethod;
 import org.apache.commons.httpclient.methods.PutMethod;
+import org.apache.zeppelin.interpreter.InterpreterOption;
+import org.apache.zeppelin.interpreter.InterpreterSetting;
+import org.apache.zeppelin.notebook.Note;
+import org.apache.zeppelin.notebook.Paragraph;
+import org.apache.zeppelin.scheduler.Job.Status;
+import org.apache.zeppelin.server.ZeppelinServer;
+import org.apache.zeppelin.user.AuthenticationInfo;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -42,13 +44,8 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.zeppelin.interpreter.InterpreterOption;
-import org.apache.zeppelin.interpreter.InterpreterSetting;
-import org.apache.zeppelin.notebook.Note;
-import org.apache.zeppelin.notebook.Paragraph;
-import org.apache.zeppelin.scheduler.Job.Status;
-import org.apache.zeppelin.server.ZeppelinServer;
-import org.apache.zeppelin.user.AuthenticationInfo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
 
 /**
  * Zeppelin interpreter rest api tests.
@@ -236,21 +233,6 @@ public class InterpreterRestApiTest extends AbstractTestRestApi {
   }
 
   @Test
-  public void testInterpreterAutoBinding() throws IOException {
-    // when
-    Note note = ZeppelinServer.notebook.createNote(anonymous);
-    GetMethod get = httpGet("/notebook/interpreter/bind/" + note.getId());
-    assertThat(get, isAllowed());
-    get.addRequestHeader("Origin", "http://localhost");
-    JsonArray body = getArrayBodyFieldFromResponse(get.getResponseBodyAsString());
-
-    // then: check interpreter is binded
-    assertTrue(0 < body.size());
-    get.releaseConnection();
-    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
-  }
-
-  @Test
   public void testInterpreterRestart() throws IOException, InterruptedException {
     // when: create new note
     Note note = ZeppelinServer.notebook.createNote(anonymous);

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java
index c23fce7..078dbb2 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/socket/NotebookServerTest.java
@@ -473,7 +473,7 @@ public class NotebookServerTest extends AbstractTestRestApi {
     String defaultInterpreterId = "";
     List<InterpreterSetting> settings = notebook.getInterpreterSettingManager().get();
     if (settings.size() > 1) {
-      defaultInterpreterId = settings.get(1).getId();
+      defaultInterpreterId = settings.get(0).getId();
     }
     // create note from sock1
     notebookServer.onMessage(sock1,

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-web/src/app/notebook/notebook.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/notebook/notebook.controller.js b/zeppelin-web/src/app/notebook/notebook.controller.js
index 6387314..27eefbc 100644
--- a/zeppelin-web/src/app/notebook/notebook.controller.js
+++ b/zeppelin-web/src/app/notebook/notebook.controller.js
@@ -1203,11 +1203,11 @@ function NotebookCtrl($scope, $route, $routeParams, $location, $rootScope,
   };
 
   const isSettingDirty = function() {
-    if (angular.equals($scope.interpreterBindings, $scope.interpreterBindingsOrig)) {
-      return false;
-    } else {
-      return true;
-    }
+    // if (angular.equals($scope.interpreterBindings, $scope.interpreterBindingsOrig)) {
+    //   return false;
+    // } else {
+    return false;
+    // }
   };
 
   const isPermissionsDirty = function() {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-web/src/components/note-create/note-create.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/note-create/note-create.controller.js b/zeppelin-web/src/components/note-create/note-create.controller.js
index a2eb5a6..95b3378 100644
--- a/zeppelin-web/src/components/note-create/note-create.controller.js
+++ b/zeppelin-web/src/components/note-create/note-create.controller.js
@@ -29,11 +29,11 @@ function NoteCreateCtrl($scope, noteListFactory, $routeParams, websocketMsgSrv)
 
   vm.createNote = function() {
     if (!vm.clone) {
-      let defaultInterpreterId = '';
+      let defaultInterpreterGroup = '';
       if ($scope.note.defaultInterpreter !== null) {
-        defaultInterpreterId = $scope.note.defaultInterpreter.id;
+        defaultInterpreterGroup = $scope.note.defaultInterpreter.name;
       }
-      vm.websocketMsgSrv.createNotebook($scope.note.notename, defaultInterpreterId);
+      vm.websocketMsgSrv.createNotebook($scope.note.notename, defaultInterpreterGroup);
       $scope.note.defaultInterpreter = $scope.interpreterSettings[0];
     } else {
       let noteId = $routeParams.noteId;

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-web/src/components/websocket/websocket-message.service.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/components/websocket/websocket-message.service.js b/zeppelin-web/src/components/websocket/websocket-message.service.js
index e60b4e7..95eb5e9 100644
--- a/zeppelin-web/src/components/websocket/websocket-message.service.js
+++ b/zeppelin-web/src/components/websocket/websocket-message.service.js
@@ -23,12 +23,12 @@ function WebsocketMessageService($rootScope, websocketEvents) {
       websocketEvents.sendNewEvent({op: 'GET_HOME_NOTE'});
     },
 
-    createNotebook: function(noteName, defaultInterpreterId) {
+    createNotebook: function(noteName, defaultInterpreterGroup) {
       websocketEvents.sendNewEvent({
         op: 'NEW_NOTE',
         data: {
           name: noteName,
-          defaultInterpreterId: defaultInterpreterId,
+          defaultInterpreterGroup: defaultInterpreterGroup,
         },
       });
     },
@@ -353,8 +353,8 @@ function WebsocketMessageService($rootScope, websocketEvents) {
     },
 
     saveInterpreterBindings: function(noteId, selectedSettingIds) {
-      websocketEvents.sendNewEvent({op: 'SAVE_INTERPRETER_BINDINGS',
-        data: {noteId: noteId, selectedSettingIds: selectedSettingIds}});
+      // websocketEvents.sendNewEvent({op: 'SAVE_INTERPRETER_BINDINGS',
+      //   data: {noteId: noteId, selectedSettingIds: selectedSettingIds}});
     },
 
     listConfigurations: function() {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java
index 20b1c2b..0d76809 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterFactory.java
@@ -27,7 +27,8 @@ import java.util.List;
 /**
  * //TODO(zjffdu) considering to move to InterpreterSettingManager
  *
- * Manage interpreters.
+ * Factory class for creating interpreters.
+ *
  */
 public class InterpreterFactory {
   private static final Logger LOGGER = LoggerFactory.getLogger(InterpreterFactory.class);
@@ -38,72 +39,49 @@ public class InterpreterFactory {
     this.interpreterSettingManager = interpreterSettingManager;
   }
 
-  private InterpreterSetting getInterpreterSettingByGroup(List<InterpreterSetting> settings,
-      String group) {
-
-    Preconditions.checkNotNull(group, "group should be not null");
-    for (InterpreterSetting setting : settings) {
-      if (group.equals(setting.getName())) {
-        return setting;
-      }
-    }
-    return null;
-  }
-
-  public Interpreter getInterpreter(String user, String noteId, String replName)
+  public Interpreter getInterpreter(String user,
+                                    String noteId,
+                                    String replName,
+                                    String defaultInterpreterSetting)
       throws InterpreterNotFoundException {
-    List<InterpreterSetting> settings = interpreterSettingManager.getInterpreterSettings(noteId);
-    InterpreterSetting setting;
-    Interpreter interpreter;
-
-    if (settings == null || settings.size() == 0) {
-      throw new InterpreterNotFoundException("No interpreter is binded to this note: " + noteId);
-    }
 
     if (StringUtils.isBlank(replName)) {
-      // Get the default interpreter of the first interpreter binding
-      InterpreterSetting defaultSetting = settings.get(0);
+      // Get the default interpreter of the defaultInterpreterSetting
+      InterpreterSetting defaultSetting =
+          interpreterSettingManager.getByName(defaultInterpreterSetting);
       return defaultSetting.getDefaultInterpreter(user, noteId);
     }
 
-    String[] replNameSplit = replName.split("\\.");
-    if (replNameSplit.length == 2) {
-      String group = replNameSplit[0];
-      String name = replNameSplit[1];
-      setting = getInterpreterSettingByGroup(settings, group);
+    String[] replNameSplits = replName.split("\\.");
+    if (replNameSplits.length == 2) {
+      String group = replNameSplits[0];
+      String name = replNameSplits[1];
+      InterpreterSetting setting = interpreterSettingManager.getByName(group);
       if (null != setting) {
-        interpreter = setting.getInterpreter(user, noteId, name);
+        Interpreter interpreter = setting.getInterpreter(user, noteId, name);
         if (null != interpreter) {
           return interpreter;
         }
         throw new InterpreterNotFoundException("No such interpreter: " + replName);
       }
-      throw new InterpreterNotFoundException("Interpreter " + group +
-          " is not binded to this note");
-    } else if (replNameSplit.length == 1){
-      // first assume replName is 'name' of interpreter. ('groupName' is ommitted)
-      // search 'name' from first (default) interpreter group
-      // TODO(jl): Handle with noteId to support defaultInterpreter per note.
-      setting = settings.get(0);
-      interpreter = setting.getInterpreter(user, noteId, replName);
+      throw new InterpreterNotFoundException("No interpreter setting named: " + group);
 
+    } else if (replNameSplits.length == 1){
+      // first assume group is omitted
+      InterpreterSetting setting =
+          interpreterSettingManager.getByName(defaultInterpreterSetting);
+      Interpreter interpreter = setting.getInterpreter(user, noteId, replName);
       if (null != interpreter) {
         return interpreter;
       }
 
-      // next, assume replName is 'group' of interpreter ('name' is omitted)
-      // search interpreter group and return first interpreter.
-      setting = getInterpreterSettingByGroup(settings, replName);
-
+      // then assume interpreter name is omitted
+      setting = interpreterSettingManager.getByName(replName);
       if (null != setting) {
         return setting.getDefaultInterpreter(user, noteId);
-      } else {
-        throw new InterpreterNotFoundException("Either no interpreter named " + replName +
-            " or it is not binded to this note");
       }
     }
 
-    throw new InterpreterNotFoundException("No such interpreter " + replName + " for note "
-        + noteId);
+    throw new InterpreterNotFoundException("No such interpreter: " + replName);
   }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java
index 3d9c2c3..8f89448 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterInfoSaving.java
@@ -50,7 +50,6 @@ public class InterpreterInfoSaving implements JsonSerializable {
   private static final Gson gson =  new GsonBuilder().setPrettyPrinting().create();
 
   public Map<String, InterpreterSetting> interpreterSettings = new HashMap<>();
-  public Map<String, List<String>> interpreterBindings = new HashMap<>();
   public List<RemoteRepository> interpreterRepositories = new ArrayList<>();
 
   public static InterpreterInfoSaving loadFromFile(Path file) throws IOException {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
index bd309b9..a12d67b 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/InterpreterSettingManager.java
@@ -77,7 +77,6 @@ import java.util.Map;
 /**
  * InterpreterSettingManager is the component which manage all the interpreter settings.
  * (load/create/update/remove/get)
- * Besides that InterpreterSettingManager also manage the interpreter setting binding.
  * TODO(zjffdu) We could move it into another separated component.
  */
 public class InterpreterSettingManager implements InterpreterSettingManagerMBean {
@@ -104,12 +103,6 @@ public class InterpreterSettingManager implements InterpreterSettingManagerMBean
   private final Map<String, InterpreterSetting> interpreterSettings =
       Maps.newConcurrentMap();
 
-  /**
-   * noteId --> list of InterpreterSettingId
-   */
-  private final Map<String, List<String>> interpreterBindings =
-      Maps.newConcurrentMap();
-
   private final List<RemoteRepository> interpreterRepositories;
   private InterpreterOption defaultOption;
   private String defaultInterpreterGroup;
@@ -224,21 +217,6 @@ public class InterpreterSettingManager implements InterpreterSettingManagerMBean
       return;
     }
 
-    // update interpreter binding first as we change interpreter setting id in ZEPPELIN-3208.
-    Map<String, List<String>> newBindingMap = new HashMap<>();
-    for (Map.Entry<String, List<String>> entry : infoSaving.interpreterBindings.entrySet()) {
-      String noteId = entry.getKey();
-      List<String> oldSettingIdList = entry.getValue();
-      List<String> newSettingIdList = new ArrayList<>();
-      for (String oldId : oldSettingIdList) {
-        if (infoSaving.interpreterSettings.containsKey(oldId)) {
-          newSettingIdList.add(infoSaving.interpreterSettings.get(oldId).getName());
-        }
-      }
-      newBindingMap.put(noteId, newSettingIdList);
-    }
-    interpreterBindings.putAll(newBindingMap);
-
     //TODO(zjffdu) still ugly (should move all to InterpreterInfoSaving)
     for (InterpreterSetting savedInterpreterSetting : infoSaving.interpreterSettings.values()) {
       savedInterpreterSetting.setProperties(InterpreterSetting.convertInterpreterProperties(
@@ -276,16 +254,6 @@ public class InterpreterSettingManager implements InterpreterSettingManagerMBean
         LOGGER.warn("No InterpreterSetting Template found for InterpreterSetting: "
             + savedInterpreterSetting.getGroup() + ", but it is found in interpreter.json, "
             + "it would be skipped.");
-        // also delete its binding
-        for (Map.Entry<String, List<String>> entry : interpreterBindings.entrySet()) {
-          List<String> ids = entry.getValue();
-          Iterator<String> iter = ids.iterator();
-          while(iter.hasNext()) {
-            if (iter.next().equals(savedInterpreterSetting.getId())) {
-              iter.remove();
-            }
-          }
-        }
         continue;
       }
 
@@ -319,7 +287,6 @@ public class InterpreterSettingManager implements InterpreterSettingManagerMBean
 
   public void saveToFile() throws IOException {
     InterpreterInfoSaving info = new InterpreterInfoSaving();
-    info.interpreterBindings = interpreterBindings;
     info.interpreterSettings = Maps.newHashMap(interpreterSettings);
     info.interpreterRepositories = interpreterRepositories;
     configStorage.save(info);
@@ -461,19 +428,7 @@ public class InterpreterSettingManager implements InterpreterSettingManagerMBean
   }
 
   public List<InterpreterSetting> getInterpreterSettings(String noteId) {
-    List<InterpreterSetting> settings = new ArrayList<>();
-      List<String> interpreterSettingIds = interpreterBindings.get(noteId);
-      if (interpreterSettingIds != null) {
-        for (String settingId : interpreterSettingIds) {
-          if (interpreterSettings.containsKey(settingId)) {
-            settings.add(interpreterSettings.get(settingId));
-          } else {
-            LOGGER.warn("InterpreterSetting {} has been removed, but note {} still bind to it.",
-                settingId, noteId);
-          }
-        }
-      }
-    return settings;
+    return get();
   }
 
   public InterpreterSetting getInterpreterSettingByName(String name) {
@@ -715,42 +670,7 @@ public class InterpreterSettingManager implements InterpreterSettingManagerMBean
     return setting;
   }
 
-  /**
-   * map interpreter ids into noteId
-   *
-   * @param user  user name
-   * @param noteId note id
-   * @param settingIdList InterpreterSetting id list
-   */
-  public void setInterpreterBinding(String user, String noteId, List<String> settingIdList)
-      throws IOException {
-    List<String> unBindedSettingIdList = new LinkedList<>();
 
-    List<String> oldSettingIdList = interpreterBindings.get(noteId);
-    if (oldSettingIdList != null) {
-      for (String oldSettingId : oldSettingIdList) {
-        if (!settingIdList.contains(oldSettingId)) {
-          unBindedSettingIdList.add(oldSettingId);
-        }
-      }
-    }
-    interpreterBindings.put(noteId, settingIdList);
-    saveToFile();
-
-    for (String settingId : unBindedSettingIdList) {
-      InterpreterSetting interpreterSetting = interpreterSettings.get(settingId);
-      //TODO(zjffdu) Add test for this scenario
-      //only close Interpreters when it is note scoped
-      if (interpreterSetting.getOption().perNoteIsolated() ||
-          interpreterSetting.getOption().perNoteScoped()) {
-        interpreterSetting.closeInterpreters(user, noteId);
-      }
-    }
-  }
-
-  public List<String> getInterpreterBinding(String noteId) {
-    return interpreterBindings.get(noteId);
-  }
 
   @VisibleForTesting
   public void closeNote(String user, String noteId) {
@@ -800,11 +720,6 @@ public class InterpreterSettingManager implements InterpreterSettingManagerMBean
     saveToFile();
   }
 
-  public void removeNoteInterpreterSettingBinding(String user, String noteId) throws IOException {
-    setInterpreterBinding(user, noteId, new ArrayList<String>());
-    interpreterBindings.remove(noteId);
-  }
-
   /** Change interpreter properties and restart */
   public void setPropertyAndRestart(
       String id,
@@ -860,7 +775,7 @@ public class InterpreterSettingManager implements InterpreterSettingManagerMBean
         return interpreterSetting;
       }
     }
-    throw new RuntimeException("No InterpreterSetting: " + name);
+    return null;
   }
 
   public void remove(String id) throws IOException {
@@ -873,15 +788,6 @@ public class InterpreterSettingManager implements InterpreterSettingManagerMBean
       InterpreterSetting intp = interpreterSettings.get(id);
       intp.close();
       interpreterSettings.remove(id);
-      for (List<String> settings : interpreterBindings.values()) {
-        Iterator<String> it = settings.iterator();
-        while (it.hasNext()) {
-          String settingId = it.next();
-          if (settingId.equals(id)) {
-            it.remove();
-          }
-        }
-      }
       saveToFile();
     }
 
@@ -897,9 +803,9 @@ public class InterpreterSettingManager implements InterpreterSettingManagerMBean
     Collections.sort(orderedSettings, new Comparator<InterpreterSetting>() {
       @Override
       public int compare(InterpreterSetting o1, InterpreterSetting o2) {
-        if (o1.getGroup().equals(defaultInterpreterGroup)) {
+        if (o1.getName().equals(defaultInterpreterGroup)) {
           return -1;
-        } else if (o2.getGroup().equals(defaultInterpreterGroup)) {
+        } else if (o2.getName().equals(defaultInterpreterGroup)) {
           return 1;
         } else {
           return o1.getName().compareTo(o2.getName());
@@ -909,6 +815,16 @@ public class InterpreterSettingManager implements InterpreterSettingManagerMBean
     return orderedSettings;
   }
 
+  public InterpreterSetting getDefaultInterpreterSetting() {
+    InterpreterSetting setting =
+        getByName(conf.getString(ConfVars.ZEPPELIN_INTERPRETER_GROUP_DEFAULT));
+    if (setting != null) {
+      return setting;
+    } else {
+      return get().get(0);
+    }
+  }
+
   @VisibleForTesting
   public List<String> getSettingIds() {
     List<String> settingIds = new ArrayList<>();

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroup.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroup.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroup.java
index b6b6b69..e1470df 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroup.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/interpreter/ManagedInterpreterGroup.java
@@ -18,6 +18,7 @@
 
 package org.apache.zeppelin.interpreter;
 
+import org.apache.commons.lang.exception.ExceptionUtils;
 import org.apache.zeppelin.interpreter.remote.RemoteInterpreterProcess;
 import org.apache.zeppelin.scheduler.Job;
 import org.apache.zeppelin.scheduler.Scheduler;

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/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 b8d3de1..a79ac63 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
@@ -89,6 +89,7 @@ public class Note implements ParagraphJobListener, JsonSerializable {
 
   private String name = "";
   private String id;
+  private String defaultInterpreterGroup;
   private Map<String, Object> noteParams = new HashMap<>();
   private LinkedHashMap<String, Input> noteForms = new LinkedHashMap<>();
 
@@ -125,9 +126,10 @@ public class Note implements ParagraphJobListener, JsonSerializable {
     generateId();
   }
 
-  public Note(NotebookRepo repo, InterpreterFactory factory,
+  public Note(String defaultInterpreterGroup, NotebookRepo repo, InterpreterFactory factory,
       InterpreterSettingManager interpreterSettingManager, JobListenerFactory jlFactory,
       SearchService noteIndex, Credentials credentials, NoteEventListener noteEventListener) {
+    this.defaultInterpreterGroup = defaultInterpreterGroup;
     this.repo = repo;
     this.factory = factory;
     this.interpreterSettingManager = interpreterSettingManager;
@@ -182,6 +184,10 @@ public class Note implements ParagraphJobListener, JsonSerializable {
     return name;
   }
 
+  public String getDefaultInterpreterGroup() {
+    return defaultInterpreterGroup;
+  }
+
   public Map<String, Object> getNoteParams() {
     return noteParams;
   }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/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 e9903c7..3f573b8 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
@@ -27,6 +27,7 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -37,12 +38,15 @@ import org.apache.zeppelin.conf.ZeppelinConfiguration;
 import org.apache.zeppelin.conf.ZeppelinConfiguration.ConfVars;
 import org.apache.zeppelin.display.AngularObject;
 import org.apache.zeppelin.display.AngularObjectRegistry;
+import org.apache.zeppelin.interpreter.Interpreter;
 import org.apache.zeppelin.interpreter.InterpreterException;
 import org.apache.zeppelin.interpreter.InterpreterFactory;
 import org.apache.zeppelin.interpreter.InterpreterGroup;
+import org.apache.zeppelin.interpreter.InterpreterNotFoundException;
 import org.apache.zeppelin.interpreter.InterpreterResult;
 import org.apache.zeppelin.interpreter.InterpreterSetting;
 import org.apache.zeppelin.interpreter.InterpreterSettingManager;
+import org.apache.zeppelin.interpreter.ManagedInterpreterGroup;
 import org.apache.zeppelin.interpreter.remote.RemoteAngularObjectRegistry;
 import org.apache.zeppelin.notebook.repo.NotebookRepo;
 import org.apache.zeppelin.notebook.repo.NotebookRepoSync;
@@ -136,15 +140,7 @@ public class Notebook implements NoteEventListener {
    * @throws IOException
    */
   public Note createNote(AuthenticationInfo subject) throws IOException {
-    Preconditions.checkNotNull(subject, "AuthenticationInfo should not be null");
-    Note note;
-    if (conf.getBoolean(ConfVars.ZEPPELIN_NOTEBOOK_AUTO_INTERPRETER_BINDING)) {
-      note = createNote(interpreterSettingManager.getInterpreterSettingIds(), subject);
-    } else {
-      note = createNote(null, subject);
-    }
-    noteSearchService.addIndexDoc(note);
-    return note;
+    return createNote(interpreterSettingManager.getDefaultInterpreterSetting().getName(), subject);
   }
 
   /**
@@ -152,20 +148,16 @@ public class Notebook implements NoteEventListener {
    *
    * @throws IOException
    */
-  public Note createNote(List<String> interpreterIds, AuthenticationInfo subject)
+  public Note createNote(String defaultInterpreterSetting, AuthenticationInfo subject)
       throws IOException {
     Note note =
-        new Note(notebookRepo, replFactory, interpreterSettingManager, jobListenerFactory,
-                noteSearchService, credentials, this);
+        new Note(defaultInterpreterSetting, notebookRepo, replFactory, interpreterSettingManager,
+            jobListenerFactory, noteSearchService, credentials, this);
     note.setNoteNameListener(folders);
 
     synchronized (notes) {
       notes.put(note.getId(), note);
     }
-    if (interpreterIds != null) {
-      bindInterpretersToNote(subject.getUser(), note.getId(), interpreterIds);
-    }
-
     notebookAuthorization.setNewNotePermissions(note.getId(), subject);
     noteSearchService.addIndexDoc(note);
     note.persist(subject);
@@ -246,9 +238,6 @@ public class Notebook implements NoteEventListener {
       newNote.setName("Note " + newNote.getId());
     }
     newNote.setCronSupported(getConf());
-    // Copy the interpreter bindings
-    List<String> boundInterpreterSettingsIds = getBindedInterpreterSettingsIds(sourceNote.getId());
-    bindInterpretersToNote(subject.getUser(), newNote.getId(), boundInterpreterSettingsIds);
 
     List<Paragraph> paragraphs = sourceNote.getParagraphs();
     for (Paragraph p : paragraphs) {
@@ -260,37 +249,22 @@ public class Notebook implements NoteEventListener {
     return newNote;
   }
 
-  public void bindInterpretersToNote(String user, String id, List<String> interpreterSettingIds)
-      throws IOException {
-    Note note = getNote(id);
+  public List<InterpreterSetting> getBindedInterpreterSettings(String noteId) {
+    Note note = getNote(noteId);
     if (note != null) {
-      List<InterpreterSetting> currentBindings =
-          interpreterSettingManager.getInterpreterSettings(id);
-      for (InterpreterSetting setting : currentBindings) {
-        if (!interpreterSettingIds.contains(setting.getId())) {
-          fireUnbindInterpreter(note, setting);
+      Set<InterpreterSetting> settings = new HashSet<>();
+      for (Paragraph p : note.getParagraphs()) {
+        try {
+          Interpreter intp = p.getBindedInterpreter();
+          settings.add((
+              (ManagedInterpreterGroup) intp.getInterpreterGroup()).getInterpreterSetting());
+        } catch (InterpreterNotFoundException e) {
+          // ignore this
         }
       }
-
-      interpreterSettingManager.setInterpreterBinding(user, note.getId(), interpreterSettingIds);
-      // comment out while note.getNoteReplLoader().setInterpreterBinding(...) do the same
-      // replFactory.putNoteInterpreterSettingBinding(id, interpreterSettingIds);
-    }
-  }
-
-  List<String> getBindedInterpreterSettingsIds(String id) {
-    Note note = getNote(id);
-    if (note != null) {
-      return interpreterSettingManager.getInterpreterBinding(note.getId());
-    } else {
-      return new LinkedList<>();
-    }
-  }
-
-  public List<InterpreterSetting> getBindedInterpreterSettings(String id) {
-    Note note = getNote(id);
-    if (note != null) {
-      return interpreterSettingManager.getInterpreterSettings(note.getId());
+      // add the default interpreter group
+      settings.add(interpreterSettingManager.getByName(note.getDefaultInterpreterGroup()));
+      return new ArrayList<>(settings);
     } else {
       return new LinkedList<>();
     }
@@ -315,11 +289,11 @@ public class Notebook implements NoteEventListener {
   }
 
   public void moveNoteToTrash(String noteId) {
-    try {
-      interpreterSettingManager.setInterpreterBinding("", noteId, new ArrayList<String>());
-    } catch (IOException e) {
-      e.printStackTrace();
-    }
+//    try {
+////      interpreterSettingManager.setInterpreterBinding("", noteId, new ArrayList<String>());
+//    } catch (IOException e) {
+//      e.printStackTrace();
+//    }
   }
 
   public void removeNote(String id, AuthenticationInfo subject) {
@@ -331,11 +305,7 @@ public class Notebook implements NoteEventListener {
       note = notes.remove(id);
       folders.removeNote(note);
     }
-    try {
-      interpreterSettingManager.removeNoteInterpreterSettingBinding(subject.getUser(), id);
-    } catch (IOException e) {
-      logger.error(e.toString(), e);
-    }
+
     noteSearchService.deleteIndexDocs(note);
     notebookAuthorization.removeNote(id);
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
index fb51d5e..a8ee121 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/Paragraph.java
@@ -271,7 +271,8 @@ public class Paragraph extends Job implements Cloneable, JsonSerializable {
   }
 
   public Interpreter getBindedInterpreter() throws InterpreterNotFoundException {
-    return this.interpreterFactory.getInterpreter(user, note.getId(), intpText);
+    return this.interpreterFactory.getInterpreter(user, note.getId(), intpText,
+        note.getDefaultInterpreterGroup());
   }
 
   public void setInterpreter(Interpreter interpreter) {
@@ -763,7 +764,8 @@ public class Paragraph extends Job implements Cloneable, JsonSerializable {
 
   public boolean isValidInterpreter(String replName) {
     try {
-      return interpreterFactory.getInterpreter(user, note.getId(), replName) != null;
+      return interpreterFactory.getInterpreter(user, note.getId(), replName,
+          note.getDefaultInterpreterGroup()) != null;
     } catch (InterpreterNotFoundException e) {
       return false;
     }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java
index 7a042ea..06499f3 100644
--- a/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java
+++ b/zeppelin-zengine/src/main/java/org/apache/zeppelin/notebook/socket/Message.java
@@ -165,13 +165,10 @@ public class Message implements JsonSerializable {
     LIST_NOTE_JOBS,               // [c-s] get note job management information
     LIST_UPDATE_NOTE_JOBS,        // [c-s] get job management information for until unixtime
     UNSUBSCRIBE_UPDATE_NOTE_JOBS, // [c-s] unsubscribe job information for job management
-                                  // @param unixTime
-    GET_INTERPRETER_BINDINGS,     // [c-s] get interpreter bindings
-                                  // @param noteId
-    SAVE_INTERPRETER_BINDINGS,    // [c-s] save interpreter bindings
-                                  // @param noteId
-                                  // @param selectedSettingIds
+    // @param unixTime
+    GET_INTERPRETER_BINDINGS,    // [c-s] get interpreter bindings
     INTERPRETER_BINDINGS,         // [s-c] interpreter bindings
+
     GET_INTERPRETER_SETTINGS,     // [c-s] get interpreter settings
     INTERPRETER_SETTINGS,         // [s-c] interpreter settings
     ERROR_INFO,                   // [s-c] error information to be sent

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java
index 5e4bfe1..3d3df9f 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/helium/HeliumApplicationFactoryTest.java
@@ -108,7 +108,6 @@ public class HeliumApplicationFactoryTest extends AbstractInterpreterTest implem
         "", "");
 
     Note note1 = notebook.createNote(anonymous);
-    interpreterSettingManager.setInterpreterBinding("user", note1.getId(),interpreterSettingManager.getInterpreterSettingIds());
 
     Paragraph p1 = note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
 
@@ -154,7 +153,6 @@ public class HeliumApplicationFactoryTest extends AbstractInterpreterTest implem
         "", "");
 
     Note note1 = notebook.createNote(anonymous);
-    interpreterSettingManager.setInterpreterBinding("user", note1.getId(), interpreterSettingManager.getInterpreterSettingIds());
 
     Paragraph p1 = note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
 
@@ -194,7 +192,6 @@ public class HeliumApplicationFactoryTest extends AbstractInterpreterTest implem
         "", "");
 
     Note note1 = notebook.createNote(anonymous);
-    notebook.bindInterpretersToNote("user", note1.getId(), interpreterSettingManager.getInterpreterSettingIds());
 
     Paragraph p1 = note1.addNewParagraph(AuthenticationInfo.ANONYMOUS);
 
@@ -211,9 +208,6 @@ public class HeliumApplicationFactoryTest extends AbstractInterpreterTest implem
       Thread.yield();
     }
 
-    // when unbind interpreter
-    notebook.bindInterpretersToNote("user", note1.getId(), new LinkedList<String>());
-
     // then
     assertEquals(ApplicationState.Status.UNLOADED, app.getStatus());
 
@@ -239,10 +233,6 @@ public class HeliumApplicationFactoryTest extends AbstractInterpreterTest implem
 
     }
 
-    // Unbind all interpreter from note
-    // NullPointerException shouldn't occur here
-    notebook.bindInterpretersToNote("user", note1.getId(), new LinkedList<String>());
-
     // remove note
     notebook.removeNote(note1.getId(), anonymous);
   }
@@ -260,7 +250,6 @@ public class HeliumApplicationFactoryTest extends AbstractInterpreterTest implem
         "", "");
 
     Note note1 = notebook.createNote(anonymous);
-    notebook.bindInterpretersToNote("user", note1.getId(), interpreterSettingManager.getInterpreterSettingIds());
     String mock1IntpSettingId = null;
     for (InterpreterSetting setting : notebook.getBindedInterpreterSettings(note1.getId())) {
       if (setting.getName().equals("mock1")) {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/AbstractInterpreterTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/AbstractInterpreterTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/AbstractInterpreterTest.java
index 249f752..23ebfaf 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/AbstractInterpreterTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/AbstractInterpreterTest.java
@@ -71,7 +71,7 @@ public abstract class AbstractInterpreterTest {
   }
 
   protected Note createNote() {
-    return new Note(null, interpreterFactory, interpreterSettingManager, null, null, null, null);
+    return new Note("test", null, interpreterFactory, interpreterSettingManager, null, null, null, null);
   }
 
   protected InterpreterContext createDummyInterpreterContext() {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/ConfInterpreterTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/ConfInterpreterTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/ConfInterpreterTest.java
index 892b43d..d39b0ec 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/ConfInterpreterTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/ConfInterpreterTest.java
@@ -29,9 +29,8 @@ public class ConfInterpreterTest extends AbstractInterpreterTest {
 
   @Test
   public void testCorrectConf() throws IOException, InterpreterException {
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getSettingIds());
-    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test.conf") instanceof ConfInterpreter);
-    ConfInterpreter confInterpreter = (ConfInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test.conf");
+    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test.conf", "test") instanceof ConfInterpreter);
+    ConfInterpreter confInterpreter = (ConfInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test.conf", "test");
 
     InterpreterContext context = InterpreterContext.builder()
         .setNoteId("noteId")
@@ -41,8 +40,8 @@ public class ConfInterpreterTest extends AbstractInterpreterTest {
     InterpreterResult result = confInterpreter.interpret("property_1\tnew_value\nnew_property\tdummy_value", context);
     assertEquals(InterpreterResult.Code.SUCCESS, result.code);
 
-    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test") instanceof RemoteInterpreter);
-    RemoteInterpreter remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test");
+    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test", "test") instanceof RemoteInterpreter);
+    RemoteInterpreter remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test", "test");
     remoteInterpreter.interpret("hello world", context);
     assertEquals(7, remoteInterpreter.getProperties().size());
     assertEquals("new_value", remoteInterpreter.getProperty("property_1"));
@@ -60,9 +59,8 @@ public class ConfInterpreterTest extends AbstractInterpreterTest {
 
   @Test
   public void testEmptyConf() throws IOException, InterpreterException {
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getSettingIds());
-    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test.conf") instanceof ConfInterpreter);
-    ConfInterpreter confInterpreter = (ConfInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test.conf");
+    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test.conf", "test") instanceof ConfInterpreter);
+    ConfInterpreter confInterpreter = (ConfInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test.conf", "test");
 
     InterpreterContext context = InterpreterContext.builder()
         .setNoteId("noteId")
@@ -71,8 +69,8 @@ public class ConfInterpreterTest extends AbstractInterpreterTest {
     InterpreterResult result = confInterpreter.interpret("", context);
     assertEquals(InterpreterResult.Code.SUCCESS, result.code);
 
-    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test") instanceof RemoteInterpreter);
-    RemoteInterpreter remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test");
+    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test", "test") instanceof RemoteInterpreter);
+    RemoteInterpreter remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test", "test");
     assertEquals(6, remoteInterpreter.getProperties().size());
     assertEquals("value_1", remoteInterpreter.getProperty("property_1"));
     assertEquals("value_3", remoteInterpreter.getProperty("property_3"));
@@ -81,16 +79,15 @@ public class ConfInterpreterTest extends AbstractInterpreterTest {
 
   @Test
   public void testRunningAfterOtherInterpreter() throws IOException, InterpreterException {
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getSettingIds());
-    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test.conf") instanceof ConfInterpreter);
-    ConfInterpreter confInterpreter = (ConfInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test.conf");
+    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test.conf", "test") instanceof ConfInterpreter);
+    ConfInterpreter confInterpreter = (ConfInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test.conf", "test");
 
     InterpreterContext context = InterpreterContext.builder()
         .setNoteId("noteId")
         .setParagraphId("paragraphId")
         .build();
 
-    RemoteInterpreter remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test");
+    RemoteInterpreter remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test", "test");
     InterpreterResult result = remoteInterpreter.interpret("hello world", context);
     assertEquals(InterpreterResult.Code.SUCCESS, result.code);
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java
index 8415a57..6d4666a 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterFactoryTest.java
@@ -17,53 +17,44 @@
 
 package org.apache.zeppelin.interpreter;
 
-import org.apache.zeppelin.interpreter.mock.MockInterpreter1;
 import org.apache.zeppelin.interpreter.remote.RemoteInterpreter;
 import org.junit.Test;
 
-import java.io.IOException;
-
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 public class InterpreterFactoryTest extends AbstractInterpreterTest {
 
-
   @Test
-  public void testGetFactory() throws IOException, InterpreterException {
-    // no default interpreter because there's no interpreter setting binded to this note
-    try {
-      interpreterFactory.getInterpreter("user1", "note1", "");
-      fail("Should throw InterpreterNotFoundException");
-    } catch (InterpreterNotFoundException e) {
+  public void testGetFactory() throws InterpreterException {
 
-    }
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getSettingIds());
-    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "") instanceof RemoteInterpreter);
-    RemoteInterpreter remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "");
+    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "", "test") instanceof RemoteInterpreter);
+    RemoteInterpreter remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "", "test");
     // EchoInterpreter is the default interpreter because test is the default interpreter group
     assertEquals(EchoInterpreter.class.getName(), remoteInterpreter.getClassName());
 
-    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test") instanceof RemoteInterpreter);
-    remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test");
+    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "double_echo", "test") instanceof RemoteInterpreter);
+    remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "double_echo", "test");
+    assertEquals(DoubleEchoInterpreter.class.getName(), remoteInterpreter.getClassName());
+
+    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test", "test") instanceof RemoteInterpreter);
+    remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test", "test");
     assertEquals(EchoInterpreter.class.getName(), remoteInterpreter.getClassName());
 
-    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test2") instanceof RemoteInterpreter);
-    remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test2");
+    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test2", "test") instanceof RemoteInterpreter);
+    remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test2", "test");
     assertEquals(EchoInterpreter.class.getName(), remoteInterpreter.getClassName());
 
-    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test2.double_echo") instanceof RemoteInterpreter);
-    remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test2.double_echo");
+    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test2.double_echo", "test") instanceof RemoteInterpreter);
+    remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test2.double_echo", "test");
     assertEquals(DoubleEchoInterpreter.class.getName(), remoteInterpreter.getClassName());
   }
 
   @Test
-  public void testUnknownRepl1() throws IOException {
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getSettingIds());
+  public void testUnknownRepl1() {
     try {
-      interpreterFactory.getInterpreter("user1", "note1", "test.unknown_repl");
+      interpreterFactory.getInterpreter("user1", "note1", "test.unknown_repl", "test");
       fail("should fail due to no such interpreter");
     } catch (InterpreterNotFoundException e) {
       assertEquals("No such interpreter: test.unknown_repl", e.getMessage());
@@ -71,13 +62,12 @@ public class InterpreterFactoryTest extends AbstractInterpreterTest {
   }
 
   @Test
-  public void testUnknownRepl2() throws IOException {
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getSettingIds());
+  public void testUnknownRepl2() {
     try {
-      interpreterFactory.getInterpreter("user1", "note1", "unknown_repl");
+      interpreterFactory.getInterpreter("user1", "note1", "unknown_repl", "test");
       fail("should fail due to no such interpreter");
     } catch (InterpreterNotFoundException e) {
-      assertEquals("Either no interpreter named unknown_repl or it is not binded to this note", e.getMessage());
+      assertEquals("No such interpreter: unknown_repl", e.getMessage());
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerTest.java
index f49ee94..1780960 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/InterpreterSettingManagerTest.java
@@ -73,12 +73,6 @@ public class InterpreterSettingManagerTest extends AbstractInterpreterTest {
     assertEquals(2, repositories.size());
     assertEquals("central", repositories.get(0).getId());
 
-    // verify interpreter binding
-    List<String> interpreterSettingIds = interpreterSettingManager.getInterpreterBinding("2C6793KRV");
-    assertEquals(2, interpreterSettingIds.size());
-    assertEquals("test", interpreterSettingIds.get(0));
-    assertEquals("test2", interpreterSettingIds.get(1));
-
     // Load it again
     InterpreterSettingManager interpreterSettingManager2 = new InterpreterSettingManager(conf,
         mock(AngularObjectRegistryListener.class), mock(RemoteInterpreterProcessListener.class), mock(ApplicationEventListener.class));
@@ -174,9 +168,6 @@ public class InterpreterSettingManagerTest extends AbstractInterpreterTest {
     assertNotNull(interpreterSetting.getInterpreterSettingManager());
 
     // restart in note page
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getSettingIds());
-    interpreterSettingManager.setInterpreterBinding("user2", "note2", interpreterSettingManager.getSettingIds());
-    interpreterSettingManager.setInterpreterBinding("user3", "note3", interpreterSettingManager.getSettingIds());
     // create 3 sessions as it is scoped mode
     interpreterSetting.getOption().setPerUser("scoped");
     interpreterSetting.getDefaultInterpreter("user1", "note1");
@@ -200,88 +191,14 @@ public class InterpreterSettingManagerTest extends AbstractInterpreterTest {
   }
 
   @Test
-  public void testInterpreterBinding() throws IOException {
-    assertNull(interpreterSettingManager.getInterpreterBinding("note1"));
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getInterpreterSettingIds());
-    assertEquals(interpreterSettingManager.getInterpreterSettingIds(), interpreterSettingManager.getInterpreterBinding("note1"));
-  }
-
-  @Test
-  public void testUpdateInterpreterBinding_PerNoteShared() throws IOException, InterpreterNotFoundException {
-    InterpreterSetting defaultInterpreterSetting = interpreterSettingManager.get().get(0);
-    defaultInterpreterSetting.getOption().setPerNote("shared");
-
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getInterpreterSettingIds());
-    // create interpreter of the first binded interpreter setting
-    interpreterFactory.getInterpreter("user1", "note1", "");
-    assertEquals(1, defaultInterpreterSetting.getAllInterpreterGroups().size());
-
-    // choose the first setting
-    List<String> newSettingIds = new ArrayList<>();
-    newSettingIds.add(interpreterSettingManager.getInterpreterSettingIds().get(1));
-
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", newSettingIds);
-    assertEquals(newSettingIds, interpreterSettingManager.getInterpreterBinding("note1"));
-    // InterpreterGroup will still be alive as it is shared
-    assertEquals(1, defaultInterpreterSetting.getAllInterpreterGroups().size());
-  }
-
-  @Test
-  public void testUpdateInterpreterBinding_PerNoteIsolated() throws IOException, InterpreterNotFoundException {
-    InterpreterSetting defaultInterpreterSetting = interpreterSettingManager.get().get(0);
-    defaultInterpreterSetting.getOption().setPerNote("isolated");
-
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getInterpreterSettingIds());
-    // create interpreter of the first binded interpreter setting
-    interpreterFactory.getInterpreter("user1", "note1", "");
-    assertEquals(1, defaultInterpreterSetting.getAllInterpreterGroups().size());
-
-    // choose the first setting
-    List<String> newSettingIds = new ArrayList<>();
-    newSettingIds.add(interpreterSettingManager.getInterpreterSettingIds().get(1));
-
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", newSettingIds);
-    assertEquals(newSettingIds, interpreterSettingManager.getInterpreterBinding("note1"));
-    // InterpreterGroup will be closed as it is only belong to this note
-    assertEquals(0, defaultInterpreterSetting.getAllInterpreterGroups().size());
-
-  }
-
-  @Test
-  public void testUpdateInterpreterBinding_PerNoteScoped() throws IOException, InterpreterNotFoundException {
-    InterpreterSetting defaultInterpreterSetting = interpreterSettingManager.get().get(0);
-    defaultInterpreterSetting.getOption().setPerNote("scoped");
-
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getInterpreterSettingIds());
-    interpreterSettingManager.setInterpreterBinding("user1", "note2", interpreterSettingManager.getInterpreterSettingIds());
-    // create 2 interpreter of the first binded interpreter setting for note1 and note2
-    interpreterFactory.getInterpreter("user1", "note1", "");
-    interpreterFactory.getInterpreter("user1", "note2", "");
-    assertEquals(1, defaultInterpreterSetting.getAllInterpreterGroups().size());
-    assertEquals(2, defaultInterpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
-
-    // choose the first setting
-    List<String> newSettingIds = new ArrayList<>();
-    newSettingIds.add(interpreterSettingManager.getInterpreterSettingIds().get(1));
-
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", newSettingIds);
-    assertEquals(newSettingIds, interpreterSettingManager.getInterpreterBinding("note1"));
-    // InterpreterGroup will be still alive but session belong to note1 will be closed
-    assertEquals(1, defaultInterpreterSetting.getAllInterpreterGroups().size());
-    assertEquals(1, defaultInterpreterSetting.getAllInterpreterGroups().get(0).getSessionNum());
-
-  }
-
-  @Test
   public void testGetEditor() throws IOException, InterpreterNotFoundException {
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getInterpreterSettingIds());
-    Interpreter echoInterpreter = interpreterFactory.getInterpreter("user1", "note1", "test.echo");
+    Interpreter echoInterpreter = interpreterFactory.getInterpreter("user1", "note1", "test.echo", "test");
     // get editor setting from interpreter-setting.json
     Map<String, Object> editor = interpreterSettingManager.getEditorSetting(echoInterpreter, "user1", "note1", "test.echo");
     assertEquals("java", editor.get("language"));
 
     // when editor setting doesn't exit, return the default editor
-    Interpreter mock1Interpreter = interpreterFactory.getInterpreter("user1", "note1", "mock1");
+    Interpreter mock1Interpreter = interpreterFactory.getInterpreter("user1", "note1", "mock1", "test");
     editor = interpreterSettingManager.getEditorSetting(mock1Interpreter,"user1", "note1", "mock1");
     assertEquals("text", editor.get("language"));
   }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SparkIntegrationTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SparkIntegrationTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SparkIntegrationTest.java
index 8ed9745..fed9ad2 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SparkIntegrationTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/SparkIntegrationTest.java
@@ -72,8 +72,7 @@ public class SparkIntegrationTest {
 
   private void testInterpreterBasics() throws IOException, InterpreterException {
     // test SparkInterpreter
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getInterpreterSettingIds());
-    Interpreter sparkInterpreter = interpreterFactory.getInterpreter("user1", "note1", "spark.spark");
+    Interpreter sparkInterpreter = interpreterFactory.getInterpreter("user1", "note1", "spark.spark", "test");
 
     InterpreterContext context = new InterpreterContext.Builder().setNoteId("note1").setParagraphId("paragraph_1").build();
     InterpreterResult interpreterResult = sparkInterpreter.interpret("sc.version", context);
@@ -85,24 +84,24 @@ public class SparkIntegrationTest {
     assertTrue(interpreterResult.msg.get(0).getData().contains("45"));
 
     // test PySparkInterpreter
-    Interpreter pySparkInterpreter = interpreterFactory.getInterpreter("user1", "note1", "spark.pyspark");
+    Interpreter pySparkInterpreter = interpreterFactory.getInterpreter("user1", "note1", "spark.pyspark", "test");
     interpreterResult = pySparkInterpreter.interpret("sqlContext.createDataFrame([(1,'a'),(2,'b')], ['id','name']).registerTempTable('test')", context);
     assertEquals(InterpreterResult.Code.SUCCESS, interpreterResult.code);
 
     // test IPySparkInterpreter
-    Interpreter ipySparkInterpreter = interpreterFactory.getInterpreter("user1", "note1", "spark.ipyspark");
+    Interpreter ipySparkInterpreter = interpreterFactory.getInterpreter("user1", "note1", "spark.ipyspark", "test");
     interpreterResult = ipySparkInterpreter.interpret("sqlContext.table('test').show()", context);
     assertEquals(InterpreterResult.Code.SUCCESS, interpreterResult.code);
 
     // test SparkSQLInterpreter
-    Interpreter sqlInterpreter = interpreterFactory.getInterpreter("user1", "note1", "spark.sql");
+    Interpreter sqlInterpreter = interpreterFactory.getInterpreter("user1", "note1", "spark.sql", "test");
     interpreterResult = sqlInterpreter.interpret("select count(1) as c from test", context);
     assertEquals(InterpreterResult.Code.SUCCESS, interpreterResult.code);
     assertEquals(InterpreterResult.Type.TABLE, interpreterResult.message().get(0).getType());
     assertEquals("c\n2\n", interpreterResult.message().get(0).getData());
 
     // test SparkRInterpreter
-    Interpreter sparkrInterpreter = interpreterFactory.getInterpreter("user1", "note1", "spark.r");
+    Interpreter sparkrInterpreter = interpreterFactory.getInterpreter("user1", "note1", "spark.r", "test");
     if (isSpark2()) {
       interpreterResult = sparkrInterpreter.interpret("df <- as.DataFrame(faithful)\nhead(df)", context);
     } else {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/lifecycle/TimeoutLifecycleManagerTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/lifecycle/TimeoutLifecycleManagerTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/lifecycle/TimeoutLifecycleManagerTest.java
index 21d4b0d..db08016 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/lifecycle/TimeoutLifecycleManagerTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/interpreter/lifecycle/TimeoutLifecycleManagerTest.java
@@ -46,9 +46,8 @@ public class TimeoutLifecycleManagerTest extends AbstractInterpreterTest {
 
   @Test
   public void testTimeout_1() throws InterpreterException, InterruptedException, IOException {
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getSettingIds());
-    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test.echo") instanceof RemoteInterpreter);
-    RemoteInterpreter remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test.echo");
+    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test.echo", "test") instanceof RemoteInterpreter);
+    RemoteInterpreter remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test.echo", "test");
     assertFalse(remoteInterpreter.isOpened());
     InterpreterSetting interpreterSetting = interpreterSettingManager.getInterpreterSettingByName("test");
     assertEquals(1, interpreterSetting.getAllInterpreterGroups().size());
@@ -71,9 +70,8 @@ public class TimeoutLifecycleManagerTest extends AbstractInterpreterTest {
 
   @Test
   public void testTimeout_2() throws InterpreterException, InterruptedException, IOException {
-    interpreterSettingManager.setInterpreterBinding("user1", "note1", interpreterSettingManager.getSettingIds());
-    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test.sleep") instanceof RemoteInterpreter);
-    final RemoteInterpreter remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test.sleep");
+    assertTrue(interpreterFactory.getInterpreter("user1", "note1", "test.sleep", "test") instanceof RemoteInterpreter);
+    final RemoteInterpreter remoteInterpreter = (RemoteInterpreter) interpreterFactory.getInterpreter("user1", "note1", "test.sleep", "test");
 
     // simulate how zeppelin submit paragraph
     remoteInterpreter.getScheduler().submit(new Job("test-job", null) {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/FolderTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/FolderTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/FolderTest.java
index 27aa633..cf01dff 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/FolderTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/FolderTest.java
@@ -71,13 +71,13 @@ public class FolderTest {
 
   @Before
   public void createFolderAndNotes() {
-    note1 = new Note(repo, interpreterFactory, interpreterSettingManager, jobListenerFactory, index, credentials, noteEventListener);
+    note1 = new Note("test", repo, interpreterFactory, interpreterSettingManager, jobListenerFactory, index, credentials, noteEventListener);
     note1.setName("this/is/a/folder/note1");
 
-    note2 = new Note(repo, interpreterFactory, interpreterSettingManager, jobListenerFactory, index, credentials, noteEventListener);
+    note2 = new Note("test", repo, interpreterFactory, interpreterSettingManager, jobListenerFactory, index, credentials, noteEventListener);
     note2.setName("this/is/a/folder/note2");
 
-    note3 = new Note(repo, interpreterFactory, interpreterSettingManager, jobListenerFactory, index, credentials, noteEventListener);
+    note3 = new Note("test", repo, interpreterFactory, interpreterSettingManager, jobListenerFactory, index, credentials, noteEventListener);
     note3.setName("this/is/a/folder/note3");
 
     folder = new Folder("this/is/a/folder");
@@ -118,7 +118,7 @@ public class FolderTest {
 
   @Test
   public void addNoteTest() {
-    Note note4 = new Note(repo, interpreterFactory, interpreterSettingManager, jobListenerFactory, index, credentials, noteEventListener);
+    Note note4 = new Note("test", repo, interpreterFactory, interpreterSettingManager, jobListenerFactory, index, credentials, noteEventListener);
     note4.setName("this/is/a/folder/note4");
 
     folder.addNote(note4);

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/b8966637/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/FolderViewTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/FolderViewTest.java b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/FolderViewTest.java
index cdba75d..ea49912 100644
--- a/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/FolderViewTest.java
+++ b/zeppelin-zengine/src/test/java/org/apache/zeppelin/notebook/FolderViewTest.java
@@ -89,7 +89,7 @@ public class FolderViewTest {
   Note abNote2;
 
   private Note createNote() {
-    Note note = new Note(repo, interpreterFactory, interpreterSettingManager, jobListenerFactory, index, credentials, noteEventListener);
+    Note note = new Note("test", repo, interpreterFactory, interpreterSettingManager, jobListenerFactory, index, credentials, noteEventListener);
     note.setNoteNameListener(folderView);
     return note;
   }