zeppelin-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jongy...@apache.org
Subject [3/3] zeppelin git commit: [ZEPPELIN-1210] Run interpreter per user
Date Thu, 20 Oct 2016 06:23:16 GMT
[ZEPPELIN-1210] Run interpreter per user

### What is this PR for?
Enabling each user to run same interpreter.

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

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

### How should this be tested?
1. Enable shiro to use authentication mode
1. Check `per user` in your interpreter tab
1. Run different paragraphs with different users
  1. Run `%spark sc.version`, you will see the two `res0: ...` in your paragraphs

### 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: CloverHearts <cloverheartsdev@gmail.com>
Author: Jongyoul Lee <jongyoul@gmail.com>

Closes #1265 from jongyoul/ZEPPELIN-1210 and squashes the following commits:

48a0d8e [Jongyoul Lee] Fixed ZEPPELIN-1542 Fixed flaky test
e84703d [Jongyoul Lee] Fixed ZEPPELIN-1542
ad80951 [Jongyoul Lee] Fixed some wrong logic of getInterpreterInstanceKey
cee39f4 [Jongyoul Lee] Fixed to pass shiro information to InterpreterFactory from ZeppelinServer
5e7da34 [Jongyoul Lee] Changed instanceKey and processKey for dealing with new UI
d201950 [CloverHearts] fix eqeqeq issue for frontweb
b18bff4 [CloverHearts] implement frontend for interpreter per user mode and misc mode
1f64e52 [CloverHearts] change default value for pernote and peruser
787a366 [CloverHearts] change Back-end test cases and member type (perNote, perUser)
8586e1f [CloverHearts] change ui for interpreter running Per x mode
0b5d671 [Jongyoul Lee] Fixed the style
960bde1 [Jongyoul Lee] Removed SecurityUtils.getPrincipal Added fromMessage.principal to get right user
01c7cf1 [Jongyoul Lee] Fixed NPE while testing ZeppelinSparkClusterTest
1fb50ab [Jongyoul Lee] Fixed NPE while testing ZeppelinSparkClusterTest
d1c4344 [Jongyoul Lee] Fixed getEditorSetting for having users' info
12a27db [Jongyoul Lee] Fixed test after rebase
510942b [Jongyoul Lee] Fixed test after rebase
cb66946 [Jongyoul Lee] Fixed test after rebase
18b39bd [Jongyoul Lee] Fixed test after rebase
daa634f [Jongyoul Lee] Fixed some tests after rebase
ed558be [Jongyoul Lee] Fixed some tests after rebase
fa7fccb [Jongyoul Lee] Fixed destroying process of remoteInterpreterProcess
0a73241 [Jongyoul Lee] Fixed conflict while rebasing.
df423d3 [Jongyoul Lee] Fixed NotebookRestApiTest
b151366 [Jongyoul Lee] Fixed some codes after rebase
a32afd7 [Jongyoul Lee] Fixed some tests
7b7eb78 [Jongyoul Lee] Fixed some tests
47cc668 [Jongyoul Lee] Fixed tests to use AuthenticationInfo
012cf99 [Jongyoul Lee] Fixed some mismatch after rebase
9a03d40 [Jongyoul Lee] Reverted some value to default ones
8589545 [Jongyoul Lee] Added option in UI
ccbedc1 [Jongyoul Lee] WIP
94dfed2 [Jongyoul Lee] WIP
6480d1d [Jongyoul Lee] resolved conflicts


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

Branch: refs/heads/master
Commit: 908b2a74ff59c231d4ba29de93812ea938f85f7f
Parents: a3a2e4d
Author: CloverHearts <cloverheartsdev@gmail.com>
Authored: Wed Oct 19 18:08:13 2016 +0900
Committer: Jongyoul Lee <jongyoul@apache.org>
Committed: Thu Oct 20 15:22:59 2016 +0900

----------------------------------------------------------------------
 .../zeppelin/interpreter/InterpreterGroup.java  |  11 +-
 .../interpreter/remote/RemoteInterpreter.java   |   1 +
 .../apache/zeppelin/rest/NotebookRestApi.java   |   9 +-
 .../apache/zeppelin/server/ZeppelinServer.java  |   2 +-
 .../apache/zeppelin/socket/NotebookServer.java  |  70 ++++---
 .../apache/zeppelin/utils/SecurityUtils.java    |   6 +
 .../src/main/resources/log4j.properties         |  25 +++
 zeppelin-server/src/main/resources/shiro.ini    |  11 +-
 .../zeppelin/rest/InterpreterRestApiTest.java   |  22 +-
 .../zeppelin/rest/NotebookRestApiTest.java      |  26 ++-
 .../zeppelin/rest/ZeppelinRestApiTest.java      | 106 +++++-----
 .../zeppelin/rest/ZeppelinSparkClusterTest.java |  54 +++--
 .../zeppelin/socket/NotebookServerTest.java     |  12 +-
 .../interpreter-create/interpreter-create.html  |  15 +-
 .../app/interpreter/interpreter.controller.js   | 131 ++++++++++--
 .../src/app/interpreter/interpreter.html        | 194 ++++++++++++++---
 .../interpreter/InterpreterFactory.java         | 109 ++++++----
 .../zeppelin/interpreter/InterpreterOption.java |  74 +++++--
 .../interpreter/InterpreterSetting.java         |  77 ++++---
 .../java/org/apache/zeppelin/notebook/Note.java |  29 ++-
 .../org/apache/zeppelin/notebook/Notebook.java  |  22 +-
 .../org/apache/zeppelin/notebook/Paragraph.java |  13 +-
 .../helium/HeliumApplicationFactoryTest.java    |  47 +++--
 .../interpreter/InterpreterFactoryTest.java     |  57 +++--
 .../notebook/NoteInterpreterLoaderTest.java     |  88 ++++----
 .../org/apache/zeppelin/notebook/NoteTest.java  |  14 +-
 .../apache/zeppelin/notebook/NotebookTest.java  | 209 ++++++++++---------
 .../notebook/repo/NotebookRepoSyncTest.java     |  93 +++++----
 .../notebook/repo/VFSNotebookRepoTest.java      |  10 +-
 .../zeppelin/search/LuceneSearchTest.java       |   7 +-
 30 files changed, 1029 insertions(+), 515 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterGroup.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterGroup.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterGroup.java
index ee53f8e..f3b158c 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterGroup.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/InterpreterGroup.java
@@ -33,7 +33,7 @@ import org.apache.zeppelin.scheduler.SchedulerFactory;
  * and InterpreterGroup will have reference to these all interpreters.
  *
  * Remember, list of interpreters are dedicated to a note.
- * (when InterpreterOption.perNoteSession==true)
+ * (when InterpreterOption.session==true)
  * So InterpreterGroup internally manages map of [noteId, list of interpreters]
  *
  * A InterpreterGroup runs on interpreter process.
@@ -203,6 +203,14 @@ public class InterpreterGroup extends ConcurrentHashMap<String, List<Interpreter
     LOGGER.info("Destroy interpreter group " + getId() + " for note " + noteId);
     List<Interpreter> intpForNote = this.get(noteId);
     destroy(intpForNote);
+
+    if (remoteInterpreterProcess != null) {
+      remoteInterpreterProcess.dereference();
+      if (remoteInterpreterProcess.referenceCount() <= 0) {
+        remoteInterpreterProcess = null;
+        allInterpreterGroups.remove(id);
+      }
+    }
   }
 
 
@@ -222,6 +230,7 @@ public class InterpreterGroup extends ConcurrentHashMap<String, List<Interpreter
       while (remoteInterpreterProcess.referenceCount() > 0) {
         remoteInterpreterProcess.dereference();
       }
+      remoteInterpreterProcess = null;
     }
 
     allInterpreterGroups.remove(id);

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java
index 073b84b..e0cdaa3 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreter.java
@@ -298,6 +298,7 @@ public class RemoteInterpreter extends Interpreter {
     if (logger.isDebugEnabled()) {
       logger.debug("st:\n{}", st);
     }
+
     FormType form = getFormType();
     RemoteInterpreterProcess interpreterProcess = getInterpreterProcess();
     Client client = null;

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/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 b83a889..d9af812 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
@@ -177,7 +177,7 @@ public class NotebookRestApi {
   public Response bind(@PathParam("noteId") String noteId, String req) throws IOException {
     List<String> settingIdList = gson.fromJson(req, new TypeToken<List<String>>() {
     }.getType());
-    notebook.bindInterpretersToNote(noteId, settingIdList);
+    notebook.bindInterpretersToNote(SecurityUtils.getPrincipal(), noteId, settingIdList);
     return new JsonResponse<>(Status.OK).build();
   }
 
@@ -458,7 +458,7 @@ public class NotebookRestApi {
     }
 
     AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal());
-    note.removeParagraph(paragraphId);
+    note.removeParagraph(SecurityUtils.getPrincipal(), paragraphId);
     note.persist(subject);
     notebookServer.broadcastNote(note);
 
@@ -599,6 +599,11 @@ public class NotebookRestApi {
     // handle params if presented
     handleParagraphParams(message, note, paragraph);
 
+    AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal());
+
+    paragraph.setAuthenticationInfo(subject);
+    note.persist(subject);
+
     note.run(paragraph.getId());
     return new JsonResponse<>(Status.OK).build();
   }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java
index c620235..de02fe0 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/server/ZeppelinServer.java
@@ -89,7 +89,7 @@ public class ZeppelinServer extends Application {
     this.heliumApplicationFactory = new HeliumApplicationFactory();
     this.schedulerFactory = new SchedulerFactory();
     this.replFactory = new InterpreterFactory(conf, notebookWsServer,
-        notebookWsServer, heliumApplicationFactory, depResolver);
+        notebookWsServer, heliumApplicationFactory, depResolver, SecurityUtils.isAuthenticated());
     this.notebookRepo = new NotebookRepoSync(conf);
     this.notebookIndex = new LuceneSearch();
     this.notebookAuthorization = NotebookAuthorization.init(conf);

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/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 2eee99e..969bdf9 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
@@ -134,7 +134,7 @@ public class NotebookServer extends WebSocketServlet implements
       if (LOG.isTraceEnabled()) {
         LOG.trace("RECEIVE MSG = " + messagereceived);
       }
-      
+
       String ticket = TicketContainer.instance.getTicket(messagereceived.principal);
       if (ticket != null && !ticket.equals(messagereceived.ticket)){
         /* not to pollute logs, log instead of exception */
@@ -472,7 +472,8 @@ public class NotebookServer extends WebSocketServlet implements
       List<String> settingIdList = gson.fromJson(String.valueOf(
           fromMessage.data.get("selectedSettingIds")), new TypeToken<ArrayList<String>>() {
           }.getType());
-      notebook().bindInterpretersToNote(noteId, settingIdList);
+      AuthenticationInfo subject = new AuthenticationInfo(fromMessage.principal);
+      notebook().bindInterpretersToNote(subject.getUser(), noteId, settingIdList);
       broadcastInterpreterBindings(noteId,
           InterpreterBindingUtils.getInterpreterBindings(notebook(), noteId));
     } catch (Exception e) {
@@ -600,6 +601,8 @@ public class NotebookServer extends WebSocketServlet implements
       return;
     }
 
+    String user = fromMessage.principal;
+
     Note note = notebook.getNote(noteId);
     NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
     if (note != null) {
@@ -610,7 +613,7 @@ public class NotebookServer extends WebSocketServlet implements
       }
       addConnectionToNote(note.getId(), conn);
       conn.send(serializeMessage(new Message(OP.NOTE).put("note", note)));
-      sendAllAngularObjects(note, conn);
+      sendAllAngularObjects(note, user, conn);
     } else {
       conn.send(serializeMessage(new Message(OP.NOTE).put("note", null)));
     }
@@ -619,6 +622,7 @@ public class NotebookServer extends WebSocketServlet implements
   private void sendHomeNote(NotebookSocket conn, HashSet<String> userAndRoles,
                             Notebook notebook, Message fromMessage) throws IOException {
     String noteId = notebook.getConf().getString(ConfVars.ZEPPELIN_NOTEBOOK_HOMESCREEN);
+    String user = fromMessage.principal;
 
     Note note = null;
     if (noteId != null) {
@@ -634,7 +638,7 @@ public class NotebookServer extends WebSocketServlet implements
       }
       addConnectionToNote(note.getId(), conn);
       conn.send(serializeMessage(new Message(OP.NOTE).put("note", note)));
-      sendAllAngularObjects(note, conn);
+      sendAllAngularObjects(note, user, conn);
     } else {
       removeConnectionFromAllNote(conn);
       conn.send(serializeMessage(new Message(OP.NOTE).put("note", null)));
@@ -786,6 +790,8 @@ public class NotebookServer extends WebSocketServlet implements
       AuthenticationInfo subject = null;
       if (fromMessage.principal != null) {
         subject = new AuthenticationInfo(fromMessage.principal);
+      } else {
+        subject = new AuthenticationInfo("anonymous");
       }
       note = notebook.importNote(noteJson, noteName, subject);
       note.persist(subject);
@@ -804,7 +810,7 @@ public class NotebookServer extends WebSocketServlet implements
     String noteId = getOpenNoteId(conn);
     final Note note = notebook.getNote(noteId);
     NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
-    AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal());
+    AuthenticationInfo subject = new AuthenticationInfo(fromMessage.principal);
     if (!notebookAuthorization.isWriter(noteId, userAndRoles)) {
       permissionError(conn, "write", fromMessage.principal,
           userAndRoles, notebookAuthorization.getWriters(noteId));
@@ -813,7 +819,7 @@ public class NotebookServer extends WebSocketServlet implements
 
     /** We dont want to remove the last paragraph */
     if (!note.isLastParagraph(paragraphId)) {
-      note.removeParagraph(paragraphId);
+      note.removeParagraph(subject.getUser(), paragraphId);
       note.persist(subject);
       broadcastNote(note);
     }
@@ -869,6 +875,7 @@ public class NotebookServer extends WebSocketServlet implements
     String interpreterGroupId = (String) fromMessage.get("interpreterGroupId");
     String varName = (String) fromMessage.get("name");
     Object varValue = fromMessage.get("value");
+    String user = fromMessage.principal;
     AngularObject ao = null;
     boolean global = false;
     // propagate change to (Remote) AngularObjectRegistry
@@ -877,12 +884,12 @@ public class NotebookServer extends WebSocketServlet implements
       List<InterpreterSetting> settings = notebook.getInterpreterFactory()
           .getInterpreterSettings(note.getId());
       for (InterpreterSetting setting : settings) {
-        if (setting.getInterpreterGroup(note.getId()) == null) {
+        if (setting.getInterpreterGroup(user, note.getId()) == null) {
           continue;
         }
-        if (interpreterGroupId.equals(setting.getInterpreterGroup(note.getId()).getId())) {
+        if (interpreterGroupId.equals(setting.getInterpreterGroup(user, note.getId()).getId())) {
           AngularObjectRegistry angularObjectRegistry = setting
-              .getInterpreterGroup(note.getId()).getAngularObjectRegistry();
+              .getInterpreterGroup(user, note.getId()).getAngularObjectRegistry();
 
           // first trying to get local registry
           ao = angularObjectRegistry.get(varName, noteId, paragraphId);
@@ -919,12 +926,12 @@ public class NotebookServer extends WebSocketServlet implements
         List<InterpreterSetting> settings = notebook.getInterpreterFactory()
             .getInterpreterSettings(note.getId());
         for (InterpreterSetting setting : settings) {
-          if (setting.getInterpreterGroup(n.getId()) == null) {
+          if (setting.getInterpreterGroup(user, n.getId()) == null) {
             continue;
           }
-          if (interpreterGroupId.equals(setting.getInterpreterGroup(n.getId()).getId())) {
+          if (interpreterGroupId.equals(setting.getInterpreterGroup(user, n.getId()).getId())) {
             AngularObjectRegistry angularObjectRegistry = setting
-                .getInterpreterGroup(n.getId()).getAngularObjectRegistry();
+                .getInterpreterGroup(user, n.getId()).getAngularObjectRegistry();
             this.broadcastExcept(
                 n.getId(),
                 new Message(OP.ANGULAR_OBJECT_UPDATE).put("angularObject", ao)
@@ -1110,7 +1117,7 @@ public class NotebookServer extends WebSocketServlet implements
     String noteId = getOpenNoteId(conn);
     final Note note = notebook.getNote(noteId);
     NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
-    AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal());
+    AuthenticationInfo subject = new AuthenticationInfo(fromMessage.principal);
     if (!notebookAuthorization.isWriter(noteId, userAndRoles)) {
       permissionError(conn, "write", fromMessage.principal,
           userAndRoles, notebookAuthorization.getWriters(noteId));
@@ -1129,7 +1136,7 @@ public class NotebookServer extends WebSocketServlet implements
     String noteId = getOpenNoteId(conn);
     final Note note = notebook.getNote(noteId);
     NotebookAuthorization notebookAuthorization = notebook.getNotebookAuthorization();
-    AuthenticationInfo subject = new AuthenticationInfo(SecurityUtils.getPrincipal());
+    AuthenticationInfo subject = new AuthenticationInfo(fromMessage.principal);
     if (!notebookAuthorization.isWriter(noteId, userAndRoles)) {
       permissionError(conn, "write", fromMessage.principal,
           userAndRoles, notebookAuthorization.getWriters(noteId));
@@ -1181,14 +1188,9 @@ public class NotebookServer extends WebSocketServlet implements
     String text = (String) fromMessage.get("paragraph");
     p.setText(text);
     p.setTitle((String) fromMessage.get("title"));
-    if (!fromMessage.principal.equals("anonymous")) {
-      AuthenticationInfo authenticationInfo = new AuthenticationInfo(fromMessage.principal,
-          fromMessage.ticket);
-      p.setAuthenticationInfo(authenticationInfo);
-
-    } else {
-      p.setAuthenticationInfo(new AuthenticationInfo());
-    }
+    AuthenticationInfo authenticationInfo =
+        new AuthenticationInfo(fromMessage.principal, fromMessage.ticket);
+    p.setAuthenticationInfo(authenticationInfo);
 
     Map<String, Object> params = (Map<String, Object>) fromMessage
        .get("params");
@@ -1513,7 +1515,7 @@ public class NotebookServer extends WebSocketServlet implements
         LOG.info("Job {} is finished", job.getId());
         try {
           //TODO(khalid): may change interface for JobListener and pass subject from interpreter
-          note.persist(null);
+          note.persist(job instanceof Paragraph ? ((Paragraph) job).getAuthenticationInfo() : null);
         } catch (IOException e) {
           LOG.error(e.toString(), e);
         }
@@ -1569,7 +1571,8 @@ public class NotebookServer extends WebSocketServlet implements
     return new NotebookInformationListener(this);
   }
 
-  private void sendAllAngularObjects(Note note, NotebookSocket conn) throws IOException {
+  private void sendAllAngularObjects(Note note, String user, NotebookSocket conn)
+      throws IOException {
     List<InterpreterSetting> settings =
         notebook().getInterpreterFactory().getInterpreterSettings(note.getId());
     if (settings == null || settings.size() == 0) {
@@ -1577,17 +1580,15 @@ public class NotebookServer extends WebSocketServlet implements
     }
 
     for (InterpreterSetting intpSetting : settings) {
-      AngularObjectRegistry registry = intpSetting.getInterpreterGroup(note.getId())
-          .getAngularObjectRegistry();
+      AngularObjectRegistry registry =
+          intpSetting.getInterpreterGroup(user, note.getId()).getAngularObjectRegistry();
       List<AngularObject> objects = registry.getAllWithGlobal(note.getId());
       for (AngularObject object : objects) {
-        conn.send(serializeMessage(new Message(OP.ANGULAR_OBJECT_UPDATE)
-            .put("angularObject", object)
-            .put("interpreterGroupId",
-                intpSetting.getInterpreterGroup(note.getId()).getId())
-            .put("noteId", note.getId())
-            .put("paragraphId", object.getParagraphId())
-        ));
+        conn.send(serializeMessage(
+            new Message(OP.ANGULAR_OBJECT_UPDATE).put("angularObject", object)
+                .put("interpreterGroupId",
+                    intpSetting.getInterpreterGroup(user, note.getId()).getId())
+                .put("noteId", note.getId()).put("paragraphId", object.getParagraphId())));
       }
     }
   }
@@ -1654,9 +1655,10 @@ public class NotebookServer extends WebSocketServlet implements
     String paragraphId = (String) fromMessage.get("paragraphId");
     String replName = (String) fromMessage.get("magic");
     String noteId = getOpenNoteId(conn);
+    String user = fromMessage.principal;
     Message resp = new Message(OP.EDITOR_SETTING);
     resp.put("paragraphId", paragraphId);
-    resp.put("editor", notebook().getInterpreterFactory().getEditorSetting(noteId, replName));
+    resp.put("editor", notebook().getInterpreterFactory().getEditorSetting(user, noteId, replName));
     conn.send(serializeMessage(resp));
     return;
   }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/zeppelin-server/src/main/java/org/apache/zeppelin/utils/SecurityUtils.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/java/org/apache/zeppelin/utils/SecurityUtils.java b/zeppelin-server/src/main/java/org/apache/zeppelin/utils/SecurityUtils.java
index f9e5929..d81d2e6 100644
--- a/zeppelin-server/src/main/java/org/apache/zeppelin/utils/SecurityUtils.java
+++ b/zeppelin-server/src/main/java/org/apache/zeppelin/utils/SecurityUtils.java
@@ -119,4 +119,10 @@ public class SecurityUtils {
     return roles;
   }
 
+  /**
+   * Checked if shiro enabled or not
+   */
+  public static boolean isAuthenticated() {
+    return org.apache.shiro.SecurityUtils.getSubject().isAuthenticated();
+  }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/zeppelin-server/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/resources/log4j.properties b/zeppelin-server/src/main/resources/log4j.properties
new file mode 100644
index 0000000..2f64407
--- /dev/null
+++ b/zeppelin-server/src/main/resources/log4j.properties
@@ -0,0 +1,25 @@
+#
+# 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.
+#
+
+log4j.rootLogger = INFO, stdout
+
+log4j.appender.stdout = org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%5p [%d] ({%t} %F[%M]:%L) - %m%n
+
+log4j.additivity.org.apache.zeppelin.interpreter = false
+log4j.logger.org.apache.zeppelin.interpreter = DEBUG, stdout

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/zeppelin-server/src/main/resources/shiro.ini
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/main/resources/shiro.ini b/zeppelin-server/src/main/resources/shiro.ini
index 371a44e..050c9d9 100644
--- a/zeppelin-server/src/main/resources/shiro.ini
+++ b/zeppelin-server/src/main/resources/shiro.ini
@@ -18,14 +18,19 @@
 [users]
 # List of users with their password allowed to access Zeppelin.
 # To use a different strategy (LDAP / Database / ...) check the shiro doc at http://shiro.apache.org/configuration.html#Configuration-INISections
-admin = password
+admin = password, admin
+user1 = user1, role1
 
 
 [urls]
-
 # anon means the access is anonymous.
 # authcBasic means Basic Auth Security
 # To enfore security, comment the line below and uncomment the next one
 /** = anon
-#/** = authcBasic
+#/** = authc
 
+[roles]
+role1 = *
+role2 = *
+role3 = *
+admin = *

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/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 c767eb0..6d4fb2c 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
@@ -30,7 +30,9 @@ 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;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
@@ -47,6 +49,7 @@ import static org.junit.Assert.*;
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class InterpreterRestApiTest extends AbstractTestRestApi {
   Gson gson = new Gson();
+  AuthenticationInfo anonymous;
 
   @BeforeClass
   public static void init() throws Exception {
@@ -58,6 +61,11 @@ public class InterpreterRestApiTest extends AbstractTestRestApi {
     AbstractTestRestApi.shutDown();
   }
 
+  @Before
+  public void setUp() {
+    anonymous = new AuthenticationInfo("anonymous");
+  }
+
   @Test
   public void getAvailableInterpreters() throws IOException {
     // when
@@ -90,7 +98,7 @@ public class InterpreterRestApiTest extends AbstractTestRestApi {
     String jsonRequest = "{\"name\":\"md2\",\"group\":\"md\",\"properties\":{\"propname\":\"propvalue\"}," +
         "\"interpreterGroup\":[{\"class\":\"org.apache.zeppelin.markdown.Markdown\",\"name\":\"md\"}]," +
         "\"dependencies\":[]," +
-        "\"option\": { \"remote\": true, \"perNoteSession\": false }}";
+        "\"option\": { \"remote\": true, \"session\": false }}";
     PostMethod post = httpPost("/interpreter/setting/", jsonRequest);
     LOG.info("testSettingCRUD create response\n" + post.getResponseBodyAsString());
     assertThat("test create method:", post, isCreated());
@@ -106,7 +114,7 @@ public class InterpreterRestApiTest extends AbstractTestRestApi {
     jsonRequest = "{\"name\":\"md2\",\"group\":\"md\",\"properties\":{\"propname\":\"Otherpropvalue\"}," +
         "\"interpreterGroup\":[{\"class\":\"org.apache.zeppelin.markdown.Markdown\",\"name\":\"md\"}]," +
         "\"dependencies\":[]," +
-        "\"option\": { \"remote\": true, \"perNoteSession\": false }}";
+        "\"option\": { \"remote\": true, \"session\": false }}";
     PutMethod put = httpPut("/interpreter/setting/" + newSettingId, jsonRequest);
     LOG.info("testSettingCRUD update response\n" + put.getResponseBodyAsString());
     assertThat("test update method:", put, isAllowed());
@@ -131,7 +139,7 @@ public class InterpreterRestApiTest extends AbstractTestRestApi {
   @Test
   public void testInterpreterAutoBinding() throws IOException {
     // create note
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
 
     // check interpreter is binded
     GetMethod get = httpGet("/notebook/interpreter/bind/" + note.getId());
@@ -144,13 +152,13 @@ public class InterpreterRestApiTest extends AbstractTestRestApi {
 
     get.releaseConnection();
     //cleanup
-    ZeppelinServer.notebook.removeNote(note.getId(), null);
+    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testInterpreterRestart() throws IOException, InterruptedException {
     // create new note
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
     note.addParagraph();
     Paragraph p = note.getLastParagraph();
     Map config = p.getConfig();
@@ -159,6 +167,7 @@ public class InterpreterRestApiTest extends AbstractTestRestApi {
     // run markdown paragraph
     p.setConfig(config);
     p.setText("%md markdown");
+    p.setAuthenticationInfo(anonymous);
     note.run(p.getId());
     while (p.getStatus() != Status.FINISHED) {
       Thread.sleep(100);
@@ -181,13 +190,14 @@ public class InterpreterRestApiTest extends AbstractTestRestApi {
     p = note.addParagraph();
     p.setConfig(config);
     p.setText("%md markdown restarted");
+    p.setAuthenticationInfo(anonymous);
     note.run(p.getId());
     while (p.getStatus() != Status.FINISHED) {
       Thread.sleep(100);
     }
     assertEquals("<p>markdown restarted</p>\n", p.getResult().message());
     //cleanup
-    ZeppelinServer.notebook.removeNote(note.getId(), null);
+    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java
index d7f55f5..9383569 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/NotebookRestApiTest.java
@@ -28,7 +28,9 @@ import org.apache.zeppelin.notebook.Note;
 import org.apache.zeppelin.notebook.NotebookAuthorization;
 import org.apache.zeppelin.notebook.NotebookAuthorizationInfoSaving;
 import org.apache.zeppelin.server.ZeppelinServer;
+import org.apache.zeppelin.user.AuthenticationInfo;
 import org.junit.AfterClass;
+import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
@@ -49,6 +51,7 @@ import static org.junit.Assert.assertThat;
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class NotebookRestApiTest extends AbstractTestRestApi {
   Gson gson = new Gson();
+  AuthenticationInfo anonymous;
 
   @BeforeClass
   public static void init() throws Exception {
@@ -60,9 +63,14 @@ public class NotebookRestApiTest extends AbstractTestRestApi {
     AbstractTestRestApi.shutDown();
   }
 
+  @Before
+  public void setUp() {
+    anonymous = new AuthenticationInfo("anonymous");
+  }
+
   @Test
   public void testPermissions() throws IOException {
-    Note note1 = ZeppelinServer.notebook.createNote(null);
+    Note note1 = ZeppelinServer.notebook.createNote(anonymous);
     // Set only readers
     String jsonRequest = "{\"readers\":[\"admin-team\"],\"owners\":[]," +
             "\"writers\":[]}";
@@ -85,7 +93,7 @@ public class NotebookRestApiTest extends AbstractTestRestApi {
     get.releaseConnection();
 
 
-    Note note2 = ZeppelinServer.notebook.createNote(null);
+    Note note2 = ZeppelinServer.notebook.createNote(anonymous);
     // Set only writers
     jsonRequest = "{\"readers\":[],\"owners\":[]," +
             "\"writers\":[\"admin-team\"]}";
@@ -119,14 +127,14 @@ public class NotebookRestApiTest extends AbstractTestRestApi {
     assertEquals(authInfo.get("owners"), Lists.newArrayList());
     get.releaseConnection();
     //cleanup
-    ZeppelinServer.notebook.removeNote(note1.getId(), null);
-    ZeppelinServer.notebook.removeNote(note2.getId(), null);
+    ZeppelinServer.notebook.removeNote(note1.getId(), anonymous);
+    ZeppelinServer.notebook.removeNote(note2.getId(), anonymous);
 
   }
 
   @Test
   public void testGetNoteParagraphJobStatus() throws IOException {
-    Note note1 = ZeppelinServer.notebook.createNote(null);
+    Note note1 = ZeppelinServer.notebook.createNote(anonymous);
     note1.addParagraph();
 
     String paragraphId = note1.getLastParagraph().getId();
@@ -142,13 +150,13 @@ public class NotebookRestApiTest extends AbstractTestRestApi {
     assertEquals(paragraphStatus.get("status"), "READY");
 
     //cleanup
-    ZeppelinServer.notebook.removeNote(note1.getId(), null);
+    ZeppelinServer.notebook.removeNote(note1.getId(), anonymous);
 
   }
 
   @Test
   public void testCloneNotebook() throws IOException {
-    Note note1 = ZeppelinServer.notebook.createNote(null);
+    Note note1 = ZeppelinServer.notebook.createNote(anonymous);
     PostMethod post = httpPost("/notebook/" + note1.getId(), "");
     LOG.info("testCloneNotebook response\n" + post.getResponseBodyAsString());
     assertThat(post, isCreated());
@@ -167,8 +175,8 @@ public class NotebookRestApiTest extends AbstractTestRestApi {
     get.releaseConnection();
 
     //cleanup
-    ZeppelinServer.notebook.removeNote(note1.getId(), null);
-    ZeppelinServer.notebook.removeNote(clonedNotebookId, null);
+    ZeppelinServer.notebook.removeNote(note1.getId(), anonymous);
+    ZeppelinServer.notebook.removeNote(clonedNotebookId, anonymous);
 
   }
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
index ffcbf2a..c2606f8 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinRestApiTest.java
@@ -34,6 +34,7 @@ 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;
 import org.junit.FixMethodOrder;
 import org.junit.Test;
@@ -51,6 +52,7 @@ import static org.junit.Assert.*;
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class ZeppelinRestApiTest extends AbstractTestRestApi {
   Gson gson = new Gson();
+  AuthenticationInfo anonymous;
 
   @BeforeClass
   public static void init() throws Exception {
@@ -62,6 +64,11 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     AbstractTestRestApi.shutDown();
   }
 
+  @Before
+  public void setUp() {
+    anonymous = new AuthenticationInfo("anonymous");
+  }
+
   /***
    * ROOT API TEST
    ***/
@@ -78,7 +85,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
   public void testGetNotebookInfo() throws IOException {
     LOG.info("testGetNotebookInfo");
     // Create note to get info
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
     assertNotNull("can't create new note", note);
     note.setName("note");
     Paragraph paragraph = note.addParagraph();
@@ -87,7 +94,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     paragraph.setConfig(config);
     String paragraphText = "%md This is my new paragraph in my new note";
     paragraph.setText(paragraphText);
-    note.persist(null);
+    note.persist(anonymous);
 
     String sourceNoteID = note.getId();
     GetMethod get = httpGet("/notebook/" + sourceNoteID);
@@ -106,7 +113,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     assertTrue(paragraphs.size() > 0);
     assertEquals(paragraphText, paragraphs.get(0).get("text"));
     //
-    ZeppelinServer.notebook.removeNote(sourceNoteID, null);
+    ZeppelinServer.notebook.removeNote(sourceNoteID, anonymous);
   }
 
   @Test
@@ -156,7 +163,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
       assertTrue("paragraph text check failed", p.getText().startsWith("text"));
     }
     // cleanup
-    ZeppelinServer.notebook.removeNote(newNotebookId, null);
+    ZeppelinServer.notebook.removeNote(newNotebookId, anonymous);
     post.releaseConnection();
   }
 
@@ -183,7 +190,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     }
     assertEquals("compare note name", expectedNoteName, newNoteName);
     // cleanup
-    ZeppelinServer.notebook.removeNote(newNotebookId, null);
+    ZeppelinServer.notebook.removeNote(newNotebookId, anonymous);
     post.releaseConnection();
 
   }
@@ -192,7 +199,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
   public void testDeleteNote() throws IOException {
     LOG.info("testDeleteNote");
     //Create note and get ID
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
     String noteId = note.getId();
     testDeleteNotebook(noteId);
   }
@@ -208,7 +215,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
   @Test
   public void testExportNotebook() throws IOException {
     LOG.info("testExportNotebook");
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
     assertNotNull("can't create new note", note);
     note.setName("source note for export");
     Paragraph paragraph = note.addParagraph();
@@ -216,7 +223,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     config.put("enabled", true);
     paragraph.setConfig(config);
     paragraph.setText("%md This is my new paragraph in my new note");
-    note.persist(null);
+    note.persist(anonymous);
     String sourceNoteID = note.getId();
     // Call export Notebook REST API
     GetMethod get = httpGet("/notebook/export/" + sourceNoteID);
@@ -230,7 +237,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     String exportJSON = (String) resp.get("body");
     assertNotNull("Can not find new notejson", exportJSON);
     LOG.info("export JSON:=" + exportJSON);
-    ZeppelinServer.notebook.removeNote(sourceNoteID, null);
+    ZeppelinServer.notebook.removeNote(sourceNoteID, anonymous);
     get.releaseConnection();
 
   }
@@ -241,7 +248,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     String noteName = "source note for import";
     LOG.info("testImortNotebook");
     // create test notebook
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
     assertNotNull("can't create new note", note);
     note.setName(noteName);
     Paragraph paragraph = note.addParagraph();
@@ -249,7 +256,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     config.put("enabled", true);
     paragraph.setConfig(config);
     paragraph.setText("%md This is my new paragraph in my new note");
-    note.persist(null);
+    note.persist(anonymous);
     String sourceNoteID = note.getId();
     // get note content as JSON
     String oldJson = getNoteContent(sourceNoteID);
@@ -267,8 +274,8 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     assertEquals("Compare paragraphs count", note.getParagraphs().size(), newNote.getParagraphs()
         .size());
     // cleanup
-    ZeppelinServer.notebook.removeNote(note.getId(), null);
-    ZeppelinServer.notebook.removeNote(newNote.getId(), null);
+    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    ZeppelinServer.notebook.removeNote(newNote.getId(), anonymous);
     importPost.releaseConnection();
   }
 
@@ -303,7 +310,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
   public void testCloneNotebook() throws IOException, CloneNotSupportedException, IllegalArgumentException {
     LOG.info("testCloneNotebook");
     // Create note to clone
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
     assertNotNull("can't create new note", note);
     note.setName("source note for clone");
     Paragraph paragraph = note.addParagraph();
@@ -311,7 +318,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     config.put("enabled", true);
     paragraph.setConfig(config);
     paragraph.setText("%md This is my new paragraph in my new note");
-    note.persist(null);
+    note.persist(anonymous);
     String sourceNoteID = note.getId();
 
     String noteName = "clone Note Name";
@@ -331,8 +338,8 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     assertEquals("Compare note names", noteName, newNote.getName());
     assertEquals("Compare paragraphs count", note.getParagraphs().size(), newNote.getParagraphs().size());
     //cleanup
-    ZeppelinServer.notebook.removeNote(note.getId(), null);
-    ZeppelinServer.notebook.removeNote(newNote.getId(), null);
+    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
+    ZeppelinServer.notebook.removeNote(newNote.getId(), anonymous);
     post.releaseConnection();
   }
 
@@ -354,7 +361,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
   public void testNoteJobs() throws IOException, InterruptedException {
     LOG.info("testNoteJobs");
     // Create note to run test.
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
     assertNotNull("can't create new note", note);
     note.setName("note for run test");
     Paragraph paragraph = note.addParagraph();
@@ -364,7 +371,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     paragraph.setConfig(config);
     
     paragraph.setText("%md This is test paragraph.");
-    note.persist(null);
+    note.persist(anonymous);
     String noteID = note.getId();
 
     note.runAll();
@@ -402,14 +409,14 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     Thread.sleep(1000);
     
     //cleanup
-    ZeppelinServer.notebook.removeNote(note.getId(), null);
+    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testGetNotebookJob() throws IOException, InterruptedException {
     LOG.info("testGetNotebookJob");
     // Create note to run test.
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
     assertNotNull("can't create new note", note);
     note.setName("note for run test");
     Paragraph paragraph = note.addParagraph();
@@ -419,7 +426,8 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     paragraph.setConfig(config);
 
     paragraph.setText("%sh sleep 1");
-    note.persist(null);
+    paragraph.setAuthenticationInfo(anonymous);
+    note.persist(anonymous);
     String noteID = note.getId();
 
     note.runAll();
@@ -455,14 +463,14 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
       }
     }
 
-    ZeppelinServer.notebook.removeNote(note.getId(), null);
+    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testRunParagraphWithParams() throws IOException, InterruptedException {
     LOG.info("testRunParagraphWithParams");
     // Create note to run test.
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
     assertNotNull("can't create new note", note);
     note.setName("note for run test");
     Paragraph paragraph = note.addParagraph();
@@ -472,7 +480,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     paragraph.setConfig(config);
 
     paragraph.setText("%spark\nval param = z.input(\"param\").toString\nprintln(param)");
-    note.persist(null);
+    note.persist(anonymous);
     String noteID = note.getId();
 
     note.runAll();
@@ -500,13 +508,13 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     assertEquals("world", params.get("param2"));
 
     //cleanup
-    ZeppelinServer.notebook.removeNote(note.getId(), null);
+    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
   }
 
   @Test
-  public void testCronJobs() throws InterruptedException, IOException{
+  public void testJobs() throws InterruptedException, IOException{
     // create a note and a paragraph
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
 
     note.setName("note for run test");
     Paragraph paragraph = note.addParagraph();
@@ -550,18 +558,18 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     DeleteMethod deleteCron = httpDelete("/notebook/cron/" + note.getId());
     assertThat("", deleteCron, isAllowed());
     deleteCron.releaseConnection();
-    ZeppelinServer.notebook.removeNote(note.getId(), null);
+    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testRegressionZEPPELIN_527() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
 
     note.setName("note for run test");
     Paragraph paragraph = note.addParagraph();
     paragraph.setText("%spark\nval param = z.input(\"param\").toString\nprintln(param)");
 
-    note.persist(null);
+    note.persist(anonymous);
 
     GetMethod getNoteJobs = httpGet("/notebook/job/" + note.getId());
     assertThat("test notebook jobs run:", getNoteJobs, isAllowed());
@@ -572,12 +580,12 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     assertFalse(body.get(0).containsKey("finished"));
     getNoteJobs.releaseConnection();
 
-    ZeppelinServer.notebook.removeNote(note.getId(), null);
+    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testInsertParagraph() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
 
     String jsonRequest = "{\"title\": \"title1\", \"text\": \"text1\"}";
     PostMethod post = httpPost("/notebook/" + note.getId() + "/paragraph", jsonRequest);
@@ -612,17 +620,17 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     assertEquals("title2", paragraphAtIdx0.getTitle());
     assertEquals("text2", paragraphAtIdx0.getText());
 
-    ZeppelinServer.notebook.removeNote(note.getId(), null);
+    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testGetParagraph() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
 
     Paragraph p = note.addParagraph();
     p.setTitle("hello");
     p.setText("world");
-    note.persist(null);
+    note.persist(anonymous);
 
     GetMethod get = httpGet("/notebook/" + note.getId() + "/paragraph/" + p.getId());
     LOG.info("testGetParagraph response\n" + get.getResponseBodyAsString());
@@ -641,12 +649,12 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     assertEquals("hello", body.get("title"));
     assertEquals("world", body.get("text"));
 
-    ZeppelinServer.notebook.removeNote(note.getId(), null);
+    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testMoveParagraph() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
 
     Paragraph p = note.addParagraph();
     p.setTitle("title1");
@@ -656,7 +664,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     p2.setTitle("title2");
     p2.setText("text2");
 
-    note.persist(null);
+    note.persist(anonymous);
 
     PostMethod post = httpPost("/notebook/" + note.getId() + "/paragraph/" + p2.getId() + "/move/" + 0, "");
     assertThat("Test post method: ", post, isAllowed());
@@ -673,18 +681,18 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     assertThat("Test post method: ", post2, isBadRequest());
     post.releaseConnection();
 
-    ZeppelinServer.notebook.removeNote(note.getId(), null);
+    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
   }
 
   @Test
   public void testDeleteParagraph() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
 
     Paragraph p = note.addParagraph();
     p.setTitle("title1");
     p.setText("text1");
 
-    note.persist(null);
+    note.persist(anonymous);
 
     DeleteMethod delete = httpDelete("/notebook/" + note.getId() + "/paragraph/" + p.getId());
     assertThat("Test delete method: ", delete, isAllowed());
@@ -694,7 +702,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     Paragraph retrParagrah = retrNote.getParagraph(p.getId());
     assertNull("paragraph should be deleted", retrParagrah);
 
-    ZeppelinServer.notebook.removeNote(note.getId(), null);
+    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
   }
 
   @Test
@@ -710,12 +718,12 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     String username = body.get("principal");
     getSecurityTicket.releaseConnection();
 
-    Note note1 = ZeppelinServer.notebook.createNote(null);
+    Note note1 = ZeppelinServer.notebook.createNote(anonymous);
     String jsonRequest = "{\"title\": \"title1\", \"text\": \"ThisIsToTestSearchMethodWithPermissions 1\"}";
     PostMethod postNotebookText = httpPost("/notebook/" + note1.getId() + "/paragraph", jsonRequest);
     postNotebookText.releaseConnection();
 
-    Note note2 = ZeppelinServer.notebook.createNote(null);
+    Note note2 = ZeppelinServer.notebook.createNote(anonymous);
     jsonRequest = "{\"title\": \"title1\", \"text\": \"ThisIsToTestSearchMethodWithPermissions 2\"}";
     postNotebookText = httpPost("/notebook/" + note2.getId() + "/paragraph", jsonRequest);
     postNotebookText.releaseConnection();
@@ -757,13 +765,13 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
       getPermission.releaseConnection();
     }
     searchNotebook.releaseConnection();
-    ZeppelinServer.notebook.removeNote(note1.getId(), null);
-    ZeppelinServer.notebook.removeNote(note2.getId(), null);
+    ZeppelinServer.notebook.removeNote(note1.getId(), anonymous);
+    ZeppelinServer.notebook.removeNote(note2.getId(), anonymous);
   }
 
   @Test
   public void testTitleSearch() throws IOException {
-    Note note = ZeppelinServer.notebook.createNote(null);
+    Note note = ZeppelinServer.notebook.createNote(anonymous);
     String jsonRequest = "{\"title\": \"testTitleSearchOfParagraph\", \"text\": \"ThisIsToTestSearchMethodWithTitle \"}";
     PostMethod postNotebookText = httpPost("/notebook/" + note.getId() + "/paragraph", jsonRequest);
     postNotebookText.releaseConnection();
@@ -784,7 +792,7 @@ public class ZeppelinRestApiTest extends AbstractTestRestApi {
     }
     assertEquals("Paragraph title hits must be at-least one", true, numberOfTitleHits >= 1);
     searchNotebook.releaseConnection();
-    ZeppelinServer.notebook.removeNote(note.getId(), null);
+    ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
   }
 
 }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java
----------------------------------------------------------------------
diff --git a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java
index 5084ae7..740ef40 100644
--- a/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java
+++ b/zeppelin-server/src/test/java/org/apache/zeppelin/rest/ZeppelinSparkClusterTest.java
@@ -31,7 +31,9 @@ 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;
 import org.junit.Test;
 
@@ -43,6 +45,7 @@ import com.google.gson.Gson;
  */
 public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
     Gson gson = new Gson();
+    AuthenticationInfo anonymous;
 
     @BeforeClass
     public static void init() throws Exception {
@@ -54,6 +57,11 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
         AbstractTestRestApi.shutDown();
     }
 
+    @Before
+    public void setUp() {
+        anonymous = new AuthenticationInfo("anonymous");
+    }
+
     private void waitForFinish(Paragraph p) {
         while (p.getStatus() != Status.FINISHED
                 && p.getStatus() != Status.ERROR
@@ -69,7 +77,7 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
     @Test
     public void basicRDDTransformationAndActionTest() throws IOException {
         // create new note
-        Note note = ZeppelinServer.notebook.createNote(null);
+        Note note = ZeppelinServer.notebook.createNote(anonymous);
 
         // run markdown paragraph, again
         Paragraph p = note.addParagraph();
@@ -77,17 +85,18 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
         config.put("enabled", true);
         p.setConfig(config);
         p.setText("%spark print(sc.parallelize(1 to 10).reduce(_ + _))");
+        p.setAuthenticationInfo(anonymous);
         note.run(p.getId());
         waitForFinish(p);
         assertEquals(Status.FINISHED, p.getStatus());
         assertEquals("55", p.getResult().message());
-        ZeppelinServer.notebook.removeNote(note.getId(), null);
+        ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
     }
 
     @Test
     public void sparkSQLTest() throws IOException {
         // create new note
-        Note note = ZeppelinServer.notebook.createNote(null);
+        Note note = ZeppelinServer.notebook.createNote(anonymous);
         int sparkVersion = getSparkVersionNumber(note);
         // DataFrame API is available from spark 1.3
         if (sparkVersion >= 13) {
@@ -98,6 +107,7 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
             p.setConfig(config);
             p.setText("%spark val df=sqlContext.createDataFrame(Seq((\"hello\",20)))\n" +
                     "df.collect()");
+            p.setAuthenticationInfo(anonymous);
             note.run(p.getId());
             waitForFinish(p);
             assertEquals(Status.FINISHED, p.getStatus());
@@ -111,6 +121,7 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
             p.setConfig(config);
             p.setText("%spark val df=sqlContext.createDataFrame(Seq((\"hello\",20)))\n" +
                     "z.show(df)");
+            p.setAuthenticationInfo(anonymous);
             note.run(p.getId());
             waitForFinish(p);
             assertEquals(Status.FINISHED, p.getStatus());
@@ -125,20 +136,21 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
                 p.setConfig(config);
                 p.setText("%spark val ds=spark.createDataset(Seq((\"hello\",20)))\n" +
                         "z.show(ds)");
+                p.setAuthenticationInfo(anonymous);
                 note.run(p.getId());
                 waitForFinish(p);
                 assertEquals(Status.FINISHED, p.getStatus());
                 assertEquals(InterpreterResult.Type.TABLE, p.getResult().type());
                 assertEquals("_1\t_2\nhello\t20\n", p.getResult().message());
             }
-            ZeppelinServer.notebook.removeNote(note.getId(), null);
+            ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
         }
     }
 
     @Test
     public void sparkRTest() throws IOException {
       // create new note
-      Note note = ZeppelinServer.notebook.createNote(null);
+      Note note = ZeppelinServer.notebook.createNote(anonymous);
       int sparkVersion = getSparkVersionNumber(note);
 
       if (isSparkR() && sparkVersion >= 14) {   // sparkr supported from 1.4.0
@@ -165,19 +177,20 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
             "df <- createDataFrame(" + sqlContextName + ", localDF)\n" +
             "count(df)"
         );
+        p.setAuthenticationInfo(anonymous);
         note.run(p.getId());
         waitForFinish(p);
         System.err.println("sparkRTest=" + p.getResult().message());
         assertEquals(Status.FINISHED, p.getStatus());
         assertEquals("[1] 3", p.getResult().message());
       }
-      ZeppelinServer.notebook.removeNote(note.getId(), null);
+      ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
     }
 
     @Test
     public void pySparkTest() throws IOException {
         // create new note
-        Note note = ZeppelinServer.notebook.createNote(null);
+        Note note = ZeppelinServer.notebook.createNote(anonymous);
         note.setName("note");
         int sparkVersion = getSparkVersionNumber(note);
 
@@ -188,6 +201,7 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
             config.put("enabled", true);
             p.setConfig(config);
             p.setText("%pyspark print(sc.parallelize(range(1, 11)).reduce(lambda a, b: a + b))");
+            p.setAuthenticationInfo(anonymous);
             note.run(p.getId());
             waitForFinish(p);
             assertEquals(Status.FINISHED, p.getStatus());
@@ -201,6 +215,7 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
                 p.setText("%pyspark from pyspark.sql import Row\n" +
                         "df=sqlContext.createDataFrame([Row(id=1, age=20)])\n" +
                         "df.collect()");
+                p.setAuthenticationInfo(anonymous);
                 note.run(p.getId());
                 waitForFinish(p);
                 assertEquals(Status.FINISHED, p.getStatus());
@@ -214,6 +229,7 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
                 p.setText("%pyspark from pyspark.sql import Row\n" +
                         "df=sqlContext.createDataFrame([Row(id=1, age=20)])\n" +
                         "z.show(df)");
+                p.setAuthenticationInfo(anonymous);
                 note.run(p.getId());
                 waitForFinish(p);
                 assertEquals(Status.FINISHED, p.getStatus());
@@ -228,6 +244,7 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
                 p.setConfig(config);
                 p.setText("%pyspark sqlContext.udf.register(\"f1\", lambda x: len(x))\n" +
                        "sqlContext.sql(\"select f1(\\\"abc\\\") as len\").collect()");
+                p.setAuthenticationInfo(anonymous);
                 note.run(p.getId());
                 waitForFinish(p);
                 assertEquals(Status.FINISHED, p.getStatus());
@@ -242,6 +259,7 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
                 p.setText("%pyspark from pyspark.sql import Row\n" +
                         "df=sqlContext.createDataFrame([Row(id=1, age=20)])\n" +
                         "df.collect()");
+                p.setAuthenticationInfo(anonymous);
                 note.run(p.getId());
                 waitForFinish(p);
                 assertEquals(Status.FINISHED, p.getStatus());
@@ -255,19 +273,20 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
                 // use SQLContext to register UDF but use this UDF through SparkSession
                 p.setText("%pyspark sqlContext.udf.register(\"f1\", lambda x: len(x))\n" +
                         "spark.sql(\"select f1(\\\"abc\\\") as len\").collect()");
+                p.setAuthenticationInfo(anonymous);
                 note.run(p.getId());
                 waitForFinish(p);
                 assertEquals(Status.FINISHED, p.getStatus());
                 assertEquals("[Row(len=u'3')]\n", p.getResult().message());
             }
         }
-        ZeppelinServer.notebook.removeNote(note.getId(), null);
+        ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
     }
 
     @Test
     public void pySparkAutoConvertOptionTest() throws IOException {
         // create new note
-        Note note = ZeppelinServer.notebook.createNote(null);
+        Note note = ZeppelinServer.notebook.createNote(anonymous);
         note.setName("note");
 
         int sparkVersionNumber = getSparkVersionNumber(note);
@@ -286,33 +305,37 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
 
             p.setText("%pyspark\nfrom pyspark.sql.functions import *\n"
                     + "print(" + sqlContextName + ".range(0, 10).withColumn('uniform', rand(seed=10) * 3.14).count())");
+            p.setAuthenticationInfo(anonymous);
             note.run(p.getId());
             waitForFinish(p);
             assertEquals(Status.FINISHED, p.getStatus());
             assertEquals("10\n", p.getResult().message());
         }
-        ZeppelinServer.notebook.removeNote(note.getId(), null);
+        ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
     }
 
     @Test
     public void zRunTest() throws IOException {
         // create new note
-        Note note = ZeppelinServer.notebook.createNote(null);
+        Note note = ZeppelinServer.notebook.createNote(anonymous);
         Paragraph p0 = note.addParagraph();
         Map config0 = p0.getConfig();
         config0.put("enabled", true);
         p0.setConfig(config0);
         p0.setText("%spark z.run(1)");
+        p0.setAuthenticationInfo(anonymous);
         Paragraph p1 = note.addParagraph();
         Map config1 = p1.getConfig();
         config1.put("enabled", true);
         p1.setConfig(config1);
         p1.setText("%spark val a=10");
+        p1.setAuthenticationInfo(anonymous);
         Paragraph p2 = note.addParagraph();
         Map config2 = p2.getConfig();
         config2.put("enabled", true);
         p2.setConfig(config2);
         p2.setText("%spark print(a)");
+        p2.setAuthenticationInfo(anonymous);
 
         note.run(p0.getId());
         waitForFinish(p0);
@@ -323,13 +346,13 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
         assertEquals(Status.FINISHED, p2.getStatus());
         assertEquals("10", p2.getResult().message());
 
-        ZeppelinServer.notebook.removeNote(note.getId(), null);
+        ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
     }
 
     @Test
     public void pySparkDepLoaderTest() throws IOException {
         // create new note
-        Note note = ZeppelinServer.notebook.createNote(null);
+        Note note = ZeppelinServer.notebook.createNote(anonymous);
         int sparkVersionNumber = getSparkVersionNumber(note);
 
         if (isPyspark() && sparkVersionNumber >= 14) {
@@ -350,6 +373,7 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
             config.put("enabled", true);
             p0.setConfig(config);
             p0.setText("%dep z.load(\"com.databricks:spark-csv_2.11:1.2.0\")");
+            p0.setAuthenticationInfo(anonymous);
             note.run(p0.getId());
             waitForFinish(p0);
             assertEquals(Status.FINISHED, p0.getStatus());
@@ -370,13 +394,14 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
                     "from pyspark.sql import SQLContext\n" +
                     "print(" + sqlContextName + ".read.format('com.databricks.spark.csv')" +
                     ".load('"+ tmpFile.getAbsolutePath() +"').count())");
+            p1.setAuthenticationInfo(anonymous);
             note.run(p1.getId());
 
             waitForFinish(p1);
             assertEquals(Status.FINISHED, p1.getStatus());
             assertEquals("2\n", p1.getResult().message());
         }
-        ZeppelinServer.notebook.removeNote(note.getId(), null);
+        ZeppelinServer.notebook.removeNote(note.getId(), anonymous);
     }
 
     /**
@@ -390,6 +415,7 @@ public class ZeppelinSparkClusterTest extends AbstractTestRestApi {
         config.put("enabled", true);
         p.setConfig(config);
         p.setText("%spark print(sc.version)");
+        p.setAuthenticationInfo(anonymous);
         note.run(p.getId());
         waitForFinish(p);
         assertEquals(Status.FINISHED, p.getStatus());

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/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 01a24e2..caac043 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
@@ -31,6 +31,7 @@ import org.apache.zeppelin.notebook.socket.Message;
 import org.apache.zeppelin.notebook.socket.Message.OP;
 import org.apache.zeppelin.rest.AbstractTestRestApi;
 import org.apache.zeppelin.server.ZeppelinServer;
+import org.apache.zeppelin.user.AuthenticationInfo;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -57,6 +58,7 @@ public class NotebookServerTest extends AbstractTestRestApi {
   private static NotebookServer notebookServer;
   private static Gson gson;
   private HttpServletRequest mockRequest;
+  private AuthenticationInfo anonymous;
 
   @BeforeClass
   public static void init() throws Exception {
@@ -74,6 +76,7 @@ public class NotebookServerTest extends AbstractTestRestApi {
   @Before
   public void setUp() {
     mockRequest = mock(HttpServletRequest.class);
+    anonymous = new AuthenticationInfo("anonymous");
   }
 
   @Test
@@ -94,14 +97,14 @@ public class NotebookServerTest extends AbstractTestRestApi {
   @Test
   public void testMakeSureNoAngularObjectBroadcastToWebsocketWhoFireTheEvent() throws IOException {
     // create a notebook
-    Note note1 = notebook.createNote(null);
+    Note note1 = notebook.createNote(anonymous);
 
     // get reference to interpreterGroup
     InterpreterGroup interpreterGroup = null;
     List<InterpreterSetting> settings = notebook.getInterpreterFactory().getInterpreterSettings(note1.getId());
     for (InterpreterSetting setting : settings) {
       if (setting.getName().equals("md")) {
-        interpreterGroup = setting.getInterpreterGroup("sharedProcess");
+        interpreterGroup = setting.getInterpreterGroup("anonymous", "sharedProcess");
         break;
       }
     }
@@ -109,6 +112,7 @@ public class NotebookServerTest extends AbstractTestRestApi {
     // start interpreter process
     Paragraph p1 = note1.addParagraph();
     p1.setText("%md start remote interpreter process");
+    p1.setAuthenticationInfo(anonymous);
     note1.run(p1.getId());
 
     // add angularObject
@@ -144,7 +148,7 @@ public class NotebookServerTest extends AbstractTestRestApi {
     verify(sock1, times(0)).send(anyString());
     verify(sock2, times(1)).send(anyString());
 
-    notebook.removeNote(note1.getId(), null);
+    notebook.removeNote(note1.getId(), anonymous);
   }
 
   @Test
@@ -167,7 +171,7 @@ public class NotebookServerTest extends AbstractTestRestApi {
     assertNotEquals(null, notebook.getNote(note.getId()));
     assertEquals("Test Zeppelin notebook import", notebook.getNote(note.getId()).getName());
     assertEquals("Test paragraphs import", notebook.getNote(note.getId()).getParagraphs().get(0).getText());
-    notebook.removeNote(note.getId(), null);
+    notebook.removeNote(note.getId(), anonymous);
   }
 
   @Test

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/zeppelin-web/src/app/interpreter/interpreter-create/interpreter-create.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/interpreter/interpreter-create/interpreter-create.html b/zeppelin-web/src/app/interpreter/interpreter-create/interpreter-create.html
index d0e0749..2638dd8 100644
--- a/zeppelin-web/src/app/interpreter/interpreter-create/interpreter-create.html
+++ b/zeppelin-web/src/app/interpreter/interpreter-create/interpreter-create.html
@@ -37,23 +37,31 @@ limitations under the License.
 
         <div>
           <h5>Option</h5>
+          <span class="checkbox input-group">
+            <label><input type="checkbox" style="width:0%;height:0%" id="perNote" ng-model="newInterpreterSetting.option.perNote"/>
+            perNote </label>
+          </span>
+          <span class="checkbox input-group">
+            <label><input type="checkbox" style="width:0%;height:0%" id="perUser" ng-model="newInterpreterSetting.option.perUser"/>
+            perUser</label>
+          </span>
           <span class="btn-group">
             <button type="button" class="btn btn-default btn-xs dropdown-toggle"
                     data-toggle="dropdown">
-              {{getSessionOption(setting.id)}} <span class="caret"></span>
+              {{getSessionOption(newInterpreterSetting.id)}} <span class="caret"></span>
             </button>
             <ul class="dropdown-menu" role="menu">
               <li>
                 <a style="cursor:pointer"
                    tooltip="Single interpreter instance are shared across notes"
-                   ng-click="setSessionOption(setting.id, 'shared')">
+                   ng-click="setSessionOption(newInterpreterSetting.id, 'shared')">
                   shared
                 </a>
               </li>
               <li>
                 <a style="cursor:pointer"
                    tooltip="Separate Interpreter instance for each note"
-                   ng-click="setSessionOption(setting.id, 'scoped')">
+                   ng-click="setSessionOption(newInterpreterSetting.id, 'scoped')">
                   scoped
                 </a>
               </li>
@@ -66,7 +74,6 @@ limitations under the License.
               </li>
             </ul>
           </span>
-          <span>Interpreter for note</span>
         </div>
 
         <div class="row interpreter" style="margin-top: 5px;">

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/zeppelin-web/src/app/interpreter/interpreter.controller.js
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/interpreter/interpreter.controller.js b/zeppelin-web/src/app/interpreter/interpreter.controller.js
index 3fe355f..0669ff8 100644
--- a/zeppelin-web/src/app/interpreter/interpreter.controller.js
+++ b/zeppelin-web/src/app/interpreter/interpreter.controller.js
@@ -16,9 +16,9 @@
 
   angular.module('zeppelinWebApp').controller('InterpreterCtrl', InterpreterCtrl);
 
-  InterpreterCtrl.$inject = ['$scope', '$http', 'baseUrlSrv', 'ngToast', '$timeout', '$route'];
+  InterpreterCtrl.$inject = ['$rootScope', '$scope', '$http', 'baseUrlSrv', 'ngToast', '$timeout', '$route'];
 
-  function InterpreterCtrl($scope, $http, baseUrlSrv, ngToast, $timeout, $route) {
+  function InterpreterCtrl($rootScope, $scope, $http, baseUrlSrv, ngToast, $timeout, $route) {
     var interpreterSettingsTmp = [];
     $scope.interpreterSettings = [];
     $scope.availableInterpreters = {};
@@ -156,7 +156,7 @@
       interpreterSettingsTmp[index] = angular.copy($scope.interpreterSettings[index]);
     };
 
-    $scope.setSessionOption = function(settingId, sessionOption) {
+    $scope.setPerNoteOption = function(settingId, sessionOption) {
       var option;
       if (settingId === undefined) {
         option = $scope.newInterpreterSetting.option;
@@ -167,18 +167,21 @@
       }
 
       if (sessionOption === 'isolated') {
-        option.perNoteSession = false;
-        option.perNoteProcess = true;
+        option.perNote = sessionOption;
+        option.session = false;
+        option.process = true;
       } else if (sessionOption === 'scoped') {
-        option.perNoteSession = true;
-        option.perNoteProcess = false;
+        option.perNote = sessionOption;
+        option.session = true;
+        option.process = false;
       } else {
-        option.perNoteSession = false;
-        option.perNoteProcess = false;
+        option.perNote = 'shared';
+        option.session = false;
+        option.process = false;
       }
     };
 
-    $scope.getSessionOption = function(settingId) {
+    $scope.setPerUserOption = function(settingId, sessionOption) {
       var option;
       if (settingId === undefined) {
         option = $scope.newInterpreterSetting.option;
@@ -187,15 +190,115 @@
         var setting = $scope.interpreterSettings[index];
         option = setting.option;
       }
-      if (option.perNoteSession) {
+
+      if (sessionOption === 'isolated') {
+        option.perUser = sessionOption;
+        option.session = false;
+        option.process = true;
+      } else if (sessionOption === 'scoped') {
+        option.perUser = sessionOption;
+        option.session = true;
+        option.process = false;
+      } else {
+        option.perUser = 'shared';
+        option.session = false;
+        option.process = false;
+      }
+    };
+
+    $scope.getPerNoteOption = function(settingId) {
+      var option;
+      if (settingId === undefined) {
+        option = $scope.newInterpreterSetting.option;
+      } else {
+        var index = _.findIndex($scope.interpreterSettings, {'id': settingId});
+        var setting = $scope.interpreterSettings[index];
+        option = setting.option;
+      }
+
+      if (option.perNote === 'scoped') {
+        return 'scoped';
+      } else if (option.perNote === 'isolated') {
+        return 'isolated';
+      } else {
+        return 'shared';
+      }
+    };
+
+    $scope.getPerUserOption = function(settingId) {
+      var option;
+      if (settingId === undefined) {
+        option = $scope.newInterpreterSetting.option;
+      } else {
+        var index = _.findIndex($scope.interpreterSettings, {'id': settingId});
+        var setting = $scope.interpreterSettings[index];
+        option = setting.option;
+      }
+
+      if (option.perUser === 'scoped') {
         return 'scoped';
-      } else if (option.perNoteProcess) {
+      } else if (option.perUser === 'isolated') {
         return 'isolated';
       } else {
         return 'shared';
       }
     };
 
+    $scope.getInterpreterRunningOption = function(settingId) {
+      var sharedModeName = 'shared';
+
+      var globallyModeName = 'Globally';
+      var perNoteModeName = 'Per Note';
+      var perUserModeName = 'Per User';
+
+      var option;
+      if (settingId === undefined) {
+        option = $scope.newInterpreterSetting.option;
+      } else {
+        var index = _.findIndex($scope.interpreterSettings, {'id': settingId});
+        var setting = $scope.interpreterSettings[index];
+        option = setting.option;
+      }
+
+      var perNote = option.perNote;
+      var perUser = option.perUser;
+
+      // Globally == shared_perNote + shared_perUser
+      if (perNote === sharedModeName && perUser === sharedModeName) {
+        return globallyModeName;
+      }
+
+      if ($rootScope.ticket.ticket === 'anonymous' && $rootScope.ticket.roles === '[]') {
+        if (perNote !== undefined && typeof perNote === 'string' && perNote !== '') {
+          return perNoteModeName;
+        }
+      } else if ($rootScope.ticket.ticket !== 'anonymous') {
+        if (perNote !== undefined && typeof perNote === 'string' && perNote !== '') {
+          if (perUser !== undefined && typeof perUser === 'string' && perUser !== '') {
+            return perUserModeName;
+          }
+          return perNoteModeName;
+        }
+      }
+
+      option.perNote = sharedModeName;
+      option.perUser = sharedModeName;
+      return globallyModeName;
+    };
+
+    $scope.setInterpreterRunningOption = function(settingId, isPerNoteMode, isPerUserMode) {
+      var option;
+      if (settingId === undefined) {
+        option = $scope.newInterpreterSetting.option;
+      } else {
+        var index = _.findIndex($scope.interpreterSettings, {'id': settingId});
+        var setting = $scope.interpreterSettings[index];
+        option = setting.option;
+      }
+      option.perNote = isPerNoteMode;
+      option.perUser = isPerUserMode;
+    };
+
     $scope.updateInterpreterSetting = function(form, settingId) {
       var thisConfirm = BootstrapDialog.confirm({
         closable: false,
@@ -402,8 +505,8 @@
           remote: true,
           isExistingProcess: false,
           setPermission: false,
-          perNoteSession: false,
-          perNoteProcess: false
+          session: false,
+          process: false
 
         }
       };

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/908b2a74/zeppelin-web/src/app/interpreter/interpreter.html
----------------------------------------------------------------------
diff --git a/zeppelin-web/src/app/interpreter/interpreter.html b/zeppelin-web/src/app/interpreter/interpreter.html
index 57b305e..e0e8613 100644
--- a/zeppelin-web/src/app/interpreter/interpreter.html
+++ b/zeppelin-web/src/app/interpreter/interpreter.html
@@ -141,40 +141,172 @@ limitations under the License.
         </span>
       </div>
     </div>
+
     <div class="row interpreter">
       <div class="col-md-12">
         <h5>Option</h5>
-        <span class="btn-group">
-          <button type="button" class="btn btn-default btn-xs dropdown-toggle"
-                  data-toggle="dropdown"
-                  ng-disabled="!valueform.$visible">
-            {{getSessionOption(setting.id)}} <span class="caret"></span>
-          </button>
-          <ul class="dropdown-menu" role="menu">
-            <li>
-              <a style="cursor:pointer"
-                 tooltip="Single interpreter instance are shared across notes"
-                 ng-click="setSessionOption(setting.id, 'shared')">
-                shared
-              </a>
-            </li>
-            <li>
-              <a style="cursor:pointer"
-                 tooltip="Separate Interpreter instance for each note"
-                 ng-click="setSessionOption(setting.id, 'scoped')">
-                scoped
-              </a>
-            </li>
-            <li>
-              <a style="cursor:pointer"
-                 tooltip="Separate Interpreter process for each note"
-                 ng-click="setSessionOption(setting.id, 'isolated')">
-                isolated
-              </a>
-            </li>
-          </ul>
-        </span>
-        <span>Interpreter for note</span>
+        <div class="row interpreter" style="margin-top: 5px;">
+          <div class="col-md-6">
+            The interpreter will be instantiated
+            <span class="btn-group">
+              <button type="button" class="btn btn-default btn-xs dropdown-toggle"
+                      data-toggle="dropdown"
+                      ng-disabled="!valueform.$visible">
+                {{getInterpreterRunningOption(setting.id)}} <span class="caret"></span>
+              </button>
+              <ul class="dropdown-menu" role="menu">
+                <li>
+                  <a style="cursor:pointer"
+                     ng-click="setInterpreterRunningOption(setting.id, 'shared', 'shared')">
+                    Globally
+                  </a>
+                </li>
+                <li>
+                  <a style="cursor:pointer"
+                     ng-click="setInterpreterRunningOption(setting.id, 'scoped', '')">
+                    Per Note
+                  </a>
+                </li>
+                <li ng-if="ticket.ticket !== 'anonymous' && ticket.roles !== '[]'">
+                  <a style="cursor:pointer"
+                     ng-click="setInterpreterRunningOption(setting.id, 'shared', 'scoped')">
+                    Per User
+                  </a>
+                </li>
+              </ul>
+            </span>
+            in
+            <span class="btn-group">
+              <button type="button" class="btn btn-default btn-xs dropdown-toggle"
+                      data-toggle="dropdown"
+                      ng-disabled="!valueform.$visible
+                                   || getInterpreterRunningOption(setting.id) === 'Globally'">
+                <span ng-if="getInterpreterRunningOption(setting.id) !== 'Per User'">
+                  {{getPerNoteOption(setting.id)}}
+                </span>
+                <span ng-if="getInterpreterRunningOption(setting.id) === 'Per User'">
+                  {{getPerUserOption(setting.id)}}
+                </span>
+                  <span class="caret"></span>
+              </button>
+              <ul class="dropdown-menu" role="menu">
+                <li
+                  ng-if="getInterpreterRunningOption(setting.id) === 'Globally'">
+                  <a style="cursor:pointer"
+                     tooltip="Single interpreter instance are shared across notes"
+                     ng-click="setPerNoteOption(setting.id, 'shared')">
+                    shared per note
+                  </a>
+                </li>
+
+                <li>
+                  <a style="cursor:pointer"
+                     ng-if="getInterpreterRunningOption(setting.id) === 'Per Note'"
+                     tooltip="Separate Interpreter instance for each note"
+                     ng-click="setPerNoteOption(setting.id, 'scoped')">
+                    scoped per note
+                  </a>
+                </li>
+                <li>
+                  <a style="cursor:pointer"
+                     ng-if="getInterpreterRunningOption(setting.id) === 'Per User'"
+                     tooltip="Separate Interpreter instance for each note"
+                     ng-click="setPerUserOption(setting.id, 'scoped')">
+                    scoped per user
+                  </a>
+                </li>
+
+                <li>
+                  <a style="cursor:pointer"
+                     ng-if="getInterpreterRunningOption(setting.id) === 'Per Note'"
+                     tooltip="Separate Interpreter process for each note"
+                     ng-click="setPerNoteOption(setting.id, 'isolated')">
+                    isolated per note
+                  </a>
+                </li>
+                <li>
+                  <a style="cursor:pointer"
+                     ng-if="getInterpreterRunningOption(setting.id) === 'Per User'"
+                     tooltip="Separate Interpreter process for each note"
+                     ng-click="setPerUserOption(setting.id, 'isolated')">
+                    isolated per user
+                  </a>
+                </li>
+              </ul>
+            </span>
+            process.
+            <span ng-if="getInterpreterRunningOption(setting.id) === 'Per User' && ticket.ticket !== 'anonymous' && ticket.roles !== '[]'">
+              <span ng-if="getPerNoteOption(setting.id) === 'shared'">
+                <button type="button" class="btn btn-default btn-xs"
+                        ng-click="setPerNoteOption(setting.id, 'scoped')"
+                        ng-disabled="!valueform.$visible"
+                        data-toggle="dropdown">
+                  <i class="fa fa-plus"></i>
+                </button>
+              </span>
+            </span>
+          </div>
+          <div class="col-md-6">
+            &nbsp;
+          </div>
+        </div>
+        <div class="row interpreter" style="margin-top: 6px;">
+          <div class="col-md-6">
+            <span ng-if="getInterpreterRunningOption(setting.id) === 'Per User' && ticket.ticket !== 'anonymous' && ticket.roles !== '[]'">
+              <span ng-if="getPerNoteOption(setting.id) !== 'shared'">
+                <span class="hidden-xs" style="padding-left: 190px;">And </span>
+                <span class="visible-xs" style="padding-left: 0px;">And </span>
+                <span class="btn-group">
+                  <button type="button" class="btn btn-default btn-xs dropdown-toggle"
+                          data-toggle="dropdown"
+                          ng-disabled="true">
+                    <span>
+                      Per Note
+                    </span>
+                    <span class="caret"></span>
+                  </button>
+                </span>
+                in
+                <span class="btn-group">
+                  <button type="button" class="btn btn-default btn-xs dropdown-toggle"
+                          data-toggle="dropdown"
+                          ng-disabled="!valueform.$visible">
+                    <span>
+                      {{getPerNoteOption(setting.id)}}
+                    </span>
+                    <span class="caret"></span>
+                  </button>
+                  <ul class="dropdown-menu" role="menu">
+                    <li>
+                      <a style="cursor:pointer"
+                         tooltip="Separate Interpreter instance for each note"
+                         ng-click="setPerNoteOption(setting.id, 'scoped')">
+                        scoped per note
+                      </a>
+                    </li>
+                    <li>
+                      <a style="cursor:pointer"
+                         tooltip="Separate Interpreter process for each note"
+                         ng-click="setPerNoteOption(setting.id, 'isolated')">
+                        isolated per note
+                      </a>
+                    </li>
+                  </ul>
+                </span>
+                process.
+                <button type="button" class="btn btn-default btn-xs"
+                        ng-disabled="!valueform.$visible"
+                        ng-click="setPerNoteOption(setting.id, 'shared')"
+                        data-toggle="dropdown">
+                  <i class="fa fa-minus"></i>
+                </button>
+              </span>
+            </span>
+          </div>
+          <div class="col-md-6">
+            &nbsp;
+          </div>
+        </div>
       </div>
     </div>
     <div class="row interpreter" style="margin-top: 5px;">


Mime
View raw message